예제 #1
0
 def move_to_origin(self):
     size = self.original_size
     self.wmin = Coordinate((-size.width / 2) + CLIP_BOUNDARY,
                            (-size.height / 2) + CLIP_BOUNDARY)
     self.wmax = Coordinate((size.width / 2) - CLIP_BOUNDARY,
                            (size.height / 2) - CLIP_BOUNDARY)
     self.angle = 0
     self._notify()
예제 #2
0
    def untransform_coordinate(self, coordinate: Coordinate) -> Coordinate:
        coordinate = coordinate.rotate(self.vcenter, -self.angle)

        x = coordinate.x / (self.vmax.x - self.vmin.x) * (
            self.wmax.x - self.wmin.x) + self.wmin.x
        y = coordinate.y / (self.vmax.y - self.vmin.y) * (
            self.wmax.y - self.wmin.y) + self.wmin.y

        return Coordinate(x, y)
예제 #3
0
    def transform_coordinate(self, coordinate: Coordinate) -> Coordinate:
        coordinate = coordinate.rotate(self.wcenter, self.angle)

        x = (coordinate.x - self.wmin.x) / (self.wmax.x - self.wmin.x) * (
            self.vmax.x - self.vmin.x)
        y = (coordinate.y - self.wmin.y) / (self.wmax.y - self.wmin.y) * (
            self.vmax.y - self.vmin.y)

        return Coordinate(x, y)
예제 #4
0
    def on_press_drawing_area(self, drawing_area, event):
        click = Coordinate(event.x, event.y)

        if self.creating_wireframe is not None:
            untransformed_click = self.vp.untransform_coordinate(click)
            self.creating_wireframe.append(untransformed_click)
            self._refresh()

        return True
예제 #5
0
    def cohen_sutherland(self, c0: Coordinate, c1: Coordinate):
        while True:
            code0 = self._code(c0)
            code1 = self._code(c1)

            if (code0 | code1) == 0:
                return True, c0, c1

            elif (code0 & code1) != 0:
                return False, None, None

            else:
                out = code0 if code0 != 0 else code1

                x = None
                y = None

                if (out & TOP) != 0:
                    x = c0.x + (c1.x - c0.x) * (self.vmin.y - c0.y) / (c1.y -
                                                                       c0.y)
                    y = self.vmin.y

                elif (out & BOTTOM) != 0:
                    x = c0.x + (c1.x - c0.x) * (self.vmax.y - c0.y) / (c1.y -
                                                                       c0.y)
                    y = self.vmax.y

                elif (out & RIGHT) != 0:
                    x = self.vmax.x
                    y = c0.y + (c1.y - c0.y) * (self.vmax.x - c0.x) / (c1.x -
                                                                       c0.x)

                elif (out & LEFT) != 0:
                    x = self.vmin.x
                    y = c0.y + (c1.y - c0.y) * (self.vmin.x - c0.x) / (c1.x -
                                                                       c0.x)

                assert x is not None and y is not None

                if out == code0:
                    c0 = Coordinate(x, y)
                else:
                    c1 = Coordinate(x, y)
예제 #6
0
    def _refresh(self):
        self._refresh_list()
        self._clear_surface()

        pencil = Pencil(self.surface)
        clipper = Clipper(self.vp.cmin, self.vp.cmax)

        for wireframe in self.vp.get_grid():
            clipped_wireframes = clipper.clip(wireframe)
            for w in clipped_wireframes:
                pencil.draw_wireframe(w)

        origin = self.vp.transform_coordinate(Coordinate(0, 0))
        if clipper.inside(origin):
            pencil.line_width(10)
            pencil.color(Color(0, 0, 0, 0.5))
            pencil.draw_point(origin)

        pencil.line_width(1.5)

        for wireframe in self.df.wireframes:
            transformed_wireframe = self.vp.transform_wireframe(wireframe)

            clipped_wireframe = clipper.clip(transformed_wireframe)

            for w in clipped_wireframe:
                pencil.draw_wireframe(w)

        if self.creating_wireframe is not None:
            new_wireframe = Wireframe(
                id='creating',
                coordinates=self.creating_wireframe,
                color=Color(1, 0, 0)
            )

            transformed_wireframe = self.vp.transform_wireframe(new_wireframe)
            pencil.draw_wireframe(transformed_wireframe)

        clipping_square = Wireframe.square(
            'clipping_square',
            self.vp.cmin,
            self.vp.cmax,
            color=Color(1, 0.5, 0),
        )

        pencil.draw_wireframe(clipping_square)

        self.window.queue_draw()
예제 #7
0
    def apply(self, df: DisplayFile, vp: Viewport):
        wireframe = df[self.oid]

        if wireframe is None:
            raise ValueError('invalid oid')

        new = None

        if self.type == 'translate':
            if self.x is None or self.y is None:
                raise ValueError('scale')

            new = wireframe.translate(Delta(self.x, self.y).rotate(-vp.angle))

        if self.type == 'scale':
            if self.x is None or self.y is None:
                raise ValueError('scale')

            new = wireframe.scale(Delta(self.x, self.y))

        if self.type == 'rotate_world':
            if self.theta is None:
                raise ValueError('rotate_world')

            new = wireframe.rotate_on_world(self.theta)

        if self.type == 'rotate_coordinate':
            if self.x is None or self.y is None or self.theta is None:
                raise ValueError('rotate_coordinate')

            new = wireframe.rotate_on_coordinate(Coordinate(self.x, self.y),
                                                 self.theta)

        if self.type == 'rotate_self':
            if self.theta is None:
                raise ValueError('rotate_self')

            new = wireframe.rotate_on_center(self.theta)

        if new is not None:
            df.replace(self.oid, new)
예제 #8
0
    def __init__(self, size: Size, on_changed: Callable[[], None]):
        self.original_size = size
        self.wmin = Coordinate((-size.width / 2) + CLIP_BOUNDARY,
                               (-size.height / 2) + CLIP_BOUNDARY)
        self.wmax = Coordinate((size.width / 2) - CLIP_BOUNDARY,
                               (size.height / 2) - CLIP_BOUNDARY)

        self.vmin = Coordinate(0, 0)
        self.vmax = Coordinate(size.width, size.height)

        self.cmin = Coordinate(CLIP_BOUNDARY, CLIP_BOUNDARY)
        self.cmax = Coordinate(size.width - CLIP_BOUNDARY,
                               size.height - CLIP_BOUNDARY)

        self.angle = 0

        self.on_changed = on_changed
예제 #9
0
 def vcenter(self) -> Coordinate:
     return Coordinate(
         (self.vmin.x + self.vmax.x) / 2,
         (self.vmin.y + self.vmax.y) / 2,
     )