Esempio n. 1
0
def make_circumcircle(p0: Point, p1: Point, p2: Point):
    ax = p0.get_x()
    ay = p0.get_y()
    bx = p1.get_x()
    by = p1.get_y()
    cx = p2.get_x()
    cy = p2.get_y()
    ox = (min(ax, bx, cx) + max(ax, bx, cx)) / 2.0
    oy = (min(ay, by, cy) + max(ay, by, cy)) / 2.0
    ax -= ox
    ay -= oy
    bx -= ox
    by -= oy
    cx -= ox
    cy -= oy
    d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2.0
    if d == 0.0:
        return None
    x = ox + ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) *
              (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d
    y = oy + ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) *
              (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d
    ra = math.hypot(x - p0.get_x(), y - p0.get_y())
    rb = math.hypot(x - p1.get_x(), y - p1.get_y())
    rc = math.hypot(x - p2.get_x(), y - p2.get_y())
    return Circle(Point(x, y), max(ra, rb, rc))
Esempio n. 2
0
    def ears_clipping(points, ears):
        if len(ears) == 0:
            return []

        edges = []
        length = len(points)
        e = ears[0]

        while len(points) > 3:
            ind = points.index(e)

            prev_pred = points[(ind - 2) % length]
            pred = points[(ind - 1) % length]
            succ = points[(ind + 1) % length]
            next_succ = points[(ind + 2) % length]

            edges.append(LineSegment(Point(pred[0], pred[1]), Point(succ[0], succ[1])))
            points.remove(e)
            length -= 1
            ears.remove(e)

            if EarClipping.__is_ear(points, prev_pred, pred, succ):
                if pred not in ears:
                    ears.append(pred)
            else:
                if pred in ears:
                    ears.remove(pred)
            if EarClipping.__is_ear(points, pred, succ, next_succ):
                if succ not in ears:
                    ears.append(succ)
            else:
                if succ in ears:
                    ears.remove(succ)
            if len(ears) > 0:
                e = ears[0]
            else:
                return []
        return edges
Esempio n. 3
0
def closest_point(seg: LineSegment, points: list):
    """
    Algorithm for get closest point between a line segment
    Algorithm based in https://goo.gl/PkLqhe
    :param seg: one line segment
    :param points: a list of points
    :return: a point more closest
    """
    distance = math.inf
    point = None

    for i in points:
        value = __nearest_distance(seg, i)
        if value < distance:
            distance = value
            point = Point(i.get_x(), i.get_y())

    return point
Esempio n. 4
0
def convex_polygon(poly: Polygon):
    if len(poly.get_list_points()) < 3:
        return False

    list_points = poly.get_list_points()

    res = 0
    for i in range(len(list_points)):
        p = list_points[i]
        tmp = list_points[((i+1) % len(list_points))]
        vx = tmp.get_x() - p.get_x()
        vy = tmp.get_y() - p.get_y()
        v = Point(vx, vy)
        u = list_points[((i+2) % len(list_points))]

        if i == 0:
            res = u.get_x() * v.get_y() - u.get_y() * v.get_x() + v.get_x() * p.get_y() - v.get_y() * p.get_x()
        else:
            new_res = u.get_x() * v.get_y() - u.get_y() * v.get_x() + v.get_x() * p.get_y() - v.get_y() * p.get_x()
            if (new_res > 0 and res < 0) or (new_res < 0 and res > 0):
                return False

    return True
Esempio n. 5
0
                strip.append(py[i])

        return min(d, ClosestPair.strip_closest(strip, len(strip), d, points))

    def get_closest_points(self):
        points = self.points

        px = copy.deepcopy(self.p)
        py = copy.deepcopy(self.p)

        px.sort(key=cmp_to_key(ClosestPair.compare_x))
        py.sort(key=cmp_to_key(ClosestPair.compare_y))

        ClosestPair.closest_util(px, py, len(px), points)

        return points.minDistance, points.point_1, points.point_2


if __name__ == '__main__':
    a = []
    a.append(Point(2, 3))
    a.append(Point(12, 30))
    a.append(Point(40, 50))
    a.append(Point(5, 1))
    a.append(Point(12, 10))
    a.append(Point(3, 4))

    asd = ClosestPair(a)

    print(asd.get_closest_points())
Esempio n. 6
0
        new_set = Set()
        Set.__add_difference(self.__binTree.get_root(), b, new_set)
        return new_set

    def __len__(self):
        return len(self.__binTree)

    def get_iterator(self):
        return self.__binTree.get_root()


if __name__ == '__main__':
    set1 = Set()
    set2 = Set()

    p1 = Point(1, 2)
    p2 = Point(3, 4)
    p3 = Point(5, 6)
    p4 = Point(7, 8)

    p1_copy = Point(1, 2)

    set1.insert(p1)
    set1.insert(p2)
    set1.insert(p3)

    set2.insert(p3)
    set2.insert(p4)

    set3 = set1.union(set2)
    set4 = set1.intersection(set2)
Esempio n. 7
0
        return self.__list_points

    def remove_point(self, p: Point):
        remove_seg = []

        for i in self.__segments.get_iterator():
            if i.get_a().comparable(i.get_a(), p) == 0 or i.get_b().comparable(
                    i.get_b(), p) == 0:
                remove_seg.append(i)

        for i in remove_seg:
            self.__segments.delete(i)

        for i in self.__list_points:
            if i.get_x() == p.get_x() and i.get_y() == p.get_y():
                self.__list_points.remove(i)
                break

    def get_list(self):
        return self.__list_tuple


if __name__ == '__main__':
    p = Polygon()
    p.add_segment(LineSegment(Point(1, 2), Point(2, 3)))
    p.add_segment(LineSegment(Point(2, 3), Point(5, 6)))
    p.add_segment(LineSegment(Point(5, 6), Point(1, 2)))

    p.remove_point(Point(1, 2))
    print('aaa')
Esempio n. 8
0
    def onClick(self, event):
        if not self.LOCK:
            self.w.create_oval(event.x - self.RADIUS,
                               event.y - self.RADIUS,
                               event.x + self.RADIUS,
                               event.y + self.RADIUS,
                               fill="black")
            self.pts.append((event.x, event.y))

            if self.btnCirculo['state'] == tk.NORMAL:
                if len(self.pts) == 2:
                    p1 = Point(self.pts[0][0], self.pts[0][1])
                    p2 = Point(self.pts[1][0], self.pts[1][1])

                    distance = classics.distance_between_two_points(p1, p2)
                    circle = Circle(p1, int(distance))
                    self.circles.append(circle)

                    self.draw_circle(p1.get_x(), p1.get_y(),
                                     circle.get_radius())
                    nome = "Circ" + str(len(self.circles))
                    self.w.create_text(p1.get_x(),
                                       p1.get_y() + circle.get_radius() + 7,
                                       text=nome)

                    self.liberaTodosBotoes()
                    self.LOCK = True
                    self.pts.clear()
            elif self.btnLinha['state'] == tk.NORMAL:
                if len(self.pts) == 2:
                    p1 = Point(self.pts[0][0], self.pts[0][1])
                    p2 = Point(self.pts[1][0], self.pts[1][1])

                    line = Line.generate_by_two_points(p1, p2)
                    self.lines.append(line)

                    p1_x_canvas = line.get_x_from_y(0)
                    p2_x_canvas = line.get_x_from_y(500)

                    self.w.create_line(int(p1_x_canvas),
                                       0,
                                       int(p2_x_canvas),
                                       500,
                                       fill="RoyalBlue2")
                    nome = "Lin" + str(len(self.lines))
                    self.w.create_text((p1_x_canvas + p2_x_canvas) / 2,
                                       (0 + 500) / 2,
                                       text=nome)

                    self.liberaTodosBotoes()
                    self.LOCK = True
                    self.pts.clear()
            elif self.btnSegmento['state'] == tk.NORMAL:
                if len(self.pts) == 2:
                    p1 = Point(self.pts[0][0], self.pts[0][1])
                    p2 = Point(self.pts[1][0], self.pts[1][1])

                    seg = LineSegment(p1, p2)
                    self.segments.append(seg)

                    self.w.create_line(p1.get_x(),
                                       p1.get_y(),
                                       p2.get_x(),
                                       p2.get_y(),
                                       fill='red')
                    nome = "Seg" + str(len(self.segments))
                    self.w.create_text((p1.get_x() + p2.get_x()) / 2,
                                       (p1.get_y() + p2.get_y()) / 2,
                                       text=nome)

                    self.liberaTodosBotoes()
                    self.LOCK = True
                    self.pts.clear()
            elif self.btnPonto['state'] == tk.NORMAL:
                p = Point(self.pts[0][0], self.pts[0][1])
                self.points.append(p)

                nome = "Ptn" + str(len(self.points))
                self.w.create_text(p.get_x(), p.get_y() + 10, text=nome)
                self.pts.clear()
            elif self.btnPolygon['state'] == tk.NORMAL:
                if len(self.pts) == 2:
                    p1 = Point(self.pts[0][0], self.pts[0][1])
                    p2 = Point(self.pts[1][0], self.pts[1][1])

                    seg = LineSegment(p1, p2)
                    self.polygons[len(self.polygons) - 1].add_segment(seg)

                    self.w.create_line(p1.get_x(),
                                       p1.get_y(),
                                       p2.get_x(),
                                       p2.get_y(),
                                       fill='blue')

                    del self.pts[0]
Esempio n. 9
0
def make_diameter(p0: Point, p1: Point):
    cx = (p0.get_x() + p1.get_x()) / 2.0
    cy = (p0.get_y() + p1.get_y()) / 2.0
    r0 = math.hypot(cx - p0.get_x(), cy - p0.get_y())
    r1 = math.hypot(cx - p1.get_x(), cy - p1.get_y())
    return Circle(Point(cx, cy), max(r0, r1))
Esempio n. 10
0
    cy -= oy
    d = (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)) * 2.0
    if d == 0.0:
        return None
    x = ox + ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) *
              (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d
    y = oy + ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) *
              (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d
    ra = math.hypot(x - p0.get_x(), y - p0.get_y())
    rb = math.hypot(x - p1.get_x(), y - p1.get_y())
    rc = math.hypot(x - p2.get_x(), y - p2.get_y())
    return Circle(Point(x, y), max(ra, rb, rc))


def make_diameter(p0: Point, p1: Point):
    cx = (p0.get_x() + p1.get_x()) / 2.0
    cy = (p0.get_y() + p1.get_y()) / 2.0
    r0 = math.hypot(cx - p0.get_x(), cy - p0.get_y())
    r1 = math.hypot(cx - p1.get_x(), cy - p1.get_y())
    return Circle(Point(cx, cy), max(r0, r1))


# Retorna duas vezes a área assinada do triângulo definido por (x0, y0), (x1, y1), (x2, y2).
def _cross_product(x0, y0, x1, y1, x2, y2):
    return (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)


if __name__ == '__main__':
    points = [Point(1, 1), Point(4, 3), Point(5, 3), Point(3, 1)]
    c = make_circle(points)