Пример #1
0
    def _create_curve_arrow(scene: Drawing, start: tuple, point1: tuple,
                            point2: tuple, end: tuple, color: tuple):
        """Create an curved path (with cubic Bezier curve) around the given points in a scene.

        The path starts at `start` and ends at `end`. Points control_point1 and c2 are used as
        bezier control points.

        Args:
            scene (Scene): The scene where the path should be created.
            start: The start point.
            point1: The first control point.
            point2: The second control point.
            end: The end point.
            color: The arrow's color.

        Return:
            The modified scene
        """
        middle = (point1[0] + (point2[0] - point1[0]) // 2, point1[1])
        scene.add(
            Path(d=['M', start, 'C', point1, point1, middle],
                 stroke=rgb(*color),
                 stroke_width=1,
                 fill='none'))
        scene.add(
            Path(d=['M', middle, 'C', point2, point2, end],
                 stroke=rgb(*color),
                 stroke_width=1,
                 fill='none'))
Пример #2
0
 def draw(self, svg_file):
     
     if self.intensity < self.filter_ratio:
         return
     
     lines = int(max(min(30 * self.intensity, 40), 1))
     y_disp = float(self.block_size) / lines
     
     start = (self.left, self.top)
     end = (self.left, self.top)
     
     path = Path(("M", self.left, self.top), stroke="black", stroke_width="0.3", fill="none")
     
     # Stop when we hit the bottom
     while start[1] < self.bottom:
         # Determine which edge we are on
         # Left
         if start[0] == self.left:
             end = (self.right, start[1] + y_disp)
         # right
         elif start[0] == self.right:
             end = (self.left, start[1] + y_disp)
         
         if end[1] < self.bottom:
             # Recalc line to terminate at bottom
             path.push('L', *end)
         
         start = end
     svg_file.add(path)
Пример #3
0
def plot(*auts, filename='plot.svg', diagonal=True, endpoints=False, display_scale=1):
	assert len({aut.signature for aut in auts}) == 1
	from svgwrite.path      import Path
	from svgwrite.shapes    import Line, Polyline
	from svgwrite.container import Group
	dwg, canvas = new_drawing(filename, display_scale)
	include_markers(dwg, endpoints)
	draw_grid(canvas, auts[0].signature)
	
	x_axis = Polyline([(0, 0), (SCALE, 0)], class_="axis")
	y_axis = Polyline([(0, 0), (0, SCALE)], class_="axis")
	canvas.add(x_axis)
	canvas.add(y_axis)
	
	if diagonal:
		diag = Line((0,0), (SCALE, SCALE), class_="grid depth0")
		canvas.add(diag)
	
	for i, aut in enumerate(auts):
		group = Group(class_="graph", id='graph_' + str(i))
		canvas.add(group)
		last = (None, None)
		for (x0, y0, x1, y1) in graph_segments(aut):
			if last != (x0, y0):
				graph = Path(class_='graph_segment')
				group.add(graph)
				graph.push('M', SCALE * x0, SCALE * y0)
			graph.push('L', SCALE * x1, SCALE * y1)
			last = (x1, y1)
		
	dwg.save()
Пример #4
0
 def draw(self, svg_file, max_lines=12):
     
     if self.intensity < self.filter_ratio:
         return
     
     count = int((max_lines * self.intensity) + 0.5)
     path = None
     for _ in range(count):
         start_side = random.choice((self.left, self.top))
         
         offset = random.random() * self.block_size
         if start_side == self.left:
             x1 = self.left
             x2 = self.right
             y1 = self.top + offset
             y2 = self.bottom - offset
         else:
             x1 = self.left + offset
             x2 = self.right - offset
             y1 = self.top
             y2 = self.bottom
         
         if path is None:
             path = Path(("M", x1, y1), stroke="black", stroke_width="0.3", fill="none")
         else:
             path.push("M", x1, y1)
         path.push("L", x2, y2)
         
     svg_file.add(path)
Пример #5
0
 def test_push_arc_2(self):
     p = Path('m0,0')
     p.push_arc(target=(7, 7),
                rotation=30,
                r=(2, 4),
                large_arc=False,
                angle_dir='-',
                absolute=True)
     self.assertEqual(p.tostring(), '<path d="m0,0 A 2 4 30 0,0 7 7" />')
Пример #6
0
    def save(cls, image, filename, mosaic=False):
        # Use debug=False everywhere to turn off SVG validation,
        # which turns out to be obscenely expensive in this
        # library.
        DEBUG = False

        svg = svgwrite.Drawing(filename=filename,
                               style='background-color: black;',
                               size=(("%dpx" % (2 * image.r_outer),
                                      "%dpx" % (2 * image.r_outer))),
                               debug=DEBUG)

        group = Group(debug=DEBUG)
        group.translate(image.r_outer, image.r_outer)

        for y, row in enumerate(image.pixels):
            ring = image.rings[y]

            theta = 2 * math.pi / len(row)

            r1 = ring.center + image.r_ring / 2
            r2 = ring.center - image.r_ring / 2

            for x, c in enumerate(row):

                if mosaic:
                    path = Path(stroke='black',
                                stroke_width=1,
                                fill=cls.color_hex(c),
                                debug=DEBUG)

                    path.push(
                        (('M', 0, r2), ('L', 0, r1), ('A', r1, r1, 0, '0,0',
                                                      (r1 * sin(theta),
                                                       r1 * cos(theta))),
                         ('L', r2 * sin(theta),
                          r2 * cos(theta)), ('A', r2, r2, 0, '0,1', (0, r2))))
                else:
                    path = Path(stroke=cls.color_hex(c),
                                stroke_width=image.r_pixel,
                                fill='none',
                                debug=DEBUG)

                    path.push((('M', 0, ring.center),
                               ('A', ring.center, ring.center, 0, '0,0',
                                (ring.center * sin(theta),
                                 ring.center * cos(theta)))))

                path.rotate(180 - degrees(theta * (x + 1)), center=(0, 0))

                group.add(path)

        svg.add(group)
        svg.save()
Пример #7
0
def cubic_bezier(x1, x2, x3, x4, color='orange', under=False):
    if under:
        return Path('M {} {} C {} {} {} {} {} {}'.format(*x1, *x2, *x3, *x4),
                    stroke=color,
                    stroke_width='0.05',
                    fill='none',
                    stroke_dasharray='0.4')
    else:
        return Path('M {} {} C {} {} {} {} {} {}'.format(*x1, *x2, *x3, *x4),
                    stroke=color,
                    stroke_width='0.05',
                    fill='none')
Пример #8
0
class SVG(object):

    ''' SVG '''

    def __init__(self, id, WIDTH, HEIGHT):
        self.id = id
        self.WIDTH = WIDTH
        self.HEIGHT = HEIGHT
        x = random.randint(0, self.WIDTH)
        y = random.randint(0, self.HEIGHT)
        self.path = Path(d=('M', x, y))
        self.elements = []

    def addElement(self, newELement):
        self.elements.append(newELement)
        self.path.push(newELement)

    def getElements(self):
        return self.elements

    def getPointOfLastElement(self):
        point = []
        #print(self.elements[-1])
        point.append(self.elements[-1][-2])
        point.append(self.elements[-1][-1])
        return point

    def getPreviousPoints(self):
        points = []
        for i in range(len(self.elements)):
            points.append([self.elements[i][-2], self.elements[i][-1]])
        print("previous points: " + str(points))
        return points

    def saveToFile(self):
        OUTPUT_DIR = "output"
        #Check if folder exists, if not then it will be created.
        path = "." + os.sep + OUTPUT_DIR + os.sep
        try:
            os.makedirs(path)
        except OSError:
            if os.path.exists(path):
                # We are nearly safe
                pass
            else:
                # There was an error on creation, so make sure we know about it
                raise
        dwg = svgwrite.Drawing(path + str(self.id) + '.svg',
                               profile='tiny', size=(self.WIDTH, self.HEIGHT))
        dwg.add(self.path)
        #print(dwg.tostring())
        dwg.save()
Пример #9
0
 def draw(self, svg_file, max_waves=20):
     
     if self.intensity < self.filter_ratio:
         return
     
     waves = int(max(min(max_waves * self.intensity, max_waves*1.5), 1))
     
     peak_offset = self.block_size * 0.8
     step_width = (self.block_size / (waves * 4.0))
     
     path = Path(("M", self.left, self.mid_y), stroke="black", stroke_width="0.3", fill="none")
     for _ in range(waves):
         path.push("q", step_width, -peak_offset, 2 * step_width, 0)
         path.push("q", step_width, peak_offset, 2 * step_width, 0)
     svg_file.add(path)
Пример #10
0
    def save(cls, image, filename, mosaic=False):
        # Use debug=False everywhere to turn off SVG validation,
        # which turns out to be obscenely expensive in this
        # library.
        DEBUG = False

        svg = svgwrite.Drawing(filename=filename,
                               style='background-color: black;',
                               size=(("%dpx" % (2 * image.r_outer),
                                      "%dpx" % (2 * image.r_outer))),
                               debug=DEBUG)

        group = Group(debug=DEBUG)
        group.translate(image.r_outer, image.r_outer)

        for y, row in enumerate(image.pixels):
            ring = image.rings[y]

            theta = 2 * math.pi / len(row)

            r1 = ring.center + image.r_ring / 2
            r2 = ring.center - image.r_ring / 2

            for x, c in enumerate(row):

                if mosaic:
                    path = Path(stroke='black',
                                stroke_width=1,
                                fill=cls.color_hex(c),
                                debug=DEBUG)

                    path.push((('M', 0, r2),
                               ('L', 0, r1),
                               ('A', r1, r1, 0, '0,0',
                                (r1 * sin(theta),
                                 r1 * cos(theta))),
                               ('L', r2 * sin(theta),
                                     r2 * cos(theta)),
                               ('A', r2, r2, 0, '0,1',
                                (0, r2))))
                else:
                    path = Path(stroke=cls.color_hex(c),
                                stroke_width=image.r_pixel,
                                fill='none',
                                debug=DEBUG)

                    path.push((('M', 0, ring.center),
                               ('A', ring.center, ring.center, 0, '0,0',
                                (ring.center * sin(theta),
                                 ring.center * cos(theta)))))

                path.rotate(180 - degrees(theta * (x + 1)),
                            center=(0, 0))

                group.add(path)

        svg.add(group)
        svg.save()
Пример #11
0
    def test_constructor(self):
        p = Path(d="M 0 0", pathLength=100)
        self.assertEqual(p['pathLength'], 100)
        self.assertEqual(p.tostring(), '<path d="M 0 0" pathLength="100" />')

        # init path with command-string
        p = Path(d='M 10,7')
        self.assertEqual(p.tostring(), '<path d="M 10,7" />')

        # init path with a tuple of values
        p = Path(d=('M', 9, 9))
        self.assertEqual(p.tostring(), '<path d="M 9 9" />')
Пример #12
0
def draw_name(drawing, x, y, node):
    name = getattr(node, "name", None)
    if name is not None:
        drawing.add(
            Text(name,
                 insert=(x, y + NODE_RADIUS + SCALE),
                 text_anchor="middle"))

        if EXPERIMENTAL:
            (start, end) = calc.calc_text_path(x, y)

            text_anchor = "text-anchor: start"

            if start[0] < WIDTH / 2:
                tmp = start
                start = end
                end = tmp
                text_anchor = "text-anchor: end"

            path_string = "M {} {} L {} {}".format(start[0], start[1], end[0],
                                                   end[1])
            p = Path(d=path_string)

            tp = TextPath(path=p, text=name, style=text_anchor)

            # TextPath has to be child of Text
            text = svgwrite.text.Text("")
            text.add(tp)
            drawing.add(p)
            drawing.add(text)
Пример #13
0
def load_death_symbol(drawing):
    # DEATH SYMBOL
    death_symbol = Group()
    death_symbol.add(
        Path(id="death", d="M 10 0 L 10 40 M 0 12 L 20 12", stroke_width="5"))
    drawing.defs.add(death_symbol)
    return death_symbol
 def add_gausian_lines(self, column_pos, max_value, min_value, values):
     for gene in values:
         for category in values[gene]:
             gene_values = values[gene][category]
             if len(gene_values) > 1:
                 stddev = statistics.stdev(gene_values)
                 median = statistics.median(gene_values)
                 colour = self.colour_helper.get_category_colour(category)
                 scale_x = 1
                 scale_y = float(self.plottable_y) / (max_value - min_value)
                 gausian_curve_path = self.calculate_gausian_curve(
                     pos=column_pos[gene],
                     height=30,
                     stddev=stddev,
                     scale_x=scale_x,
                     scale_y=scale_y,
                     horizontal=False,
                     median=median,
                     max_value=max_value,
                     min_value=min_value)
                 self.plot.add(
                     Path(stroke=colour,
                          stroke_width=2,
                          stroke_linecap='round',
                          stroke_opacity=0.5,
                          fill=colour,
                          fill_opacity=0.1,
                          d=gausian_curve_path))
Пример #15
0
def make_svg_from_paths(dwg, paths_parsed):
    g_shape = dwg.g(class_="path")
    for p in paths_parsed:
        ps = Path(p.d())
        print(p.d())
        g_shape.add(ps)
    return g_shape
Пример #16
0
 def draw(self, svg_file):
     
     if self.intensity < self.filter_ratio:
         return
     
     segments = int(max(min(20 * self.intensity, 30), 1))
     
     def rand_point():
         return random.uniform(self.left, self.right), random.uniform(self.top, self.bottom)
     
     start = rand_point()
     path = Path(("M",) + start, stroke="black", stroke_width="0.3", fill="none")
     for _ in range(segments):
         path.push("T", *rand_point())
     
     svg_file.add(path)
Пример #17
0
    def materialOutline(self, lines, layer=None):
        cfg = self.cfg
        if self.svg is not None:
            self.xOffset = 0.0
            self.yOffset = cfg.dxfInput.ySize
            self.svg.add(Rect((0, 0), (cfg.dxfInput.xSize * self.pScale, \
                                       cfg.dxfInput.ySize * self.pScale), \
                              fill='rgb(255, 255, 255)'))
            path = self.materialPath
            if path is None:
                self.materialPath = Path(stroke_width=.5, stroke='red', \
                                         fill='none')
                path = self.materialPath
            for l in lines:
                (start, end) = l
                path.push('M', (self.scaleOffset(start)))
                path.push('L', (self.scaleOffset(end)))

        if self.d is not None:
            if layer is None:
                layer = self.lBorder
            for l in lines:
                (start, end) = l
                self.d.add(dxf.line(cfg.dxfInput.fix(start), \
                                    cfg.dxfInput.fix(end), layer=layer))
Пример #18
0
    def material(self, xSize, ySize):
        if self.svg is not None:
            self.offset = 0.0
            path = self.materialPath
            if path is None:
                self.materialPath = Path(stroke_width=.5, stroke='red', \
                                      fill='none')
                path = self.materialPath
            path.push('M', (self.scaleOffset((0, 0))))
            path.push('L', (self.scaleOffset((xSize, 0))))
            path.push('L', (self.scaleOffset((xSize, ySize))))
            path.push('L', (self.scaleOffset((0, ySize))))
            path.push('L', (self.scaleOffset((0, 0))))

            self.path.push('M', (self.scaleOffset((0, 0))))

            # dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), \
            # debug=True)

        cfg = self.cfg
        if self.d is not None:
            orientation = cfg.orientation
            if orientation == O_UPPER_LEFT:
                p0 = (0.0, 0.0)
                p1 = (xSize, 0.0)
                p2 = (xSize, -ySize)
                p3 = (0.0, -ySize)
            elif orientation == O_LOWER_LEFT:
                p0 = (0.0, 0.0)
                p1 = (xSize, 0.0)
                p2 = (xSize, ySize)
                p3 = (0.0, ySize)
            elif orientation == O_UPPER_RIGHT:
                p0 = (0.0, 0.0)
                p1 = (-xSize, 0.0)
                p2 = (-xSize, -ySize)
                p3 = (0.0, -ySize)
            elif orientation == O_LOWER_RIGHT:
                p0 = (0.0, 0.0)
                p1 = (-xSize, 0.0)
                p2 = (-xSize, ySize)
                p3 = (0.0, ySize)
            elif orientation == O_CENTER:
                p0 = (-xSize / 2, -ySize / 2)
                p1 = (xSize / 2, -ySize / 2)
                p2 = (xSize / 2, ySize / 2)
                p3 = (-xSize / 2, ySize / 2)
            elif orientation == O_POINT:
                dxfInput = cfg.dxfInput
                p0 = (dxfInput.xMin, dxfInput.yMin)
                p1 = (dxfInput.xMin, dxfInput.yMax)
                p2 = (dxfInput.xMax, dxfInput.yMax)
                p3 = (dxfInput.xMax, dxfInput.yMin)
            else:
                ePrint("invalid orientation")
            self.d.add(dxf.line(p0, p1, layer=self.lBorder))
            self.d.add(dxf.line(p1, p2, layer=self.lBorder))
            self.d.add(dxf.line(p2, p3, layer=self.lBorder))
            self.d.add(dxf.line(p3, p0, layer=self.lBorder))
Пример #19
0
 def __init__(self, id, WIDTH, HEIGHT):
     self.id = id
     self.WIDTH = WIDTH
     self.HEIGHT = HEIGHT
     x = random.randint(0, self.WIDTH)
     y = random.randint(0, self.HEIGHT)
     self.path = Path(d=('M', x, y))
     self.elements = []
Пример #20
0
    def _define_one_symbol(self):
        dot = Symbol(id="dot")
        dot.add(Circle(center=(0, 0), r=self.dimens.stroke_width * 0.4, fill="black", stroke="none"))
        self.dwg.defs.add(dot)

        one = Symbol(id="one", class_="bit-1", stroke_width=1, stroke="black")
        one.add(Circle(center=(0, 0), r=self.dimens.bit_radius, fill="none", stroke="none"))

        empty_face_symbol = Symbol(id="empty_face")
        light_face_symbol = Symbol(id="light_face")
        dense_face_symbol = Symbol(id="dense_face")

        points = ["{} {}".format(
            self.dimens.bit_radius * math.sin(2 * math.pi * v / self.poly.num_vertices),
            self.dimens.bit_radius * math.cos(2 * math.pi * v / self.poly.num_vertices)
        ) for v in range(0, 3)]
        data = ['M', "0 0 L", *points, 'Z']

        path = Path(data, fill="none", stroke_linejoin="bevel")
        empty_face_symbol.add(path)
        light_face_symbol.add(path)
        dense_face_symbol.add(path)

        x0 = 0
        x1 = self.dimens.bit_radius * math.sin(2 * math.pi * 2 / self.poly.num_vertices)
        y0 = self.dimens.bit_radius * math.cos(2 * math.pi * 2 / self.poly.num_vertices)
        y1 = self.poly.outer_circle_radius * self.dimens.bit_radius
        w = x1 - x0
        h = y1 - y0
        h_rect = y1

        num_dense = 200
        num_light = int(num_dense / 2)
        points = np.apply_along_axis(
            lambda p: np.array([p[0] * w, p[1] * h_rect + p[0] * y0]),
            1,
            np.clip(
                i4_sobol_generate(2, num_dense) + np.random.rand(num_dense, 2) / h,
                0, 1
            ))
        for p in points[:num_light]:
            light_face_symbol.add(Use(dot.get_iri(), (p[0], p[1])))
            dense_face_symbol.add(Use(dot.get_iri(), (p[0], p[1])))
        for p in points[num_light:]:
            dense_face_symbol.add(Use(dot.get_iri(), (p[0], p[1])))
        self.dwg.defs.add(empty_face_symbol)
        self.dwg.defs.add(light_face_symbol)
        self.dwg.defs.add(dense_face_symbol)

        f1 = Use(empty_face_symbol.get_iri())
        one.add(f1)
        f2 = Use(dense_face_symbol.get_iri())
        f2.rotate(120)
        one.add(f2)
        f3 = Use(light_face_symbol.get_iri())
        f3.rotate(240)
        one.add(f3)
        self.dwg.defs.add(one)
Пример #21
0
 def __init__(self):
     super().__init__()
     rect = Rect(insert=(0, 0), size=(5, 5), fill='#9e9e9e')
     path = Path('M 0 5 L 5 0 Z M 6 4 L 4 6 Z M -1 1 L 1 -1 Z',
                 stroke='#888', stroke_width=1)
     pattern = Pattern(id=self.__class__.__name__.lower(),
                       patternUnits='userSpaceOnUse',
                       size=(5, 5), stroke='none')
     pattern.add(rect)
     pattern.add(path)
     self.add(pattern)
Пример #22
0
    def open(self, inFile, drawDxf=True, drawSvg=True):
        if drawSvg and self.svg is None:
            svgFile = inFile + ".svg"
            try:
                self.svg = Drawing(svgFile, profile='full', fill='black')
                self.path = Path(stroke_width=.5, stroke='black', fill='none')
            except IOError:
                self.svg = None
                self.path = None
                ePrint("svg file open error %s" % (svgFile))

        if drawDxf and self.d is None:
            dxfFile = inFile + "_ngc.dxf"
            try:
                self.d = dxf.drawing(dxfFile)
                self.layerIndex = 0
                self.d.add_layer('0', color=self.color, lineweight=0)
                self.setupLayers()
            except IOError:
                self.d = None
                ePrint("dxf file open error %s" % (dxfFile))
Пример #23
0
def arc(center):
    center = center
    arc_start = 150
    arc_end = 30
    radius = center[2]
    #p= Path(d=f"M {center[0]} {center[1]}")
    p = Path(d=[])
    current_a = (-(radius * math.cos(math.pi *
                                     (arc_start / 180.0))) + center[0],
                 -(radius * math.sin(math.pi *
                                     (arc_start / 180.0))) + center[1])

    #p.push(f"M {(radius * math.cos(math.pi *arc_start/180.0 )) +center[0] } {(radius * math.sin(math.pi * arc_start/180.0)) +center[1] } ")
    #p.push(f"M 0 0 L 0 0 {center[0]} {center[1]} ")
    p.push(f"M {current_a[0]} {current_a[1]} ")
    target = (-(radius * math.cos(math.pi * (arc_end / 180.1))) + center[0],
              -(radius * math.sin(math.pi * (arc_end / 180.1))) + center[1])
    p.push_arc(target,
               rotation=0,
               r=radius,
               large_arc=False,
               angle_dir='-',
               absolute=True)
    #p.push(f" L {target[0]} {target[1]} ")

    #p.push(f"L {target[0]} {target[1]} {center[0]} {center[1]}")

    svg_entity = svgwrite.Drawing().path(d=p.commands,
                                         stroke="blue",
                                         stroke_width="1",
                                         fill="none")
    ergebnis = svg_entity._repr_svg_()
    return ergebnis
Пример #24
0
 def drawLayer(self,
               paths,
               fillColor='black',
               fillOpacity=0.5,
               strokeColor='black',
               strokeWidth=1,
               strokeOpacity=1.0):
     for path in paths:
         _polygon = self.svgFile.add(Path(path))
         _polygon.fill(fillColor, opacity=fillOpacity)
         _polygon.stroke(strokeColor,
                         width=strokeWidth,
                         opacity=strokeOpacity)
Пример #25
0
def draw_slice(center, radius, start_angle, stop_angle, **kwargs):
    p_a = Path(**kwargs)
    angle = math.radians(stop_angle - start_angle) / 2.0
    p_a.push(f"""M {center[0]} {center[1]}
                 l {cos(-1*angle)*radius} {sin(-1*angle)*radius}""")
    p_a.push_arc(
        target=(cos(angle) * radius + center[0],
                sin(angle) * radius + center[1]),
        rotation=0,
        r=radius,
        large_arc=True if stop_angle - start_angle > 180 else False,
        angle_dir="+",
        absolute=True,
    )
    p_a.push("Z")

    p_a.rotate(
        angle=(min([start_angle, stop_angle]) +
               (stop_angle - start_angle) / 2.0),
        center=center,
    )

    return p_a
Пример #26
0
 def draw_line(scene: Drawing, start: tuple, ctrl1: tuple, ctrl2: tuple,
               end: tuple, is_curved: bool, edge_color: tuple):
     if is_curved:  # cubic Bezier curve
         scene.add(
             Path(d=['M', start, 'C', ctrl1, ctrl2, end],
                  stroke=rgb(*edge_color),
                  stroke_width=1,
                  fill='none'))
     else:
         scene.add(
             Line(start,
                  end,
                  shape_rendering='inherit',
                  stroke=rgb(*edge_color),
                  stroke_width=1))
Пример #27
0
    def draw(self):
        lenghts = self.config['timingdiagram']['lengths']
        styles = self.config['timingdiagram']

        seq = self.states
        grp = Group()

        lastframe = len(
            seq) * lenghts.FRAME_LENGTH + 2 * lenghts.BEGIN_MARGIN_FRAME

        Y_AXES_TOP = (lenghts.Y_AXE_STARTX, lenghts.Y_AXE_TOP_MARGIN)
        Y_AXES_BOT = (lenghts.Y_AXE_STARTX,
                      lenghts.Y_AXE_TOP_MARGIN + lenghts.Y_AXE_HEIGHT)
        Y_AXES_END = (lenghts.Y_AXE_STARTX + lastframe,
                      lenghts.Y_AXE_TOP_MARGIN + lenghts.Y_AXE_HEIGHT)

        grp.add(Line(Y_AXES_TOP, Y_AXES_BOT, **styles.axes.d))
        grp.add(Line(Y_AXES_BOT, Y_AXES_END, **styles.axes.d))

        grp.add(
            Line((lenghts.Y_AXE_STARTX - 2, lenghts.TOP_VALUE_LINE),
                 (lenghts.Y_AXE_STARTX + lastframe, lenghts.TOP_VALUE_LINE),
                 **styles.top_line.d))
        grp.add(
            Line((lenghts.Y_AXE_STARTX - 2, lenghts.BOT_VALUE_LINE),
                 (lenghts.Y_AXE_STARTX + lastframe, lenghts.BOT_VALUE_LINE),
                 **styles.bottom_line.d))

        grp.add(
            Text("true", (lenghts.WIDTH_VARIABLE_NAME, lenghts.TOP_VALUE_LINE),
                 **styles.valuename.d))
        grp.add(
            Text("false",
                 (lenghts.WIDTH_VARIABLE_NAME, lenghts.BOT_VALUE_LINE),
                 **styles.valuename.d))
        grp.add(
            Text(
                self.name,
                (lenghts.WIDTH_VARIABLE_NAME - 10, lenghts.BOT_VALUE_LINE - 5),
                **styles.varname.d))

        grp.add(Path(self._build_curve(), **styles.curve.d))

        return grp
Пример #28
0
    def get_svg(self, unit=mm):
        '''
        Generate an SVG Drawing based of the generated gear profile.
        :param unit: None or a unit within the 'svgwrite' module, such as svgwrite.mm, svgwrite.cm
        :return: An svgwrite.Drawing object populated only with the gear path.
        '''

        points = self.get_point_list()
        width, height = np.ptp(points, axis=0)
        left, top = np.min(points, axis=0)
        size = (width * unit, height * unit) if unit is not None else (width,
                                                                       height)
        dwg = Drawing(size=size,
                      viewBox='{} {} {} {}'.format(left, top, width, height))
        p = Path('M')
        p.push(points)
        p.push('Z')
        dwg.add(p)
        return dwg
Пример #29
0
def trans_arc(dxf_entity):
    radius= dxf_entity.dxf.radius
    #stroke = dxf_entity.dxf.color
    center = slice_l2(dxf_entity.dxf.center)
    arc_start = dxf_entity.dxf.start_angle
    arc_end = dxf_entity.dxf.end_angle
    p=Path(d=[])
    radius = dxf_entity.dxf.radius
    current_a = (-(radius * math.cos(math.pi * (arc_start/180.0 ))) +center[0], -(radius * math.sin(math.pi * (arc_start/180.0))) +center[1])
    #p.push(f"M {current_a[0]} {current_a[1]} L {center[0]} {center[1]}  {current_a[0]} {current_a[1]} ")
    p.push(f"M {current_a[0]} {current_a[1]}  ")
    target=( -(radius * math.cos(math.pi * (arc_end/180.1) )) +center[0], -(radius * math.sin(math.pi * (arc_end/180.1)))+center[1] )
    p.push_arc(target, rotation=0, r=radius, large_arc=False , angle_dir='-', absolute=True)
    #p.push(f" L {target[0]} {target[1]} ")
    #p.push(f"L {target[0]} {target[1]} {center[0]} {center[1]}") 
    #print(f"trans_arc: dxf_entity.dxf.start_angle= {dxf_entity.dxf.start_angle} dxf_entity.dxf.end_angle={dxf_entity.dxf.end_angle} circle_center={circle_center},dxf_entity.dxf.center= {dxf_entity.dxf.center}")
    #print(f"trans_arc: dxf_entity.dxf.radius= {dxf_entity.dxf.radius}")
    #svg_entity = svgwrite.Drawing().circle(center=circle_center, r=0, stroke =stroke , fill="none", stroke_width = thickness)# !!!
    #svg_entity = svgwrite.Drawing().arc(center=circle_center, r=circle_radius, stroke =stroke , fill="none", stroke_width = thickness)
    svg_entity = svgwrite.Drawing().path(d=p.commands,stroke=stroke, stroke_width=thickness ,fill="none") # ->src/python/svgwrite/svgwrite/path.py
    print(f"p.commands= {svg_entity._repr_svg_()}")
    #svg_entity = svgwrite.Drawing().arc(center=circle_center, r=circle_radius, stroke =stroke , fill="none", stroke_width = thickness)
    svg_entity.scale(SCALE,-SCALE)
    return svg_entity
Пример #30
0
    def render(self,
               canvas,
               level,
               x=0,
               y=0,
               origin=None,
               height=None,
               side=1,
               init=True,
               level_index=0):
        """
		Render node set to canvas

		:param canvas:  SVG object
		:param list level:  List of nodes to render
		:param int x:  X coordinate of top left of level block
		:param int y:  Y coordinate of top left of level block
		:param tuple origin:  Coordinates to draw 'connecting' line to
		:param float height:  Block height budget
		:param int side:  What direction to move into: 1 for rightwards, -1 for leftwards
		:param bool init:  Whether the draw the top level of nodes. Only has an effect if
						   side == self.SIDE_LEFT
		:return:  Updated canvas
		"""
        if not level:
            return canvas

        # this eliminates a small misalignment where the left side of the
        # graph starts slightly too far to the left
        if init and side == self.SIDE_LEFT:
            x += self.step

        # determine how many nodes we'll need to fit on top of each other
        # within this block
        required_space_level = sum([self.max_breadth(node) for node in level])

        # draw each node and the tree below it
        for node in level:
            # determine how high this block will be based on the available
            # height and the nodes we'll need to fit in it
            required_space_node = self.max_breadth(node)

            block_height = (required_space_node /
                            required_space_level) * height

            # determine how much we want to enlarge the text
            occurrence_ratio = node.occurrences / self.max_occurrences[
                level_index]
            if occurrence_ratio >= 0.75:
                embiggen = 3
            elif occurrence_ratio > 0.5:
                embiggen = 2
            elif occurrence_ratio > 0.25:
                embiggen = 1.75
            elif occurrence_ratio > 0.15:
                embiggen = 1.5
            else:
                embiggen = 1

            # determine how large the text block will be (this is why we use a
            # monospace font)
            characters = len(node.name)
            text_width = characters * self.step
            text_width *= (embiggen * 1)

            text_offset_y = self.fontsize if self.align == "top" else (
                (block_height) / 2)

            # determine where in the block to draw the text and where on the
            # canvas the block appears
            block_position = (x, y)
            block_offset_x = -(text_width +
                               self.step) if side == self.SIDE_LEFT else 0

            self.x_min = min(self.x_min, block_position[0] + block_offset_x)
            self.x_max = max(self.x_max,
                             block_position[0] + block_offset_x + text_width)

            # the first node on the left side of the graph does not need to be
            # drawn if the right side is also being drawn because in that case
            # it's already going to be included through that part of the graph
            if not (init and side == self.SIDE_LEFT):
                container = SVG(x=block_position[0] + block_offset_x,
                                y=block_position[1],
                                width=text_width,
                                height=block_height,
                                overflow="visible")
                container.add(
                    Text(text=node.name,
                         insert=(0, text_offset_y),
                         alignment_baseline="middle",
                         style="font-size:" + str(embiggen) + "em"))
                canvas.add(container)
            else:
                # adjust position to make left side connect to right side
                x += text_width
                block_position = (block_position[0] + text_width,
                                  block_position[1])

            # draw the line connecting this node to the parent node
            if origin:
                destination = (x - self.step, y + text_offset_y)

                # for the left side of the graph, draw a curve leftwards
                # instead of rightwards
                if side == self.SIDE_RIGHT:
                    bezier_origin = origin
                    bezier_destination = destination
                else:
                    bezier_origin = (destination[0] + self.step,
                                     destination[1])
                    bezier_destination = (origin[0] - self.step, origin[1])

                # bezier curve control points
                control_x = bezier_destination[0] - (
                    (bezier_destination[0] - bezier_origin[0]) / 2)
                control_left = (control_x, bezier_origin[1])
                control_right = (control_x, bezier_destination[1])

                # draw curve
                flow = Path(stroke="#000", fill_opacity=0, stroke_width=1.5)
                flow.push("M %f %f" % bezier_origin)
                flow.push("C %f %f %f %f %f %f" % tuple(
                    [*control_left, *control_right, *bezier_destination]))
                canvas.add(flow)

            # bezier curves for the next set of nodes will start at these
            # coordinates
            new_origin = (block_position[0] +
                          ((text_width + self.step) * side),
                          block_position[1] + text_offset_y)

            # draw this node's children
            canvas = self.render(canvas,
                                 node.children,
                                 x=x + ((text_width + self.gap) * side),
                                 y=y,
                                 origin=new_origin,
                                 height=int(block_height),
                                 side=side,
                                 init=False,
                                 level_index=level_index + 1)
            y += block_height

        return canvas
Пример #31
0
def nest(output, files, wbin, hbin, enclosing_rectangle=False):

    packer = newPacker()

    def float2dec(x):
        return _float2dec(x, 4)

    def bbox_paths(paths):
        bbox = None
        for p in paths:
            p_bbox = p.bbox()
            if bbox is None:
                bbox = p_bbox
            else:
                bbox = (min(p_bbox[0], bbox[0]), max(p_bbox[1], bbox[1]),
                        min(p_bbox[2], bbox[2]), max(p_bbox[3], bbox[3]))
        return tuple(float2dec(x) for x in bbox)

    all_paths = {}
    for svg\
            in files:
        paths, attributes = svg2paths(svg)
        bbox = bbox_paths(paths)
        for i in range(files[svg]):
            rid = svg + str(i)
            all_paths[rid] = {'paths': paths, 'bbox': bbox}
            print(rid)
            packer.add_rect(bbox[1] - bbox[0], bbox[3] - bbox[2], rid=rid)

    print('Rectangle packing...')
    while True:
        packer.add_bin(wbin, hbin)
        packer.pack()
        rectangles = {r[5]: r for r in packer.rect_list()}
        if len(rectangles) == len(all_paths):
            break
        else:
            print('not enough space in the bin, adding ')

    combineds = {}

    print('packing into SVGs...')
    for rid, obj in all_paths.items():
        paths = obj['paths']
        bbox = obj['bbox']
        group = Group()

        width, height = (float2dec(bbox[1] - bbox[0]),
                         float2dec(bbox[3] - bbox[2]))
        bin, x, y, w, h, _ = rectangles[rid]
        if bin not in combineds:
            svg_file = output
            if bin != 0:
                splitext = os.path.splitext(svg_file)
                svg_file = splitext[0] + '.%s' % bin + splitext[1]
            dwg = Drawing(svg_file,
                          profile='tiny',
                          size=('%smm' % wbin, '%smm' % hbin),
                          viewBox="0 0 %s %s" % (wbin, hbin))
            combineds[bin] = dwg

        combined = combineds[bin]

        if (width > height and w > h) or \
                (width < height and w < h) or \
                (width == height and w == h):
            rotate = 0
            dx = -bbox[0]
            dy = -bbox[2]
        else:
            rotate = 90
            dx = -bbox[2]
            dy = -bbox[0]

        for p in paths:
            path = Path(d=p.d())
            path.stroke(color='red', width='1')
            path.fill(opacity=0)
            group.add(path)

        group.translate(x + dx, y + dy)
        group.rotate(rotate)
        combined.add(group)

    for combined in combineds.values():
        if enclosing_rectangle:
            r = Rect(size=(wbin, hbin))
            r.fill(opacity=0)
            r.stroke(color='lightgray')
            combined.add(r)

        print('SVG saving...')
        combined.save(pretty=True)
Пример #32
0
    def process(self):
        graphs = {}
        intervals = []

        smooth = self.parameters.get("smooth")
        normalise_values = self.parameters.get("normalise")
        completeness = convert_to_int(self.parameters.get("complete"), 0)
        graph_label = self.parameters.get("label")
        top = convert_to_int(self.parameters.get("top"), 10)

        # first gather graph data: each distinct item gets its own graph and
        # for each graph we have a sequence of intervals, each interval with
        # its own value
        first_date = "9999-99-99"
        last_date = "0000-00-00"

        for row in self.iterate_items(self.source_file):
            if row["item"] not in graphs:
                graphs[row["item"]] = {}

            # make sure the months and days are zero-padded
            interval = row.get("date", "")
            interval = "-".join([
                str(bit).zfill(2 if len(bit) != 4 else 4)
                for bit in interval.split("-")
            ])
            first_date = min(first_date, interval)
            last_date = max(last_date, interval)

            if interval not in intervals:
                intervals.append(interval)

            if interval not in graphs[row["item"]]:
                graphs[row["item"]][interval] = 0

            graphs[row["item"]][interval] += float(row.get("value", 0))

        # first make sure we actually have something to render
        intervals = sorted(intervals)
        if len(intervals) <= 1:
            self.dataset.update_status(
                "Not enough data for a side-by-side over-time visualisation.")
            self.dataset.finish(0)
            return

        # only retain most-occurring series - sort by sum of all frequencies
        if len(graphs) > top:
            selected_graphs = {
                graph: graphs[graph]
                for graph in sorted(
                    graphs,
                    key=lambda x: sum(
                        [graphs[x][interval] for interval in graphs[x]]),
                    reverse=True)[0:top]
            }
            graphs = selected_graphs

        # there may be items that do not have values for all intervals
        # this will distort the graph, so the next step is to make sure all
        # graphs consist of the same continuous interval list
        missing = {graph: 0 for graph in graphs}
        for graph in graphs:
            missing[graph], graphs[graph] = pad_interval(
                graphs[graph],
                first_interval=first_date,
                last_interval=last_date)

        # now that's done, make sure the graph datapoints are in order
        intervals = sorted(list(graphs[list(graphs)[0]].keys()))

        # delete graphs that do not have the required amount of intervals
        # this is useful to get rid of outliers and items that only occur
        # very few times over the full interval
        if completeness > 0:
            intervals_required = len(intervals) * (completeness / 100)
            disqualified = []
            for graph in graphs:
                if len(intervals) - missing[graph] < intervals_required:
                    disqualified.append(graph)

            graphs = {
                graph: graphs[graph]
                for graph in graphs if graph not in disqualified
            }

        # determine max value per item, so we can normalize them later
        limits = {}
        max_limit = 0
        for graph in graphs:
            for interval in graphs[graph]:
                limits[graph] = max(limits.get(graph, 0),
                                    abs(graphs[graph][interval]))
                max_limit = max(max_limit, abs(graphs[graph][interval]))

        # order graphs by highest (or lowest) value)
        limits = {
            limit: limits[limit]
            for limit in sorted(limits, key=lambda l: limits[l])
        }
        graphs = {graph: graphs[graph] for graph in limits}

        if not graphs:
            # maybe nothing is actually there to be graphed
            self.dataset.update_status(
                "No items match the selection criteria - nothing to visualise."
            )
            self.dataset.finish(0)
            return None

        # how many vertical grid lines (and labels) are to be included at most
        # 12 is a sensible default because it allows one label per month for a full
        # year's data
        max_gridlines = 12

        # If True, label is put at the lower left bottom of the graph rather than
        # outside it. Automatically set to True if one of the labels is long, as
        # else the label would fall off the screen
        label_in_graph = max([len(item) for item in graphs]) > 30

        # determine how wide each interval should be
        # the graph has a minimum width - but the graph's width will be
        # extended if at this minimum width each item does not have the
        # minimum per-item width
        min_full_width = 600
        min_item_width = 50
        item_width = max(min_item_width, min_full_width / len(intervals))

        # determine how much space each graph should get
        # same trade-off as for the interval width
        min_full_height = 300
        min_item_height = 100
        item_height = max(min_item_height, min_full_height / len(graphs))

        # margin - this should be enough for the text labels to fit in
        margin_base = 50
        margin_right = margin_base * 4
        margin_top = margin_base * 3

        # this determines the "flatness" of the isometric projection and an be
        # tweaked for different looks - basically corresponds to how far the
        # camera is above the horizon
        plane_angle = 120

        # don't change these
        plane_obverse = radians((180 - plane_angle) / 2)
        plane_angle = radians(plane_angle)

        # okay, now determine the full graphic size with these dimensions projected
        # semi-isometrically. We can also use these values later for drawing for
        # drawing grid lines, et cetera. The axis widths and heights here are the
        # dimensions of the bounding box wrapping the isometrically projected axes.
        x_axis_length = (item_width * (len(intervals) - 1))
        y_axis_length = (item_height * len(graphs))

        x_axis_width = (sin(plane_angle / 2) * x_axis_length)
        y_axis_width = (sin(plane_angle / 2) * y_axis_length)
        canvas_width = x_axis_width + y_axis_width

        # leave room for graph header
        if graph_label:
            margin_top += (2 * (canvas_width / 50))

        x_axis_height = (cos(plane_angle / 2) * x_axis_length)
        y_axis_height = (cos(plane_angle / 2) * y_axis_length)
        canvas_height = x_axis_height + y_axis_height

        # now we have the dimensions, the canvas can be instantiated
        canvas = get_4cat_canvas(
            self.dataset.get_results_path(),
            width=(canvas_width + margin_base + margin_right),
            height=(canvas_height + margin_base + margin_top),
            header=graph_label)

        # draw gridlines - vertical
        gridline_x = y_axis_width + margin_base
        gridline_y = margin_top + canvas_height

        step_x_horizontal = sin(plane_angle / 2) * item_width
        step_y_horizontal = cos(plane_angle / 2) * item_width
        step_x_vertical = sin(plane_angle / 2) * item_height
        step_y_vertical = cos(plane_angle / 2) * item_height

        # labels for x axis
        # month and week both follow the same pattern
        # it's not always possible to distinguish between them but we will try
        # by looking for months greater than 12 in which case we are dealing
        # with weeks
        # we need to know this because for months there is an extra row in the
        # label with the full month
        is_week = False
        for i in range(0, len(intervals)):
            if re.match(r"^[0-9]{4}-[0-9]{2}",
                        intervals[i]) and int(intervals[i].split("-")[1]) > 12:
                is_week = True
                break

        skip = max(1, int(len(intervals) / max_gridlines))
        for i in range(0, len(intervals)):
            if i % skip == 0:
                canvas.add(
                    Line(start=(gridline_x, gridline_y),
                         end=(gridline_x - y_axis_width,
                              gridline_y - y_axis_height),
                         stroke="grey",
                         stroke_width=0.25))

                # to properly position the rotated and skewed text a container
                # element is needed
                label1 = str(intervals[i])[0:4]
                center = (gridline_x, gridline_y)
                container = SVG(x=center[0] - 25,
                                y=center[1],
                                width="50",
                                height="1.5em",
                                overflow="visible",
                                style="font-size:0.8em;")
                container.add(
                    Text(insert=("25%", "100%"),
                         text=label1,
                         transform="rotate(%f) skewX(%f)" %
                         (-degrees(plane_obverse), degrees(plane_obverse)),
                         text_anchor="middle",
                         baseline_shift="-0.5em",
                         style="font-weight:bold;"))

                if re.match(r"^[0-9]{4}-[0-9]{2}",
                            intervals[i]) and not is_week:
                    label2 = month_abbr[int(str(intervals[i])[5:7])]
                    if re.match(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}", intervals[i]):
                        label2 += " %i" % int(intervals[i][8:10])

                    container.add(
                        Text(insert=("25%", "150%"),
                             text=label2,
                             transform="rotate(%f) skewX(%f)" %
                             (-degrees(plane_obverse), degrees(plane_obverse)),
                             text_anchor="middle",
                             baseline_shift="-0.5em"))

                canvas.add(container)

            gridline_x += step_x_horizontal
            gridline_y -= step_y_horizontal

        # draw graphs as filled beziers
        top = step_y_vertical * 1.5
        graph_start_x = y_axis_width + margin_base
        graph_start_y = margin_top + canvas_height

        # draw graphs in reverse order, so the bottom one is most in the
        # foreground (in case of overlap)
        for graph in reversed(list(graphs)):
            self.dataset.update_status("Rendering graph for '%s'" % graph)

            # path starting at lower left corner of graph
            area_graph = Path(fill=self.colours[self.colour_index])
            area_graph.push("M %f %f" % (graph_start_x, graph_start_y))
            previous_value = None

            graph_x = graph_start_x
            graph_y = graph_start_y
            for interval in graphs[graph]:
                # normalise value
                value = graphs[graph][interval]
                try:
                    limit = limits[graph] if normalise_values else max_limit
                    value = top * copysign(abs(value) / limit, value)
                except ZeroDivisionError:
                    value = 0

                if previous_value is None:
                    # vertical line upwards to starting value of graph
                    area_graph.push("L %f %f" %
                                    (graph_start_x, graph_start_y - value))
                elif not smooth:
                    area_graph.push("L %f %f" % (graph_x, graph_y - value))
                else:
                    # quadratic bezier from previous value to current value
                    control_left = (graph_x - (step_x_horizontal / 2),
                                    graph_y + step_y_horizontal -
                                    previous_value - (step_y_horizontal / 2))
                    control_right = (graph_x - (step_x_horizontal / 2),
                                     graph_y - value + (step_y_horizontal / 2))
                    area_graph.push("C %f %f %f %f %f %f" %
                                    (*control_left, *control_right, graph_x,
                                     graph_y - value))

                previous_value = value
                graph_x += step_x_horizontal
                graph_y -= step_y_horizontal

            # line to the bottom of the graph at the current Y position
            area_graph.push(
                "L %f %f" %
                (graph_x - step_x_horizontal, graph_y + step_y_horizontal))
            area_graph.push("Z")  # then close the Path
            canvas.add(area_graph)

            # add text labels - skewing is a bit complicated and we need a
            # "center" to translate the origins properly.
            if label_in_graph:
                insert = (graph_start_x + 5, graph_start_y - 10)
            else:
                insert = (graph_x - (step_x_horizontal) + 5,
                          graph_y + step_y_horizontal - 10)

            # we need to take the skewing into account for the translation
            offset_y = tan(plane_obverse) * insert[0]
            canvas.add(
                Text(insert=(0, 0),
                     text=graph,
                     transform="skewY(%f) translate(%f %f)" %
                     (-degrees(plane_obverse), insert[0],
                      insert[1] + offset_y)))

            # cycle colours, back to the beginning if all have been used
            self.colour_index += 1
            if self.colour_index >= len(self.colours):
                self.colour_index = 0

            graph_start_x -= step_x_vertical
            graph_start_y -= step_y_vertical

        # draw gridlines - horizontal
        gridline_x = margin_base
        gridline_y = margin_top + canvas_height - y_axis_height
        for graph in graphs:
            gridline_x += step_x_vertical
            gridline_y += step_y_vertical
            canvas.add(
                Line(start=(gridline_x, gridline_y),
                     end=(gridline_x + x_axis_width,
                          gridline_y - x_axis_height),
                     stroke="black",
                     stroke_width=1))

        # x axis
        canvas.add(
            Line(start=(margin_base + y_axis_width,
                        margin_top + canvas_height),
                 end=(margin_base + canvas_width,
                      margin_top + canvas_height - x_axis_height),
                 stroke="black",
                 stroke_width=2))

        # and finally save the SVG
        canvas.save(pretty=True)
        self.dataset.finish(len(graphs))
Пример #33
0
 def test_push_arc_2(self):
     p = Path('m0,0')
     p.push_arc(target=(7,7), rotation=30, r=(2,4), large_arc=False, angle_dir='-', absolute=True)
     self.assertEqual(p.tostring(), '<path d="m0,0 A 2 4 30 0,0 7 7" />')
Пример #34
0
 def test_push_arc_1(self):
     p = Path('m0,0')
     p.push_arc(target=(7,7), rotation=30, r=5)
     self.assertEqual(p.tostring(), '<path d="m0,0 a 5 5 30 1,1 7 7" />')
Пример #35
0
 def test_nested_commands(self):
     p = Path(d=('M 1,2', ['L', (7, 7, 'H 1 2 3 4 5')]))
     self.assertEqual(p.tostring(), '<path d="M 1,2 L 7 7 H 1 2 3 4 5" />')
Пример #36
0
    def test_flat_commands(self):
        p = Path(d="M 0 0")
        self.assertEqual(p.tostring(), '<path d="M 0 0" />')
        # push separated commands and values
        p.push(100, 100, 100, 200)
        self.assertEqual(p.tostring(), '<path d="M 0 0 100 100 100 200" />')

        # push commands strings
        p = Path()
        p.push('M 100 100 100 200')
        self.assertEqual(p.tostring(), '<path d="M 100 100 100 200" />')


        p = Path(d=('M 10', 7))
        p.push('l', 100., 100.)
        p.push('v 100.7 200.1')
        self.assertEqual(p.tostring(), '<path d="M 10 7 l 100.0 100.0 v 100.7 200.1" />')
Пример #37
0
 def draw(self, svg_file, max_lines=12):
     
     if self.intensity < self.filter_ratio:
         return
     
     path = Path(("M", self.left, self.top), stroke="black", stroke_width="0.3", fill="none")
     count = int((max_lines * self.intensity))
     
     left_third = self.left + (self.block_size / 4.0)
     right_third = self.left + (3 * (self.block_size / 4.0))
     top_third = self.top + (self.block_size / 4.0)
     bottom_third = self.top + (3 * (self.block_size / 4.0))
     
     for m in range(count):
         if m == 0:
             path.push("L", self.right, self.bottom)
             path.push("M", self.right, self.top)
         elif m == 1:
             path.push("L", self.left, self.bottom)
             path.push("M", self.mid_x, self.top)
         elif m == 2:
             path.push("L", self.mid_x, self.bottom)
             path.push("M", self.left, self.mid_y)
         elif m == 3:
             path.push("L", self.right, self.mid_y)
             path.push("M", left_third, self.top)
         elif m == 4:
             path.push("L", left_third, self.bottom)
             path.push("M", right_third, self.top)
         elif m == 5:
             path.push("L", right_third, self.bottom)
             path.push("M", self.left, top_third)
         elif m == 6:
             path.push("L", self.right, top_third)
             path.push("M", self.left, bottom_third)
         elif m == 7:
             path.push("L", self.right, bottom_third)
             path.push("M", left_third, self.top)
         elif m == 8:
             path.push("L", self.right, bottom_third)
             path.push("M", right_third, self.top)
         elif m == 9:
             path.push("L", self.left, bottom_third)
             path.push("M", left_third, self.bottom)
         elif m == 10:
             path.push("L", self.right, top_third)
             path.push("M", right_third, self.bottom)
         elif m == 11:
             path.push("L", self.left, top_third)
     
     
     svg_file.add(path)
Пример #38
0
def semicircle(s, r, direction, color='orange'):
    return Path('M {} {} A {} {} 0 1 {} {} {}'.format(*s, r, r, direction,
                                                      s[0], s[1] - 2 * r),
                stroke=color,
                stroke_width='0.05',
                fill='none')
Пример #39
0
 def get_path(self, points, translate_x, style={}):
     parts = [
         'M {}{}'.format(round(start_x + translate_x, 7), rest)
         for start_x, rest in points
     ]
     return Path(d=' '.join(parts), **style)
Пример #40
0
 def get_svg(self, **kwargs):
     path = Path([str(self)], **kwargs)
     return path