Example #1
0
 def getDirection(self, a):
     p0 = self.AO.getPoint(a)
     p1 = self.OQ.getPoint(a)
     p2 = self.QB.getPoint(a)
     r0 = (Segment(p0, p1)).getPoint(a)
     r1 = (Segment(p1, p2)).getPoint(a)
     return (Segment(r0, r1)).direction
Example #2
0
    def _legalize_segment(self, triangle, segment):
        changes = []
        if self._is_legal_segment(triangle, segment):
            return changes

        point_i = segment.start
        point_j = segment.end
        near_triangle = triangle.get_near_triangle_by_segment(segment)
        point_k = near_triangle.last_points([point_i, point_j])[0]
        self._events.append(Event(ev_type=event.DELETE_SEGMENT, data=segment))

        new_triangle_a, new_triangle_b = Triangle.change_common_segment(triangle, near_triangle)
        new_common_segment = new_triangle_a.get_common_segment(new_triangle_b)
        self._events.append(Event(ev_type=event.ADD_SEGMENT, data=new_common_segment))
        changes.append([triangle, [new_triangle_a, new_triangle_b]])
        changes.append([near_triangle, [new_triangle_a, new_triangle_b]])
        if point_i in new_triangle_a.points:
            next_changes = self._legalize_segment(new_triangle_a, Segment(point_i, point_k))
        else:
            next_changes = self._legalize_segment(new_triangle_b, Segment(point_i, point_k))

        changes.extend(next_changes)

        if point_j in new_triangle_a.points:
            next_changes = self._legalize_segment(new_triangle_a, Segment(point_j, point_k))
        else:
            next_changes = self._legalize_segment(new_triangle_b, Segment(point_j, point_k))

        changes.extend(next_changes)
        return changes
 def __init__(self, p1, p2, p3):
     self.points = [p1, p2, p3]
     self.sides = [
         Segment(p1, p2).length(),
         Segment(p2, p3).length(),
         Segment(p3, p1).length()
     ]
Example #4
0
    def test_is_intersect(self):
        segments = self.get_segments()

        self.assertTrue(Segment.is_intersects(segments[0], segments[1]))
        self.assertFalse(Segment.is_intersects(segments[0], segments[2]))
        self.assertTrue(Segment.is_intersects(segments[5], segments[3]))
        self.assertFalse(Segment.is_intersects(segments[4], segments[6]))
Example #5
0
    def _init_base_triangle(self):
        left_bound = self._points[0].x - 1
        right_bound = self._points[0].x + 1
        top_bound = self._points[0].y + 1
        down_bound = self._points[0].y - 1
        higher_point = self._points[0]

        for point in self._points:
            if point.x >= right_bound:
                right_bound = point.x + 1
            if point.x <= left_bound:
                left_bound = point.x - 1
            if point.y >= top_bound:
                top_bound = point.y + 1
                higher_point = point
            if point.y <= down_bound:
                down_bound = point.y - 1

        self._higher_point = higher_point
        self._events.append(Event(ev_type=event.SELECT_BASE_POINT, data=higher_point))
        down_base_point = self._find_down_base_point(right_bound, down_bound)
        self._down_base_point = down_base_point
        self._events.append(Event(ev_type=event.SELECT_BASE_POINT, data=down_base_point))
        top_base_point = self._find_top_base_point(left_bound, top_bound, down_base_point)
        self._top_base_point = top_base_point
        self._events.append(Event(ev_type=event.SELECT_BASE_POINT, data=top_base_point))
        self._base_triangle = Triangle(down_base_point, top_base_point, higher_point)

        self._events.append(Event(ev_type=event.ADD_BASE_SEGMENT, data=Segment(down_base_point, top_base_point)))
        self._events.append(Event(ev_type=event.ADD_BASE_SEGMENT, data=Segment(down_base_point, higher_point)))
        self._events.append(Event(ev_type=event.ADD_BASE_SEGMENT, data=Segment(higher_point, top_base_point)))
Example #6
0
 def get_segments(self):
     return [
         Segment(Point(5, 5), Point(1, 1)),
         Segment(Point(1, 1), Point(1, 6)),
         Segment(Point(0, -1), Point(7, -1)),
         Segment(Point(-2, 6), Point(-2, -4)),
         Segment(Point(-4, 4), Point(4, -4)),
         Segment(Point(-8, -1), Point(5, 1)),
         Segment(Point(1, 2), Point(6, 0)),
         Segment(Point(-5, 0), Point(5, 0)),
         Segment(Point(0, 5), Point(0, -5)),
         Segment(Point(-5, 5), Point(-1, 1))
     ]
Example #7
0
    def get_intersect(c1, c2):
        length = Segment(c1.center, c2.center).length()
        points = []

        if length == 0 and c1.radius == c2.radius:
            return {"orientation": CircleOrientation.EQUAL, "points": points}

        if c1.radius + c2.radius < length:
            return {
                "orientation": CircleOrientation.NOT_INTERSECT,
                "points": points
            }

        if fabs(c1.radius - c2.radius) > length:
            return {
                "orientation": CircleOrientation.NOT_INTERSECT,
                "points": points
            }

        b = (c2.radius**2 - c1.radius**2 + length**2) / (2 * length)
        a = length - b
        h = sqrt(c1.radius**2 - a**2)

        p0 = Point(c1.center.x + a / length * (c2.center.x - c1.center.x),
                   c1.center.y + a / length * (c2.center.y - c1.center.y))

        points.append(
            Point(p0.x + h / length * (c2.center.y - c1.center.y),
                  p0.y - h / length * (c2.center.x - c1.center.x)))

        points.append(
            Point(p0.x - h / length * (c2.center.y - c1.center.y),
                  p0.y + h / length * (c2.center.x - c1.center.x)))

        return {"orientation": CircleOrientation.INTERSECT, "points": points}
Example #8
0
    def get_tangents(self, point: Point):
        point_position = self.substitute(point)

        if point_position < 0:
            return None
        if point_position == 0:
            return LineBuilder.from_points(self.center, point).get_orthogonal()

        catheter = Segment(point, self.center).length()
        hypotenuse = sqrt(self.radius**2 + catheter**2)

        c = self.center.x - point.x
        d = self.center.y - point.y

        b = [
            hypotenuse * (c * self.radius - d) / (c**2 - d**2),
            hypotenuse * (-c * self.radius - d) / (c**2 - d**2)
        ]

        a = [hypotenuse**2 - d * b[0] / c, hypotenuse**2 - d * b[1] / c]

        tangent_points = [
            Point(point.x - a[0], point.y - b[0]),
            Point(point.x - a[1], point.y - b[1])
        ]

        return [
            LineBuilder.from_points(point, tangent_points[0]),
            LineBuilder.from_points(point, tangent_points[1])
        ]
Example #9
0
    def _find_top_base_point(self, left_bound, top_bound, down_base_point):
        points_a = copy.deepcopy(self._points + [down_base_point])
        points_b = copy.deepcopy(self._points + [down_base_point])

        left = -1e9
        right = left_bound
        res_point = None
        while right - left >= 0:
            middle = left + (right - left) // 2
            base.BASE_POINT = Point(x=middle, y=top_bound)

            points_a = sort_point(points_a, lexicographical_comparator)
            points_b = sort_point(points_b, ccw_comparator)

            equal_point_sets = True
            for i in range(len(points_a)):
                if points_a[i] != points_b[i]:
                    equal_point_sets = False
                if points_a[i] != self._down_base_point:
                    if Segment(base.BASE_POINT, self._down_base_point).contains_point(points_a[i]):
                        equal_point_sets = False

            if equal_point_sets:
                left = middle + 1
                res_point = base.BASE_POINT
            else:
                right = middle - 1

        return res_point
Example #10
0
    def get_segments(self):
        segments = []
        points = self.points

        length = len(points)
        for i in range(0, length):
            j = (i + 1) % length
            segments.append(Segment(points[i], points[j]))

        return segments
Example #11
0
    def is_simple(self):
        segments = self.get_segments()

        length = len(segments)
        for i in range(0, length):
            for j in range(i + 2, i + length - 1):

                if Segment.is_intersects(segments[i], segments[j % length]):
                    return False

        return True
Example #12
0
 def __init__(self, A: Point, B: Point, O: Point, Q: Point):
     self.A = A
     self.B = B
     self.O = O
     self.Q = Q
     self.AB = Segment(self.A, self.B)
     self.AO = Segment(self.A, self.O)
     self.OQ = Segment(self.O, self.Q)
     self.QB = Segment(self.Q, self.B)
     self._length = None
Example #13
0
    def test_contain_point(self):
        segment = Segment(Point(1, 1), Point(4, 4))

        self.assertTrue(segment.contain_point(Point(2, 2)))
        self.assertTrue(segment.contain_point(Point(1, 1)))
        self.assertTrue(segment.contain_point(Point(4, 4)))

        self.assertFalse(segment.contain_point(Point(0, 0)))

        self.assertFalse(segment.contain_point(Point(-5, 88)))
        self.assertFalse(segment.contain_point(Point(-1, 0.5)))
Example #14
0
def get_optimal_point(points):
    """
    Returns the point the sum of the distances
    from which to other points is minimal
    """
    min_length = inf
    point = None

    for i in range(0, len(points)):
        length = 0

        for j in range(0, len(points)):
            if i == j:
                continue

            length += Segment(points[i], points[j]).length()

        if min_length > length:
            min_length = length
            point = points[i]

    return point
Example #15
0
class Curve():
    def __init__(self, A: Point, B: Point, O: Point, Q: Point):
        self.A = A
        self.B = B
        self.O = O
        self.Q = Q
        self.AB = Segment(self.A, self.B)
        self.AO = Segment(self.A, self.O)
        self.OQ = Segment(self.O, self.Q)
        self.QB = Segment(self.Q, self.B)
        self._length = None

    @property
    def length(self):
        if self._length is None:
            pointsNumber = 10
            previousPoint = None
            self._length = 0
            for i in range(pointsNumber):
                point = self.getPoint(i / pointsNumber)
                if previousPoint is not None:
                    self._length += (point - previousPoint).length
                previousPoint = point
        return self._length

    def getPoint(self, a):
        p0 = self.AO.getPoint(a)
        p1 = self.OQ.getPoint(a)
        p2 = self.QB.getPoint(a)
        r0 = (Segment(p0, p1)).getPoint(a)
        r1 = (Segment(p1, p2)).getPoint(a)
        return (Segment(r0, r1)).getPoint(a)

    def getDirection(self, a):
        p0 = self.AO.getPoint(a)
        p1 = self.OQ.getPoint(a)
        p2 = self.QB.getPoint(a)
        r0 = (Segment(p0, p1)).getPoint(a)
        r1 = (Segment(p1, p2)).getPoint(a)
        return (Segment(r0, r1)).direction
Example #16
0
 def getSides(self):
     return [
         Segment(source, target)
         for source, target in zip(self.pointList, [self.pointList[-1]].
                                   extend(self.pointList[0:-1]))
     ]
Example #17
0
 def getSide(self, i) -> Segment:
     vertices = self.getVertices()
     return Segment(vertices[i], vertices[(i + 1) % 4])
Example #18
0
    def _insert_point(self, point):
        base_triangle = self._locator.point_location(point)
        res_triangles, changes = base_triangle.split_by_point(point)

        for key in changes:
            self._locator.add_triangle_children(key, changes[key])

        next_changes = []
        used_triangles = []
        for triangle in changes:
            # inside triangle
            if len(changes[triangle]) == 3:
                self._events.append(Event(ev_type=event.ADD_SEGMENT, data=Segment(point, base_triangle.point_a)))
                self._events.append(Event(ev_type=event.ADD_SEGMENT, data=Segment(point, base_triangle.point_b)))
                self._events.append(Event(ev_type=event.ADD_SEGMENT, data=Segment(point, base_triangle.point_c)))

                segment_a = Segment(base_triangle.point_a, base_triangle.point_b)
                temp_changes = self._legalize_by_segment(changes[triangle], segment_a)
                next_changes.extend(temp_changes)

                segment_b = Segment(base_triangle.point_b, base_triangle.point_c)
                temp_changes = self._legalize_by_segment(changes[triangle], segment_b)
                next_changes.extend(temp_changes)

                segment_c = Segment(base_triangle.point_c, base_triangle.point_a)
                temp_changes = self._legalize_by_segment(changes[triangle], segment_c)
                next_changes.extend(temp_changes)
            # on segment
            else:
                triangle_a, triangle_b = changes[triangle]
                common_segment = triangle_a.get_common_segment(triangle_b)
                self._events.append(Event(ev_type=event.ADD_SEGMENT, data=common_segment))
                point_i = triangle_a.last_points([common_segment.start, common_segment.end])[0]
                point_j = triangle_b.last_points([common_segment.start, common_segment.end])[0]
                base_segment = Segment(point_i, point_j)
                if base_segment.contains_point(common_segment.start):
                    start_point = common_segment.end
                else:
                    start_point = common_segment.start

                segment_a = Segment(point_i, start_point)
                next_changes = self._legalize_segment(triangle_a, segment_a)
                segment_b = Segment(point_j, start_point)
                temp_changes = self._legalize_segment(triangle_b, segment_b)
                next_changes.extend(temp_changes)

            for base_triangle, new_triangles in next_changes:
                self._locator.add_triangle_children(base_triangle, new_triangles)
            next_changes.clear()
            used_triangles.append(triangle)

        for triangle in used_triangles:
            self._locator.clear_leaf(triangle)