Пример #1
0
 def __init__(self, obj_id, name, x, y):
     # Object constructor
     Object.__init__(self, obj_id, name, "Point")
     # Constructor of Point
     Point2D.__init__(self, x, y)
     self.nx = x
     self.ny = y
Пример #2
0
def clipCenter(start_point: Point2D, end_point: Point2D):
    x1 = start_point.x
    y1 = start_point.y

    TL, TR, BR, BL, M = getAngularCoeficients(start_point, end_point)

    if end_point.x > start_point.x:  # P2 is at the right of P1
        if M >= TR:  # TOP BORDER
            y2 = 1
            x2 = (y2 - y1) / M + x1

        elif BR <= M and M < TR:  # RIGHT BORDER
            x2 = 1
            y2 = (x2 - x1) * M + y1

        elif M < BR:  # BOTTOM BORDER
            y2 = -1
            x2 = (y2 - y1) / M + x1

    else:
        if M < TL:  # TOP BORDER
            y2 = 1
            x2 = (y2 - y1) / M + x1

        elif TL <= M and M < BL:  # LEFT BORDER
            x2 = -1
            y2 = M * (x2 - x1) + y1

        elif M >= BL:  # BOTTOM BORDER
            y2 = -1
            x2 = (y2 - y1) / M + x1

    return Line(Point2D(x1, y1), Point2D(x2, y2))
Пример #3
0
def calculateCSInterception(p: Point2D, regionCode, m, xe, xd, yf, yt):
    new_y = None
    new_x = None

    if regionCode & 1:  # LEFT
        new_x = xe
        new_y = m * (xe - p.x) + p.y
        if new_y <= yt and new_y >= yf:
            return Point2D(new_x, new_y)

    if regionCode & 2:  # RIGHT
        new_x = xd
        new_y = m * (xd - p.x) + p.y
        if new_y <= yt and new_y >= yf:
            return Point2D(new_x, new_y)

    if regionCode & 4:  # BOTTOM
        new_x = p.x + 1 / m * (yf - p.y)
        new_y = yf
        if new_x <= xd and new_x >= xe:
            return Point2D(new_x, new_y)

    if regionCode & 8:  # TOP
        new_x = p.x + 1 / m * (yt - p.y)
        new_y = yt
        return Point2D(new_x, new_y)
Пример #4
0
    def on_mouse_move(self, widget, event):
        # translate window
        if self.mouse_pressed:
            current_pos = Point2D(event.x, event.y)
            # self.main_window.print_log(f'event-x:{event.x} eventy:{event.y}')
            delta_viewport = Point2D(
                current_pos.x - self.mouse_start_pos.x,
                current_pos.y - self.mouse_start_pos.y,
            )
            # self.main_window.print_log(
            #         f'd_vp_x:{delta_viewport.x} d_vp_y:{delta_viewport.y}')
            delta_scn = self.viewport.viewport_to_scn(delta_viewport)
            # self.main_window.print_log(
            #         f'd_scn_x:{delta_scn.x} d_scn_y:{delta_scn.y}')
            delta_world = self.window.scn_to_world(delta_scn)

            def f_win(val):
                self.window.translate(Point2D(-val.x, -val.y), 2)

            def f_obj(obj_id, val):
                self.main_window.display_file[obj_id].translate(val)

            self.apply_to_selected_objects(delta_world, f_win, f_obj)

            self.mouse_start_pos = current_pos
            widget.queue_draw()
Пример #5
0
def clipEdge(start_point: Point2D, end_point: Point2D):
    y2 = end_point.y
    x2 = end_point.x

    TL, TR, BR, BL, M = getAngularCoeficients(start_point, end_point)

    # calculate LEFT border interception (general case)
    x1 = -1
    y1 = end_point.y - M * (end_point.x - x1)

    if M >= TL or M < BL:
        return None

    if M > TR:  # LEFT or TOP-LEFT
        if end_point.y >= 1:  # intercepts the TOP border too
            y2 = 1
            x2 = (y2 - y1) / M + x1

    elif M <= BR:  # LEFT or BOTTOM-LEFT
        if end_point.y <= -1:  # intercepts the BOTTOM border too
            y2 = -1
            x2 = (y2 - y1) / M + x1

    else:  # LEFT or LEFT-RIGHT
        if end_point.x >= 1:  # intercepts the RIGHT border too
            x2 = 1
            y2 = (x2 - x1) * M + y1

    return Line(Point2D(x1, y1), Point2D(x2, y2))
Пример #6
0
    def draw(self, transform: np.array, cairo):
        resolution = 50
        points = []

        array_x = np.array(
            [pt.x for pt in self.scn],
            dtype=float)

        array_y = np.array(
            [pt.y for pt in self.scn],
            dtype=float)

        if self.curve_type == CurveType.bezier:
            for section in range(0, len(self.scn) - 1, 3):
                for delta in np.linspace(0, 1, resolution):
                    T = np.array(
                        [delta**3, delta**2, delta, 1], dtype=float)
                    TM = T @ self.bezier_matrix
                    x = TM @ array_x[section:section + 4]
                    y = TM @ array_y[section:section + 4]
                    points.append(Point2D(x, y))

        elif self.curve_type == CurveType.b_spline:
            for i in range(0, len(self.scn) - 3):
                Gx = array_x[i:i + 4]
                Gy = array_y[i:i + 4]
                Cx = self.bspline_matrix @ Gx
                Cy = self.bspline_matrix @ Gy

                E = self.calc_bspline_foward(1.0 / resolution)
                Dx = E @ Cx
                Dy = E @ Cy

                for _ in range(resolution + 1):
                    x = Dx[0]
                    y = Dy[0]

                    Dx = Dx + np.append(Dx[1:], 0)
                    Dy = Dy + np.append(Dy[1:], 0)

                    points.append(Point2D(x, y))

        cairo.save()
        [vx, vy, _] = np.array(
            ([points[0].x, points[0].y, 1]),
            dtype=float).dot(transform)
        cairo.move_to(vx, vy)
        for i in range(1, len(points) - 1):
            x = points[i].x
            y = points[i].y
            [vx, vy, _] = np.array(
                ([x, y, 1]),
                dtype=float).dot(transform)
            if -1 < x and x < 1 and -1 < y and y < 1:
                cairo.line_to(vx, vy)
                cairo.stroke()

            cairo.move_to(vx, vy)
Пример #7
0
def clipCorner(start_point: Point2D, end_point: Point2D):
    x2 = end_point.x
    y2 = end_point.y

    TL, TR, BR, BL, M = getAngularCoeficients(start_point, end_point)

    if M >= TR or M <= BL:
        return None

    if TL < BR:  # case 1 (predominantly bottom)
        if M < TL:  # LEFT or LEFT-BOTTOM
            x1 = -1
            y1 = end_point.y - M * (end_point.x - x1)

            if end_point.y <= -1:  # intercepts BOTTOM border too
                y2 = -1
                x2 = (y2 - y1) / M + x1

        else:
            y1 = 1
            x1 = end_point.x - (end_point.y - y1) / M

            if M >= BR:  # TOP or TOP-RIGHT
                if end_point.x >= 1:
                    x2 = 1
                    y2 = (x2 - x1) * M + y1

            else:  # TOP or TOP-BOTTOM
                if end_point.y <= -1:
                    y2 = -1
                    x2 = (y2 - y1) / M + x1

    else:  # case 2 (predominantly right)
        if M >= TL:  # TOP or TOP-RIGHT
            y1 = 1
            x1 = end_point.x - (end_point.y - y1) / M

            if end_point.x >= 1:
                x2 = 1
                y2 = (x2 - x1) * M + y1

        else:
            x1 = -1
            y1 = end_point.y - M * (end_point.x - x1)

            if M <= BR:  # LEFT or LEFT-BOTTOM
                if end_point.y <= -1:  # intercepts BOTTOM border too
                    y2 = -1
                    x2 = (y2 - y1) / M + x1

            else:  # LEFT or LEFT-RIGHT
                if end_point.x >= 1:  # intercepts the RIGHT border too
                    x2 = 1
                    y2 = (x2 - x1) * M + y1

    return Line(Point2D(x1, y1), Point2D(x2, y2))
Пример #8
0
    def get_center(self, center):
        cx = (self.start.x + self.end.x) / 2
        cy = (self.start.y + self.end.y) / 2

        if center == 1:
            return Point2D(0, 0)
        elif center == 2:
            return Point2D(cx, cy)
        else:
            return self.start
Пример #9
0
    def get_center(self, center):
        cx = 0
        cy = 0
        for point in self.points:
            cx += point.x
            cy += point.y
        cx /= len(self.points)
        cy /= len(self.points)

        if center == 1:
            return Point2D(0, 0)
        elif center == 2:
            return Point2D(cx, cy)
        else:
            return self.points[0]
Пример #10
0
 def update_scn(self, transform):
     self.scn = []
     for index, point in enumerate(self.points):
         [vx, vy, _] = np.array(
                 ([self.points[index].x, self.points[index].y, 1]),
                 dtype=float).dot(transform)
         self.scn.append(Point2D(vx, vy))
Пример #11
0
    def cb_menu_file_new(self, *args):
        self.main_window.display_file.clear()
        self.store.clear()

        self.window = Window(Point2D(0, 0), 0, 200, 200)

        # re-draw objects on drawing_area
        self.main_window.drawing_area.queue_draw()
Пример #12
0
def cohenSutherlandClip(line: Line):
    p0 = line.start
    p1 = line.end

    codeP0 = computeOutCode(p0, -1, -1, 1, 1)
    codeP1 = computeOutCode(p1, -1, -1, 1, 1)

    if not (codeP0 | codeP1):
        # TOTALMENTE CONTIDA
        return line
    elif (codeP0 & codeP1):
        # TOTALMENTE FORA DA JANELA
        return None
    else:
        # PARCIALMENTE CONTIDA (CALCULAR CLIP PARA OS DOIS PONTOS)
        if p1.x == p0.x:
            y0 = p0.y
            y1 = p1.y
            if p1.y > 1: y1 = 1
            elif p1.y < -1: y1 = -1
            if p0.y < -1: y0 = -1
            elif p0.y > 1: y0 = 1
            return Line(Point2D(p0.x, y0), Point2D(p1.x, y1))

        m = (p1.y - p0.y) / (p1.x - p0.x)

        if codeP0:
            p0 = calculateCSInterception(p0, codeP0, m, -1, 1, -1, 1)

        if p0 and codeP1:
            p1 = calculateCSInterception(p1, codeP1, m, -1, 1, -1, 1)

        if not (p0) or not (p1):
            return None
        else:
            return Line(p0, p1)
Пример #13
0
 def __init__(self, main_window):
     self.main_window = main_window
     self.builder = main_window.builder
     self.main_window.filepath = "obj_files/persistance.obj"
     self.store = self.builder.get_object("liststore_obj")
     self.scrolled_window = self.builder.get_object("scrolled_window_log")
     self.lb_window_pos = self.builder.get_object("lb_window_pos")
     self.entry_step = self.builder.get_object("entry_step")
     self.entry_angle = self.builder.get_object("entry_angle")
     self.da_width = 0
     self.da_height = 0
     self.mouse_start_pos = None
     self.mouse_pressed = False
     self.window = Window(Point2D(0, 0), 0, 200, 200)
     self.viewport = Viewport(0, 0, 100, 100, 100, 100)
Пример #14
0
 def f_win(val):
     self.window.translate(Point2D(-val.x, -val.y), 2)
Пример #15
0
 def on_mouse_press(self, widget, event):
     # self.main_window.print_log("MOUSE PRESS")
     if event.button == MouseButtons.left:
         self.mouse_start_pos = Point2D(event.x, event.y)
         self.mouse_pressed = True
Пример #16
0
    def cb_menu_edit_reset_window(self, *args):
        self.window = Window(Point2D(0, 0), 0, 200, 200)

        # re-draw objects on drawing_area
        self.main_window.drawing_area.queue_draw()
Пример #17
0
    def bt_create_object_clicked_cb(self, button):
        page = self.builder.get_object("add_obj_notebook").get_current_page()

        try:
            name = self.builder.get_object("entry_obj_name").get_text()

            new_id = 0
            if self.main_window.display_file:
                new_id = max(self.main_window.display_file)
                new_id += 1

            # new point insertion
            if page == 0:
                x = float(self.builder.get_object("entry_point_x").get_text())
                y = float(self.builder.get_object("entry_point_y").get_text())

                if name == "":
                    name = f"Point {new_id}"
                obj = DrawablePoint2D(new_id, name, x, y)

            # new line insertion
            elif page == 1:
                x1 = float(self.builder.get_object("entry_line_x1").get_text())
                y1 = float(self.builder.get_object("entry_line_y1").get_text())
                x2 = float(self.builder.get_object("entry_line_x2").get_text())
                y2 = float(self.builder.get_object("entry_line_y2").get_text())

                if name == "":
                    name = f"Line {new_id}"
                obj = DrawableLine(new_id, name, Point2D(x1, y1),
                                   Point2D(x2, y2))

            # new wireframe insertion
            elif page == 2:
                buffer = self.builder.get_object(
                    "wireframe_points_view").get_buffer()
                start_iter = buffer.get_start_iter()
                end_iter = buffer.get_end_iter()
                entrada = buffer.get_text(start_iter, end_iter, False)
                entrada = entrada.split("\n")
                filled = self.builder.get_object("filled_check").get_active()

                pontos = []
                for i in range(len(entrada)):
                    x, y = entrada[i].split()
                    pontos.append(Point2D(float(x), float(y)))

                if name == "":
                    name = f"Wireframe {new_id}"
                obj = DrawablePolygon(new_id, name, pontos, filled)

            # add curve
            elif page == 3:
                curve_type = None
                if self.builder.get_object("rdb_bezier").get_active():
                    if name == "":
                        name = f"Bezier {new_id}"
                    curve_type = CurveType.bezier
                else:
                    if name == "":
                        name = f"B-spline {new_id}"
                    curve_type = CurveType.b_spline

                buffer = self.builder.get_object(
                    "curve_points_view").get_buffer()
                start_iter = buffer.get_start_iter()
                end_iter = buffer.get_end_iter()
                entrada = buffer.get_text(start_iter, end_iter, False)
                entrada = entrada.split("\n")

                pontos = []
                for i in range(len(entrada)):
                    x, y = entrada[i].split()
                    pontos.append(Point2D(float(x), float(y)))

                obj = DrawableCurve(new_id, name, pontos, curve_type)
            # end if

            if name == "":
                raise ValueError()

            self.main_window.display_file[obj.id] = obj

            store = self.builder.get_object("liststore_obj")
            store.append([obj.id, obj.name, obj.type])

            da = self.builder.get_object("gtk_drawing_area")
            da.draw(da.get_window().cairo_create())

            self.dialog_add_object.destroy()
        except ValueError:
            self.main_window.print_log(
                "Error: Invalid Value / All fields need to be defined\n")
Пример #18
0
 def __init__(self, obj_id, name, start, end):
     # constructor of Object
     Object.__init__(self, obj_id, name, "Line")
     # constructor of Line
     Line.__init__(self, start, end)
     self.scn = Line(Point2D(0, 0), Point2D(0, 0))
Пример #19
0
def nichollLeeNichollClip(line: Line):
    p1 = line.start
    p2 = line.end

    codeP1 = computeOutCode(p1, -1, -1, 1, 1)
    codeP2 = computeOutCode(p2, -1, -1, 1, 1)

    if (codeP1 | codeP2) == 0:  # trivially accepted
        return line
    elif (codeP1 & codeP2) > 0:  # trivially rejected
        return None

    if p1.x == p2.x:  # to prevent division by zero error
        x1 = p1.x
        x2 = p2.x
        y1 = p1.y
        y2 = p2.y

        if p1.y > 1:
            y1 = 1
        elif p1.y < -1:
            y1 = -1
        if p2.y > 1:
            y2 = 1
        elif p2.y < -1:
            y2 = -1

        return Line(Point2D(x1, y1), Point2D(x2, y2))

    if codeP1 == 0:  # CENTER
        clipped = clipCenter(p1, p2)

    elif codeP1 == 1:  # LEFT
        clipped = clipEdge(p1, p2)

    elif codeP1 == 2:  # RIGHT (-x, y)
        p1_aux = Point2D(-p1.x, p1.y)
        p2_aux = Point2D(-p2.x, p2.y)
        clipped = clipEdge(p1_aux, p2_aux)
        if clipped:
            clipped.start.x *= -1
            clipped.end.x *= -1

    elif codeP1 == 4:  # BOTTOM (y, x)
        p1_aux = Point2D(p1.y, p1.x)
        p2_aux = Point2D(p2.y, p2.x)
        clipped = clipEdge(p1_aux, p2_aux)

        if clipped:
            temp = clipped.start.x
            clipped.start.x = clipped.start.y
            clipped.start.y = temp
            temp = clipped.end.x
            clipped.end.x = clipped.end.y
            clipped.end.y = temp

    elif codeP1 == 8:  # TOP (-y, x)
        p1_aux = Point2D(-p1.y, p1.x)
        p2_aux = Point2D(-p2.y, p2.x)
        clipped = clipEdge(p1_aux, p2_aux)

        if clipped:
            temp = clipped.start.x
            clipped.start.x = clipped.start.y
            clipped.start.y = -temp
            temp = clipped.end.x
            clipped.end.x = clipped.end.y
            clipped.end.y = -temp

    elif codeP1 == 5:  # LEFT-BOTTOM (x, -y)
        p1_aux = Point2D(p1.x, -p1.y)
        p2_aux = Point2D(p2.x, -p2.y)
        clipped = clipCorner(p1_aux, p2_aux)
        if clipped:
            clipped.start.y *= -1
            clipped.end.y *= -1

    elif codeP1 == 6:  # RIGHT-BOTTOM (-x, -y)
        p1_aux = Point2D(-p1.x, -p1.y)
        p2_aux = Point2D(-p2.x, -p2.y)
        clipped = clipCorner(p1_aux, p2_aux)
        if clipped:
            clipped.start.x *= -1
            clipped.end.x *= -1
            clipped.start.y *= -1
            clipped.end.y *= -1

    elif codeP1 == 9:  # TOP-LEFT
        clipped = clipCorner(p1, p2)

    else:  # TOP-RIGHT (-x, y)
        p1_aux = Point2D(-p1.x, p1.y)
        p2_aux = Point2D(-p2.x, p2.y)
        clipped = clipCorner(p1_aux, p2_aux)
        if clipped:
            clipped.start.x *= -1
            clipped.end.x *= -1

    return clipped
Пример #20
0
 def f_win(amount):
     self.window.translate(Point2D(-x * amount, -y * amount), 1)
Пример #21
0
def weilerAthertonPolygonClip(polygon: Polygon):
    points = getOrderedPoints(polygon)

    # lista todas interseções
    i = 0
    while i < len(points):
        p1 = points[i]
        p2 = points[(i + 1) % len(points)]

        line = cohenSutherlandClip(Line(p1, p2))

        if line:
            t1 = pointClip(p1)
            t2 = pointClip(p2)
            if t1:
                if not t2:
                    np = line.end
                    np.pType = 2
                    insertPoint(points, np, i + 1)
            else:
                if t2:
                    np = line.start
                    np.pType = 1
                    insertPoint(points, np, i + 1)
                else:
                    np1 = line.start
                    np2 = line.end
                    np1.pType = 1
                    np2.pType = 2
                    insertPoint(points, np1, i + 1)
                    insertPoint(points, np2, i + 2)
                    i += 1
        i += 1
    # END FOR

    # nova lista dos pontos clip (varre as bordas externas)
    control = len(points)
    # borda superior
    sup = [Point2D(-1, 1)]
    for i in range(control):
        if points[i].y == 1 and points[i] not in sup:
            sup.append(points[i])
    sup.sort(key=lambda a: a.x)
    # borda direita
    right = [Point2D(1, 1)]
    for i in range(control):
        if points[i].x == 1 and points[i] not in right:
            right.append(points[i])
    right.sort(key=lambda a: a.y, reverse=True)
    # borda inferior
    inf = [Point2D(1, -1)]
    for i in range(control):
        if points[i].y == -1 and points[i] not in inf:
            inf.append(points[i])
    inf.sort(key=lambda a: a.x, reverse=True)
    # borda esquerda
    left = [Point2D(-1, -1)]
    for i in range(control):
        if points[i].x == -1 and points[i] not in left:
            left.append(points[i])
    left.sort(key=lambda a: a.y)

    clipping = sup + right + inf + left

    markUnvisited(points)

    # fluxo principal
    visible = []
    for i in range(
            len(points
                )):  # FLUXO PARA PERCORRER TODOS OS PONTOS DO OBJETO CLIPPADO
        if points[i].visited: continue

        if pointClip(points[i]):
            # DEFINE UM NOVO ESPACO PARA POLIGONO
            visible.append([])

            point = points[i]
            l = 1
            index = i
            while True:
                if point.visited:
                    break
                else:  # INSERE O PONTO NO POLIGONO A SER DESENHADO
                    point.visited = True
                    visible[-1].append(point)

                # DEFINING NEXT LIST
                if point.pType == 1:  # INCOMING
                    l = 1
                    index = (points.index(point) + 1)
                elif point.pType == 2:  # OUTGOING
                    l = 2
                    index = (clipping.index(point) + 1)
                else:
                    index = index + 1

                # DEFINING NEXT
                if l == 1:
                    point = points[index % len(points)]
                else:
                    point = clipping[index % len(clipping)]

            # end of visits
    # END FOR
    if len(visible):
        return visible
    else:
        return None
Пример #22
0
 def f_obj(obj_id, amount):
     self.main_window.display_file[obj_id].translate(
         Point2D(x * amount, y * amount))
Пример #23
0
 def clip(self, algorithm=None):
     if clip.pointClip(Point2D(self.nx, self.ny)):
         self.visible = True
     else:
         self.visible = False