示例#1
0
    def render(self,
               size: Tuple[int, int] = (512, 512),
               view_box: str = "-0.5 -0.5 1.0 1.0",
               **extra) -> Drawing:
        drawing = Drawing("", size, viewBox=view_box, **extra)

        for view in self.views:
            projection = np.dot(view.camera.view, view.camera.projection)

            clip_path = drawing.defs.add(drawing.clipPath())
            clip_min = view.viewport.minx, view.viewport.miny
            clip_size = view.viewport.width, view.viewport.height
            clip_path.add(drawing.rect(clip_min, clip_size))

            # TODO: Handle Z-index with meshes
            for group in view.scene.groups:
                for g in self._create_group(drawing, projection, view.viewport,
                                            group):
                    g["clip-path"] = clip_path.get_funciri()
                    drawing.add(g)
        return drawing
    def draw_path_clip(self):
        path_filename = "{}/path_clip_{}.svg".format(
            self.output_folder,
            basename(self.filename).replace(".svg", ""))
        dwg = Drawing(path_filename)
        image_bbox = calc_overall_bbox(self.tile_paths)

        dx = self.pent_x - min(image_bbox[0], image_bbox[1])
        dy = self.pent_y - min(image_bbox[2], image_bbox[3])
        dwg.add(
            dwg.path(
                **{
                    "d": self.new_pentagon().d(),
                    "fill": "none",
                    'stroke-width': 4,
                    'stroke': rgb(0, 0, 0)
                }))
        neg_transform = "translate({}, {})".format(-dx, -dy)
        transform = "translate({}, {})".format(dx, dy)
        clip_path = dwg.defs.add(
            dwg.clipPath(id="pent_path", transform=neg_transform))
        clip_path.add(dwg.path(d=self.new_pentagon().d()))
        group = dwg.add(
            dwg.g(clip_path="url(#pent_path)",
                  transform=transform,
                  id="clippedpath"))
        for i, path in enumerate(self.tile_paths):
            group.add(
                dwg.path(d=path.d(),
                         style=self.tile_attributes[i].get('style'),
                         id=self.tile_attributes[i]['id']))
        dwg.add(dwg.use("#clippedpath", transform="transform(100, 100)"))

        dwg.viewbox(self.pent_x, self.pent_y, self.pent_width,
                    self.pent_height)
        dwg.save()
        xml = xml.dom.minidom.parse(path_filename)
        open(path_filename, "w").write(xml.toprettyxml())
示例#3
0
    def render(self, dwg: Drawing) -> Group:
        g = dwg.g()

        # Render antennae
        antennae_rho = self.size * self.antennae_rho
        antennae_base_phi = 1.5 * math.pi
        antennae_delta_phi = 0.2 * math.pi
        antennae_delta_phi_total = (self.antennae_count -
                                    1) * antennae_delta_phi
        antennae_left_phi = antennae_base_phi - antennae_delta_phi_total / 2

        for i in range(self.antennae_count):
            antennae_coords = (
                antennae_rho *
                math.cos(antennae_left_phi + i * antennae_delta_phi),
                antennae_rho *
                math.sin(antennae_left_phi + i * antennae_delta_phi))

            antenna = dwg.circle(center=antennae_coords,
                                 r=self.size * self.antennae_relative_size,
                                 fill=self.color)

            path = dwg.path(stroke=helper.colors.darken_hex(self.color),
                            stroke_width=3)
            path.push("M %f %f" % antennae_coords)
            path.push("L %f %f" % (0, 0))

            g.add(path)
            g.add(antenna)

        # Render body
        shadow_mask = dwg.defs.add(dwg.clipPath(id="bodymask-%s" % self.id))
        shadow_mask.add(dwg.circle(center=(0, 0), r=self.size))

        body_dark = dwg.circle(center=(0, 0),
                               r=self.size,
                               stroke_width=0,
                               fill=helper.colors.darken_hex(self.color),
                               clip_path="url(#bodymask-%s)" % self.id)
        g.add(body_dark)

        body_highlight = dwg.circle(center=(-self.size * .2, -self.size * .2),
                                    r=self.size * .95,
                                    stroke_width=0,
                                    fill=self.color,
                                    clip_path="url(#bodymask-%s)" % self.id)
        g.add(body_highlight)

        # Render eyes
        eye_rho = self.size * self.eye_distance
        eye_base_phi = 1.5 * math.pi
        eye_delta_phi = 0.3 * math.pi
        eye_delta_phi_total = (self.eye_count - 1) * eye_delta_phi
        eye_left_phi = eye_base_phi - eye_delta_phi_total / 2

        for eye_i in range(self.eye_count):
            eye_coords = (eye_rho *
                          math.cos(eye_left_phi + eye_i * eye_delta_phi),
                          eye_rho *
                          math.sin(eye_left_phi + eye_i * eye_delta_phi))

            eye = self.eye_factory(self.size * self.eye_relative_size)
            eye_g = eye.render(dwg)
            eye_g.translate(eye_coords[0], eye_coords[1])

            g.add(eye_g)

        # Render mouth
        mouth = self.mouth_factory(self.size * self.mouth_relative_size,
                                   helper.colors.darken_hex(self.color, .75))
        mouth_g = mouth.render(dwg)
        mouth_g.translate(0, self.size * self.mouth_height)

        g.add(mouth_g)

        return g
    def draw_pattern(self):
        self.output_filename = "{}/snake_tiling_m_{}_{}.svg".format(
            self.output_folder, self.dx, self.dy)
        dwg = Drawing(self.output_filename)
        # add background panel
        background_clippath = dwg.rect(insert=(self.pattern_viewbox[0],
                                               self.pattern_viewbox[1]),
                                       size=('100%', '100%'))
        background_panel = dwg.rect(insert=(self.pattern_viewbox[0],
                                            self.pattern_viewbox[1]),
                                    size=('101%', '101%'),
                                    fill='#3072a2')
        clip_path = dwg.defs.add(dwg.clipPath(id="background_panel"))
        clip_path.add(background_clippath)
        clipped_drawing = dwg.add(
            dwg.g(clip_path="url(#background_panel)", id="clippedpath"))
        clipped_drawing.add(background_panel)
        current_color = 0

        def add_pentagon(group, transform, current_color, draw_pent=True):
            pent_group = group.add(
                dwg.g(transform=format_transform(*transform)))
            if draw_pent:
                pent_group.add(
                    dwg.path(
                        **{
                            'd': self.new_pentagon().d(),
                            'fill': self.colors[current_color %
                                                len(self.colors)],
                            'stroke-width': 4,
                            'stroke': rgb(0, 0, 0)
                        }))
            return pent_group

        for y in range(self.num_down):
            transform = "translate({}, {})".format(0, self.rep_spacing * y)
            dgroup = clipped_drawing.add(dwg.g(transform=transform))
            for x in range(self.num_across):
                # if x is odd, point 1 of pent 1 needs to be attached to point 3 of pent 2
                if x % 2 == 1:
                    dx = int(
                        x / 2
                    ) * self.rep_spacing + self.pent_width * 2 + self.column_offset.real
                    diff = dx + self.column_offset.imag * 1j
                else:
                    diff = int(x / 2) * self.rep_spacing
                for i in range(4):
                    snake_bbox = calc_overall_bbox(self.tile_paths)
                    snake_width, snake_height = abs(snake_bbox[0] - snake_bbox[1]), \
                                                abs(snake_bbox[2] - snake_bbox[3])
                    pent_group = add_pentagon(
                        dgroup,
                        (self.transforms[i][0], self.transforms[i][1] + diff),
                        current_color,
                        draw_pent=False)
                    for i, path in enumerate(self.tile_paths):
                        stransform = 'translate({},{})'.format(
                            snake_width * self.dx, snake_height * self.dy)
                        pent_group.add(
                            dwg.path(
                                **{
                                    'd': path.d(),
                                    'style': self.tile_attributes[i].get(
                                        'style'),
                                    'id': self.tile_attributes[i]['id'],
                                    'transform': stransform
                                }))
                    current_color += 1

        dwg.viewbox(*self.pattern_viewbox)
        dwg.save()