def clip_region(vertices, clipping_region): clipped = [] for v1, v2 in poly_iter(vertices): regions = [ CohenRegion.region(v) & clipping_region for v in [v1, v2]] if all([region != clipping_region for region in regions]): clipped.extend([v1, v2]) elif all([region == clipping_region for region in regions]): continue elif any([region == clipping_region for region in regions]): clip_index = 0 if regions[0] == clipping_region else 1 dx, dy, _ = v2 - v1 m = dx / dy if clipping_region == CohenRegion.TOP: x = v1.x + m * (1 - v1.y) y = 1 elif clipping_region == CohenRegion.BOTTOM: x = v1.x + m * (-1 - v1.y) y = -1 elif clipping_region == CohenRegion.RIGHT: x = 1 y = v1.y + (1 - v1.x) / m elif clipping_region == CohenRegion.LEFT: x = -1 y = v1.y + (-1 - v1.x) / m if clip_index == 0: v1 = Vetor2D(x, y) else: v2 = Vetor2D(x, y) clipped.extend([v1, v2]) return clipped
def viewport(self) -> Rectangle: widget = self.builder.get_object('drawing_area') return Rectangle(min=Vetor2D(0, 0), max=Vetor2D( widget.get_allocated_width(), widget.get_allocated_height(), )).with_margin(10)
def onResize(self, widget: Gtk.Widget, allocation: Gdk.Rectangle): w_proportion = allocation.width / self.size[0] h_proportion = allocation.height / self.size[1] self.view.window.max = Vetor2D(self.view.window.max.x * w_proportion, self.view.window.max.y * h_proportion) self.view.window.min = Vetor2D(self.view.window.min.x * w_proportion, self.view.window.min.y * h_proportion) self.size = (allocation.width, allocation.height) self.view.update_norm_coord()
def onOk(self, widget): window = self.builder.get_object("dialog_object") notebook = self.builder.get_object("notebook1") page_number = notebook.get_current_page() name = entry_text(self, "name_entry") if OBJECT_TYPES[page_number] == "point": print("Ponto") x = float(entry_text(self, 'entry_x')) y = float(entry_text(self, 'entry_y')) self.dialog.new_object = Point(Vetor2D(x, y), name=name) elif OBJECT_TYPES[page_number] == "line": print("Reta") x1 = float(entry_text(self, 'entry_x1')) y1 = float(entry_text(self, 'entry_y1')) x2 = float(entry_text(self, 'entry_x2')) y2 = float(entry_text(self, 'entry_y2')) self.dialog.new_object = Line(Vetor2D(x1, y1), Vetor2D(x2, y2), name=name) elif OBJECT_TYPES[page_number] == "polygon": print("Polígono") if len(self.vertices) >= 3: filled = self.builder.get_object('switch_filled').get_active() self.dialog.new_object = Polygon(self.vertices, name=name, filled=filled) elif OBJECT_TYPES[page_number] == "curve": print("Curva") if self.builder.get_object('btn_bezier').get_active(): type = 'bezier' elif self.builder.get_object('btn_bspline').get_active(): type = 'bspline' if len(self.vertices) >= 4: self.dialog.new_object = Curve.control_point(self.vertices, type=type, name=name) else: print("Invalid Page") raise ValueError('No page with given index.') window.destroy()
def cohen_sutherland_line_clip(line: Line) -> Line: nova_linha = copy.deepcopy(line) inicio, fim = nova_linha.normalized_vertices regions = [ CohenRegion.region(v) for v in (inicio, fim) ] while True: # dois pontos dentro if all([r == CohenRegion.INSIDE for r in regions]): return nova_linha # dois pontos fora elif regions[0] & regions[1] != 0: return clip_index = 0 if regions[0] != CohenRegion.INSIDE else 1 dx, dy, _ = fim - inicio m = dx / dy if regions[clip_index] & CohenRegion.TOP != 0: x = inicio.x + m * (1 - inicio.y) y = 1 elif regions[clip_index] & CohenRegion.BOTTOM != 0: x = inicio.x + m * (-1 - inicio.y) y = -1 elif regions[clip_index] & CohenRegion.RIGHT != 0: x = 1 y = inicio.y + (1 - inicio.x) / m elif regions[clip_index] & CohenRegion.LEFT != 0: x = -1 y = inicio.y + (-1 - inicio.x) / m if clip_index == 0: inicio = Vetor2D(x, y) nova_linha.normalized_vertices[0] = inicio regions[0] = CohenRegion.region(inicio) else: fim = Vetor2D(x, y) nova_linha.normalized_vertices[1] = fim regions[1] = CohenRegion.region(fim)
def onDraw(self, widget, cr): if self.view.window is None: self.size = (widget.get_allocated_width(), widget.get_allocated_height()) self.view.window = Window( Vetor2D(-self.size[0] / 2, -self.size[1] / 2), Vetor2D(self.size[0] / 2, self.size[1] / 2), ) viewport = self.viewport() vp_matrix = viewport_matrix(viewport) cr.set_line_width(1.0) cr.paint() cr.set_source_rgb(0, 0, 100) for object in self.view.obj_list: clipped = object.clipped(method=self.clipping_method) if clipped: clipped.draw(cr, vp_matrix) viewport.draw(cr, vp_matrix)
def onAddPoint(self, widget): notebook = self.builder.get_object("notebook1") page_number = notebook.get_current_page() if OBJECT_TYPES[page_number] == "polygon": x = float(entry_text(self, 'entry_x3')) y = float(entry_text(self, 'entry_y3')) elif OBJECT_TYPES[page_number] == "curve": x = float(entry_text(self, "entry_x4")) y = float(entry_text(self, "entry_y4")) self.vertices.append(Vetor2D(x, y)) print(f'Ponto Adicionado: {x}, {y}')
def navigationButton(self, widget): TRANSFORMATIONS = { 'nav-move-up': ('translate', Vetor2D(0, 10)), 'nav-move-down': ('translate', Vetor2D(0, -10)), 'nav-move-left': ('translate', Vetor2D(-10, 0)), 'nav-move-right': ('translate', Vetor2D(10, 0)), 'nav-rotate-left': ('rotate', -5), 'nav-rotate-right': ('rotate', 5), 'nav-zoom-in': ('scale', Vetor2D(1.1, 1.1)), 'nav-zoom-out': ('scale', Vetor2D(0.9, 0.9)), } op, *args = TRANSFORMATIONS[widget.get_name()] for object in self.selected_objs(): if op == 'translate': args[0] = (args[0] @ rotation_matrix(self.view.window.angle)) object.translate(*args) elif op == 'scale': object.scale(*args) elif op == 'rotate': try: arb_x = int(entry_text(self, 'rot_x')) arb_y = int(entry_text(self, 'rot_y')) except ValueError: arb_x = 0 arb_y = 0 ref = { RotationRef.CENTER: object.centroid, RotationRef.ORIGIN: Vetor2D(0, 0), RotationRef.ARBITRARY: Vetor2D(float(arb_x), float(arb_y)), }[self.rotation_ref] object.rotate(*args, ref) object.update_norm_coord(self.view.window) self.window.queue_draw()