Beispiel #1
0
    def _write(self, shapes, svg_file, args):
        stroke_width = args.stroke_width if args.stroke_width else "0.1%"

        write_preamble(args, svg_file)

        shift = Vector2D(args.width / 2.0, args.height / 2.0)
        for points, polygon in shapes:
            rgb = self.parts.colours.get(polygon.colour, "#ffffff")
            stroke_colour = args.stroke_colour if args.stroke_colour else rgb
            context = dict(rgb=rgb,
                           stroke_width=stroke_width,
                           stroke_colour=stroke_colour,
                           opacity=self._opacity_from_colour(polygon.colour))
            if len(points) == 2:
                context['point1'] = Vector2D(points[0].x, -points[0].y) + shift
                context['point2'] = Vector2D(points[1].x, -points[1].y) + shift

                svg_file.write(SVG_LINE.format(**context))
            else:
                svg_file.write(SVG_POLYGON_PREAMBLE.format(**context))
                for point in points:
                    dpoint = Vector2D(point.x, -point.y) + shift
                    svg_file.write('{point.x:.6f},{point.y:.6f} '.format(point=dpoint))
                svg_file.write('" />\n')
        svg_file.write("</svg>\n")
        svg_file.close()
Beispiel #2
0
def _project_polygons(width, height, polygons):
    # vx' = width + az
    # vy' = height + bz
    pixel_x = 0.5
    pixel_y = 0.5
    half_width = width / 2.0
    half_height = height / 2.0
    new_polygons = []
    for polygon in polygons:
        new_points = []
        for point in polygon.points:
            point_x = half_width * (point.x / (half_width + pixel_x * -point.z))
            point_y = half_height * (point.y / (half_height + pixel_y * -point.z))
            new_point = Vector2D(point_x, point_y)
            new_points.append(new_point)
        new_polygons.append((new_points, polygon))
    return new_polygons
Beispiel #3
0
def project_polygons(width, height, polygons):
    # vx' = width + az
    # vy' = height + bz
    print(len(polygons))
    pixel_x = 0.5
    pixel_y = 0.5
    half_width = width / 2.0
    half_height = height / 2.0
    new_polygons = []
    for polygon in polygons:
        new_points = []
        for point in polygon:
            point_x = half_width * (point["x"] / (half_width + pixel_x * -point["z"]))
            point_y = half_height * (point["y"] / (half_height + pixel_y * -point["z"]))
            new_point = Vector2D(point_x, point_y)
            new_points.append(new_point)
        new_polygons.append((new_points, polygon))
    
    return new_polygons
Beispiel #4
0
    def render(self, image, depth, viewport_scale, stroke_colour):
        """
        Sort the edges of the polygon by their minimum projected y
        coordinates, discarding horizontal edges.
        """
        edges = self.get_edges(image, viewport_scale)
        if not edges:
            return
        width, height = image.size

        end_py = edges[-1].point2.y
        if end_py < 0:
            return

        edge1 = edges.pop(0)

        if edge1.point1.y >= height:
            return

        edge2 = edges.pop(0)

        int_edge1_y1 = int(edge1.point1.y)

        if int_edge1_y1 < edge1.point1.y or int_edge1_y1 < edge2.point1.y:
            int_edge1_y1 += 1
        while int_edge1_y1 <= end_py and int_edge1_y1 < height:
            # Retrieve new edges as required.
            if int_edge1_y1 >= edge1.point2.y:
                if not edges:
                    break
                edge1 = edges.pop(0)
            if int_edge1_y1 >= edge2.point2.y:
                if not edges:
                    break
                edge2 = edges.pop(0)
            if int_edge1_y1 < 0:
                int_edge1_y1 += 1
                continue
            # Calculate the starting and finishing coordinates of the span
            # at the current y coordinate.
            gradient_1 = Vector2D(edge1.dx_dy, edge1.dz_dy)
            start_point_1 = Vector2D(edge1.point1.x, edge1.point1.z)
            start_1 = start_point_1 + (int_edge1_y1 -
                                       edge1.point1.y) * gradient_1

            gradient_2 = Vector2D(edge2.dx_dy, edge2.dz_dy)
            start_point_2 = Vector2D(edge2.point1.x, edge2.point1.z)
            start_2 = start_point_2 + (int_edge1_y1 -
                                       edge2.point1.y) * gradient_2

            # Do not render the span if it lies outside the image or has
            # values that cannot be stored in the depth buffer.
            # Truncate the span if it lies partially within the image.
            if start_1.x > start_2.x:
                start_2, start_1 = start_1, start_2
            # Only calculate a depth gradient for the span if it is more than
            # one pixel wide.
            if start_1.y <= 0 and start_2.y <= 0:
                int_edge1_y1 += 1
                continue
            elif start_1.y >= Z_MAX and start_2.y >= Z_MAX:
                int_edge1_y1 += 1
                continue

            start_x, end_sx = int(start_1.x), int(start_2.x)
            if start_x < start_1.x:
                start_x += 1
            if start_x >= width:
                int_edge1_y1 += 1
                continue
            elif end_sx < 0:
                int_edge1_y1 += 1
                continue

            int_edge1_y1 = self.draw_span(depth, end_sx, image, int_edge1_y1,
                                          start_1, start_2, start_x,
                                          stroke_colour, width)