Пример #1
0
    def line_segment_intersection(self, segment: Segment) -> int:
        """
        Method that checks for polygon-line segment intersection. We look at the polygon sides
        as line segments. We for intersection for each of the sides. If segment intersects any
        of the polygon sides, the answer is affirmative. If the line segment is completely in-
        side of outside of polygon, the answer is negative.
        Args:
            segment: Segment object

        Returns: 1 if there is intersection, 0 otherwise

        """
        for i in range(len(self.points)):
            edge = Segment(self.points[i],
                           self.points[(i + 1) % len(self.points)])
            if segment.check_for_intersection(edge) == 1:
                return 1
        return 0
Пример #2
0
class TestSegment(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        pass

    @classmethod
    def tearDownClass(cls):
        pass

    def setUp(self):
        self.segment1 = Segment(Point(0, 0), Point(5, 5))
        self.segment_intersects1 = Segment(Point(0, 5), Point(5, 0))
        self.segment_does_not_intersect1 = Segment(Point(-5, -8), Point(9, -3))
        self.segment_single_common_endpoint = Segment(Point(5, 5), Point(9, 3))
        self.segment_coincident = Segment(Point(0, 0), Point(5, 5))
        self.segment_contains1 = Segment(Point(0, 0), Point(6, 6))
        self.segment_deg = Segment(Point(3, 3), Point(3, 3))
        self.segment_deg2 = Segment(Point(9, 5), Point(9, 5))

    def tearDown(self):
        pass

    def test_intersection(self):
        self.assertEqual(
            self.segment1.check_for_intersection(self.segment_intersects1), 1)
        self.assertEqual(
            self.segment1.check_for_intersection(
                self.segment_does_not_intersect1), 0)
        self.assertEqual(
            self.segment1.check_for_intersection(
                self.segment_single_common_endpoint), 1)
        self.assertEqual(
            self.segment1.check_for_intersection(self.segment_coincident), 1)
        self.assertEqual(
            self.segment1.check_for_intersection(self.segment_contains1), 1)
        self.assertEqual(
            self.segment_contains1.check_for_intersection(self.segment1), 1)
        self.assertEqual(
            self.segment1.check_for_intersection(self.segment_deg), 1)
        self.assertEqual(
            self.segment_deg.check_for_intersection(self.segment_deg2), 0)
Пример #3
0
    def point_in_polygon(self, point: Point) -> int:
        """
        Idea - Ray Casting.
        We check if the point belongs to any of the line segments coincident to polygon sides.
        Point is considered to be an empty line segment in that case. If there exists at least
        a single intersection, the point is on the edge of polygon.
        The ray - We create a line segment determined by point passed through parameter and a
        (Tx, miny-1) point. It takes O(n) to find miny - we are looking for the polygon vertex
        with the smallest value on y axis. We then go through all polygon vertices and check if
        there are any points with same value on x axis and smaller value on y axis than T. When
        there are not, we return number of intersections modulo 2. Otherwise, we form the list
        L of neighbour vertices with same x value on x axis, and we also memorize point index.
        Special case: if the first and list point of polygons are containt in the ray, they need
        to be merged.
        If the ray goest through the edge of the polygon, number of intersections is 3. If the
        ray contains the side of polygon, number of intersections is 3. We subtract the length
        of all elements of L reduced for 1. For elements in L, we take predecessor point from a
        first point in list and successor point from a last element in the list and we check if
        they are on the opposite sides of the ray. If they are, we reduce by one the number of
        intersections.
        We return the number of intersections modulo 2.
        Args:
            point:

        Returns:

        """
        index_minimum = 0
        no_of_intersections = 0
        neighbours_list = []

        for i in range(len(self.points)):
            if self.points[i].return_y() < self.points[index_minimum].return_y(
            ):
                index_minimum = i

        point2 = Point(point.return_x(),
                       self.points[index_minimum].return_y() - 1)
        segment = Segment(point, point2)

        segment_point = Segment(point, point)

        for i in range(len(self.points)):
            edge_ = Segment(self.points[i],
                            self.points[(i + 1) % len(self.points)])

            if edge_.check_for_intersection(segment_point) == 1:
                return 1

            elif segment.check_for_intersection(edge_) == 1:
                no_of_intersections += 1

        neighbour_ = 0
        for i in range(len(self.points)):

            if self.points[i].return_x() == point.return_x() and \
                    self.points[i].return_y() <= point.return_y() and neighbour_ != 1:
                neighbours_list.append([(self.points[i], i)])
                neighbour_ = 1

            elif self.points[i].return_x() == point.return_x() and \
                    self.points[i].return_y() <= point.return_y() and neighbour_ == 1:
                neighbours_list[len(neighbours_list) - 1].append(
                    (self.points[i], i))
                neighbour_ = 1

            else:
                neighbour_ = 0

        if not neighbours_list:
            return no_of_intersections % 2

        if neighbours_list[0][0][1] == 0 and neighbours_list[-1][-1][1] == len(
                self.points) - 1:
            neighbours_list[0] = neighbours_list[-1] + neighbours_list[0]
            neighbours_list.pop(-1)
        for i in range(len(neighbours_list)):
            no_of_intersections -= len(neighbours_list[i]) - 1

        for i in range(len(neighbours_list)):

            first_point = self.points[neighbours_list[i][0][1] - 1]

            second_point = self.points[(neighbours_list[i][
                (len(neighbours_list[i]) - 1)][1] + 1) % len(self.points)]

            if (point.return_x() - first_point.return_x()) * (
                    second_point.return_x() - point.return_x()) > 0:
                no_of_intersections -= 1

        return no_of_intersections % 2