コード例 #1
0
def __nearest_distance(seg: LineSegment, p: Point):
    a = p.get_x() - seg.get_a().get_x()
    b = p.get_y() - seg.get_a().get_y()
    c = seg.get_b().get_x() - seg.get_a().get_x()
    d = seg.get_b().get_x() - seg.get_a().get_y()

    dot = a * c + b * d
    q = c ** 2 + d ** 2
    param = -1

    if q != 0:
        param = dot / q

    if param < 0:
        xx = seg.get_a().get_x()
        yy = seg.get_a().get_y()
    elif param > 1:
        xx = seg.get_b().get_x()
        yy = seg.get_b().get_y()
    else:
        xx = seg.get_a().get_x() + param * c
        yy = seg.get_a().get_y() + param * d

    dx = p.get_x() - xx
    dy = p.get_y() - yy
    return math.sqrt(dx ** 2 + dy ** 2)
コード例 #2
0
def distance_between_two_points(pa: Point, pb: Point):
    """
    Get a distance between two points
    :param pa - Point A
    :param pb - Point B
    :return distance between point A and B
    """
    return math.sqrt(pow(pb.get_x() - pa.get_x(), 2) + pow(pb.get_y() - pa.get_y(), 2))
コード例 #3
0
def __points_orientation(p: Point, q: Point, r: Point):
    value = (q.get_y() - p.get_y()) * (r.get_x() - q.get_x()) - (q.get_x() - p.get_x()) * (r.get_y() - q.get_y())

    if value == 0:
        return 0
    elif value > 0:
        return 1
    else:
        return 2
コード例 #4
0
def _make_circle_two_points(points: list, p: Point, q: Point):
    circ = make_diameter(p, q)
    left = None
    right = None
    px = p.get_x()
    py = p.get_y()
    qx = q.get_x()
    qy = q.get_y()

    # para cada ponto que nao está no circulo
    for r in points:
        if classics.side_of_circle(circ, r) >= 0:
            continue

        # Formar uma circunferência e classificá-la no lado esquerdo ou direito
        cross = _cross_product(px, py, qx, qy, r.get_x(), r.get_y())
        c = make_circumcircle(p, q, r)
        if c is None:
            continue
        elif cross > 0.0 and (left is None
                              or _cross_product(px, py, qx, qy,
                                                c.get_centre().get_x(),
                                                c.get_centre().get_y()) >
                              _cross_product(px, py, qx, qy,
                                             left.get_centre().get_x(),
                                             left.get_centre().get_y())):
            left = c
        elif cross < 0.0 and (right is None
                              or _cross_product(px, py, qx, qy,
                                                c.get_centre().get_x(),
                                                c.get_centre().get_y()) <
                              _cross_product(px, py, qx, qy,
                                             right.get_centre().get_x(),
                                             right.get_centre().get_y())):
            right = c

    # selecionar qual circulo vai retornar
    if left is None and right is None:
        return circ
    elif left is None:
        return right
    elif right is None:
        return left
    else:
        return left if (left.get_radius() <= right.get_radius()) else right
コード例 #5
0
def distance_between_one_line_and_one_point(p: Point, l: Line):
    """
    Get a distance between one line and one point
    :param p: one point
    :param l: one line
    :return: distance between p and l
    """
    return (math.fabs(l.get_a() * p.get_x() + l.get_a() * p.get_y() + l.get_c())) / \
           math.sqrt(pow(l.get_a(), 2) + pow(l.get_b(), 2))
コード例 #6
0
def orient_2d(a: Point, b: Point, c: Point):
    """
    Orientation of tree points
    Algorithm based in http://www.geeksforgeeks.org/orientation-3-ordered-points/
    :param a: point 1
    :param b: point 2
    :param c: point 3
    :return: orientation
    """
    first = (b.get_y() - a.get_y()) * (c.get_x() - b.get_x())
    second = (c.get_y() - b.get_y()) * (b.get_x() - a.get_x())
    det = first - second

    if det == 0:
        return 0
    elif det > 0:
        return 1
    else:
        return -1
コード例 #7
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))
コード例 #8
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
コード例 #9
0
def point_in_polygon(p: Point, polygon: Polygon):
    cn = 0
    v = copy.deepcopy(polygon.get_list_points())
    v.append(v[0])

    for i in range(len(v)-1):
        if (v[i].get_y() <= p.get_y() and v[i+1].get_y() > p.get_y()) or \
           (v[i].get_y() > p.get_y() and v[i+1].get_y() <= p.get_y()):

            vt = (p.get_y() - v[i].get_y()) / float(v[i+1].get_y() - v[i].get_y())
            if p.get_x() < (v[i].get_x() + vt * (v[i+1].get_x() - v[i].get_x())):
                cn += 1

    return True if (cn % 2) == 1 else False
コード例 #10
0
def __point_in_segment(p: Point, s: LineSegment):
    px = p.get_x()
    py = p.get_y()

    sa_x = s.get_a().get_x()
    sa_y = s.get_a().get_y()
    sb_x = s.get_b().get_x()
    sb_y = s.get_b().get_y()

    if px <= max(sa_x, sb_x) and px >= min(sa_x, sb_x) and \
                    py <= max(sa_y, sb_y) and py >= min(sa_y, sb_y):
        return True
    else:
        return False
コード例 #11
0
    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
コード例 #12
0
 def compare_x(p1: Point, p2: Point):
     return p1.get_x() - p2.get_x()
コード例 #13
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]
コード例 #14
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))