예제 #1
0
 def test_equals(self):
     """Segments should be equalitive"""
     self.assertEqual(Move(10, 10), Move(10, 10))
     self.assertEqual(Line(10, 10), Line(10, 10))
     self.assertEqual(line(10, 10), line(10, 10))
     self.assertNotEqual(line(10, 10), Line(10, 10))
     self.assertEqual(Horz(10), Line(10, 0))
     self.assertEqual(Vert(10), Line(0, 10))
     self.assertNotEqual(Vert(10), Horz(10))
예제 #2
0
    def test_to_curves(self):
        """Segments can become curves"""
        self.assertRaises(ValueError, Move(0, 0).to_curve, None)
        self.assertEqual(
            Line(10, 10).to_curve(Vector2d(10, 5)), (10, 5, 10, 10, 10, 10))
        self.assertEqual(
            Horz(10).to_curve(Vector2d(10, 5)), (10, 5, 10, 5, 10, 5))
        self.assertEqual(
            Vert(10).to_curve(Vector2d(5, 10)), (5, 10, 5, 10, 5, 10))
        self.assertEqual(
            Curve(5, 5, 10, 10, 4, 4).to_curve(Vector2d(0, 0)),
            (5, 5, 10, 10, 4, 4))

        self.assertEqual(
            Smooth(10, 10, 4, 4).to_curve(Vector2d(4, 4), Vector2d(10, 10)),
            (-2, -2, 10, 10, 4, 4),
        )

        self.assertAlmostTuple(
            Quadratic(10, 10, 4, 4).to_curve(Vector2d(0, 0)).args,
            (6.666666666666666, 6.666666666666666, 8, 8, 4, 4),
        )

        self.assertAlmostTuple(
            TepidQuadratic(4, 4).to_curve(Vector2d(14, 19), Vector2d(11,
                                                                     12)).args,
            #            (20.666666666666664, 30, 17.333333333333332, 25, 4, 4),
            (15.999999999999998, 23.666666666666664, 12.666666666666666,
             18.666666666666664, 4, 4),
        )

        curves = list(Arc(50, 50, 0, 0, 1, 85, 85).to_curves(Vector2d(0, 0)))
        self.assertEqual(len(curves), 3)
        self.assertAlmostTuple(
            curves[0].args,
            (19.77590700610636, -5.4865851247611115, 38.18634924829132,
             -10.4196482558544, 55.44095225512604, -5.796291314453416))
        self.assertAlmostTuple(
            curves[1].args,
            (72.69555526196076, -1.172934373052433, 86.17293437305243,
             12.30444473803924, 90.79629131445341, 29.559047744873958))
        self.assertAlmostTuple(
            curves[2].args,
            (95.41964825585441, 46.81365075170867, 90.4865851247611,
             65.22409299389365, 77.85533905932738, 77.85533905932738))

        def apply_to_curve(obj):
            obj.to_curve(Vector2d())

        def apply_to_curves(obj):
            obj.to_curve(Vector2d())

        self.assertRaises(ValueError, apply_to_curve, ZoneClose())
        self.assertRaises(ValueError, apply_to_curves, zoneClose())

        self.assertRaises(ValueError, apply_to_curve, Move(0, 0))
        self.assertRaises(ValueError, apply_to_curves, move(0, 0))
예제 #3
0
def draw_line(x1, y1, x2, y2, width, name, parent):
    elem = parent.add(inkex.PathElement())
    elem.style = {
        'stroke': '#000000',
        'stroke-width': str(width),
        'fill': 'none'
    }
    elem.set('inkscape:label', name)
    elem.path = [Move(x1, y1), Line(x2, y2)]
예제 #4
0
    def effect(self):
        for node in self.svg.selection.filter(inkex.PathElement):
            path = node.path.to_absolute()
            result = []
            for cmd_proxy in path.proxy_iterator(
            ):  # type: inkex.Path.PathCommandProxy
                prev = cmd_proxy.previous_end_point
                end = cmd_proxy.end_point
                if cmd_proxy.letter == 'M':
                    result.append(Move(*cmd_proxy.args))
                else:
                    for seg in self.fractalize((prev.x, prev.y, end.x, end.y),
                                               self.options.subdivs,
                                               self.options.smooth):
                        result.append(Line(*seg))
                    result.append(Line(end.x, end.y))

            node.path = result
예제 #5
0
 def plot_beam(beam: List[Tuple[Ray, float]],
               node: inkex.ShapeElement) -> None:
     path = inkex.Path()
     if len(beam) > 0:
         path += [Move(beam[0][0].origin[0], beam[0][0].origin[1])]
         for ray, t in beam:
             p1 = ray.origin + t * ray.direction
             path += [Line(p1[0], p1[1])]
     element = node.getparent().add(inkex.PathElement())
     element.style = node.get("style")
     element.path = path.transform(-node.composed_transform())
 def plot_beam(self, beam: List[Ray], node: inkex.ShapeElement) -> None:
     path = inkex.Path()
     if len(beam) > 0:
         path += [Move(beam[0].origin[0], beam[0].origin[1])]
         for ray in beam:
             p1 = ray.origin + ray.travel * ray.direction
             path += [Line(p1[0], p1[1])]
     element = self._beam_layer.add(inkex.PathElement())
     # Need to convert to path to get the correct style for inkex.Use
     element.style = node.to_path_element().style
     element.path = path
예제 #7
0
 def plot_beam(self, beam: List[Tuple[Ray, float]],
               node: inkex.ShapeElement) -> None:
     path = inkex.Path()
     if len(beam) > 0:
         path += [Move(beam[0][0].origin[0], beam[0][0].origin[1])]
         for ray, t in beam:
             p1 = ray.origin + t * ray.direction
             path += [Line(p1[0], p1[1])]
     svg = self.document.getroot()
     element = svg.add(inkex.PathElement())
     element.style = node.get("style")
     element.path = path
예제 #8
0
    def effect(self):
        for node in self.svg.selection.filter(inkex.PathElement):
            result = Path()
            prev = Vector2d()
            start = None
            for seg in node.path.to_absolute():
                if start is None:
                    start = seg.end_point(start, prev)
                if isinstance(seg, Curve):
                    result += [
                        Move(seg.x2, seg.y2),
                        Line(prev.x, prev.y),
                        Move(seg.x3, seg.y3),
                        Line(seg.x4, seg.y4),
                    ]
                elif isinstance(seg, Quadratic):
                    result += [
                        Move(seg.x2, seg.y2),
                        Line(prev.x, prev.y),
                        Move(seg.x2, seg.y2),
                        Line(seg.x3, seg.y3)
                    ]
                prev = seg.end_point(start, prev)

            if not result:
                continue

            elem = node.getparent().add(inkex.PathElement())
            elem.path = result.transform(node.transform)
            elem.style = {
                'stroke-linejoin': 'miter',
                'stroke-width': '1.0px',
                'stroke-opacity': '1.0',
                'fill-opacity': '1.0',
                'stroke': '#000000',
                'stroke-linecap': 'butt',
                'fill': 'none'
            }
예제 #9
0
    def to_meshdata(subpath):
        """Convert csp subpath to corners, edge path data."""
        if len(subpath) >= 5:
            corners = []
            edges = []
            for i, corner in enumerate(subpath[:4]):
                corners.append(corner[1])
                edge = [list(subpath[i]), list(subpath[i+1])]
                edge[0][0] = list(edge[0][1])
                edge[1][2] = list(edge[1][1])
                if inkex.CubicSuperPath.is_line(edge[0], edge[1]):
                    edges.append(Line(*edge[1][1]))
                else:
                    edges.append(Curve(*(edge[0][2] + edge[1][0] + edge[1][1])))

        return corners, edges
예제 #10
0
def draw_poly(pts, face, st, name, parent):
    """Draw polygone"""
    style = {'stroke': '#000000', 'stroke-width': str(st.th), 'stroke-linejoin': st.linejoin,
             'stroke-opacity': st.s_opac, 'fill': st.fill, 'fill-opacity': st.f_opac}
    path = inkex.Path()
    for facet in face:
        if not path:  # for first point
            path.append(Move(pts[facet - 1][0], -pts[facet - 1][1]))
        else:
            path.append(Line(pts[facet - 1][0], -pts[facet - 1][1]))
    path.close()

    poly = parent.add(inkex.PathElement())
    poly.label = name
    poly.style = style
    poly.path = path
예제 #11
0
    def process_segment(cmd_proxy, facegroup, delx, dely):
        """Process each segments"""

        segments = []
        if isinstance(cmd_proxy.command,
                      (Curve, Smooth, TepidQuadratic, Quadratic, Arc)):
            prev = cmd_proxy.previous_end_point
            for curve in cmd_proxy.to_curves():
                bez = [prev] + curve.to_bez()
                prev = curve.end_point(cmd_proxy.first_point, prev)
                tees = [
                    t for t in beziertatslope(bez, (dely, delx)) if 0 < t < 1
                ]
                tees.sort()
                if len(tees) == 1:
                    one, two = beziersplitatt(bez, tees[0])
                    segments.append(Curve(*(one[1] + one[2] + one[3])))
                    segments.append(Curve(*(two[1] + two[2] + two[3])))
                elif len(tees) == 2:
                    one, two = beziersplitatt(bez, tees[0])
                    two, three = beziersplitatt(two, tees[1])
                    segments.append(Curve(*(one[1] + one[2] + one[3])))
                    segments.append(Curve(*(two[1] + two[2] + two[3])))
                    segments.append(Curve(*(three[1] + three[2] + three[3])))
                else:
                    segments.append(curve)
        elif isinstance(cmd_proxy.command, (Line, Curve)):
            segments.append(cmd_proxy.command)
        elif isinstance(cmd_proxy.command, ZoneClose):
            segments.append(
                Line(cmd_proxy.first_point.x, cmd_proxy.first_point.y))
        elif isinstance(cmd_proxy.command, (Vert, Horz)):
            segments.append(cmd_proxy.command.to_line(cmd_proxy.end_point))

        for seg in Path([Move(*cmd_proxy.previous_end_point)] +
                        segments).proxy_iterator():
            if isinstance(seg.command, Move): continue
            Motion.makeface(seg.previous_end_point, seg.command, facegroup,
                            delx, dely)
예제 #12
0
    def makeface(last, segment, facegroup, delx, dely):
        """translate path segment along vector"""
        elem = facegroup.add(inkex.PathElement())

        npt = segment.translate([delx, dely])

        # reverse direction of path segment
        if isinstance(segment, Curve):
            rev = Curve(npt.x3, npt.y3, npt.x2, npt.y2, last[0] + delx,
                        last[1] + dely)
        elif isinstance(segment, Line):
            rev = Line(last[0] + delx, last[1] + dely)
        else:
            raise RuntimeError("Unexpected segment type {}".format(
                type(segment)))

        elem.path = inkex.Path([
            Move(last[0], last[1]),
            segment,
            npt.to_line(Vector2d()),
            rev,
            ZoneClose(),
        ])
예제 #13
0
 def test_new_path(self):
     """Test new path element"""
     path = PathElement.new(path=[Move(10, 10), Line(20, 20)])
     self.assertEqual(path.get('d'), 'M 10 10 L 20 20')
예제 #14
0
    def effect(self):
        path_num = 0
        elems = []
        npaths = []
        sstr = None
        for selem in self.svg.selection.filter(PathElement):
            elems.append(copy.deepcopy(selem))
        if len(elems) == 0:
            raise inkex.AbortExtension("Nothing selected")
        for elem in elems:
            escale = 1.0
            npaths.clear()
            #inkex.utils.debug(elem.attrib)
            if 'style' in elem.attrib:
                sstr = elem.attrib['style']
            if 'transform' in elem.attrib:
                transforms = elem.attrib['transform'].split()
                for tf in transforms:
                    if tf.startswith('scale'):
                        escale = float(tf.split('(')[1].split(')')[0])
                if sstr != None:
                    lsstr = sstr.split(';')
                    for stoken in range(len(lsstr)):
                        if lsstr[stoken].startswith('stroke-width'):
                            swt = lsstr[stoken].split(':')[1]
                            if not swt[2:].isalpha(
                            ):  # is value expressed in units (e.g. px)?
                                swf = str(float(swt) * escale)  # no. scale it
                                lsstr[stoken] = lsstr[stoken].replace(swt, swf)
                        if lsstr[stoken].startswith('stroke-miterlimit'):
                            swt = lsstr[stoken].split(':')[1]
                            if not swt[2:].isalpha(
                            ):  # is value expressed in units (e.g. px)?
                                swf = str(float(swt) * escale)  # no. scale it
                                lsstr[stoken] = lsstr[stoken].replace(swt, swf)
                    sstr = ";".join(lsstr)
                else:
                    sstr = None
                elem.apply_transform()
            xbound, ybound = elem.bounding_box()  # Get bounds of this element
            xmin, xmax = xbound
            ymin, ymax = ybound
            ntotal = len(elem.path)
            nodecnt = 0
            startx = 0
            starty = ymax + 10 * escale
            endx = 0
            endy = starty
            xoffset = 0
            orig_sx = 0
            orig_sy = 0
            orig_ex = 0
            orig_ey = 0
            sx1 = 0
            sy1 = 0
            orig_length = 0
            prev = Vector2d()
            for ptoken in elem.path.to_absolute(
            ):  # For each point in the path
                startx = xmin + xoffset
                if ptoken.letter == 'M':  # Starting a new line
                    orig_sx = ptoken.x
                    orig_sy = ptoken.y
                    cd = Path()
                    cd.append(Move(startx, starty))
                    sx1 = orig_sx
                    sy1 = orig_sy
                else:
                    if last_letter != 'M':
                        orig_sx = orig_ex
                        orig_sy = orig_ey

                    if ptoken.letter == 'L':
                        orig_ex = ptoken.x
                        orig_ey = ptoken.y
                        orig_length = math.sqrt((orig_sx - orig_ex)**2 +
                                                (orig_sy - orig_ey)**2)
                        endx = startx + orig_length
                        cd.append(Line(endx, endy))
                    elif ptoken.letter == 'H':
                        orig_ey = ptoken.to_line(prev).y
                        orig_length = abs(orig_sx - ptoken.x)
                        orig_ex = ptoken.x
                        endx = startx + orig_length
                        cd.append(Line(endx, endy))
                    elif ptoken.letter == 'V':
                        orig_ex = ptoken.to_line(prev).x
                        orig_length = abs(orig_sy - ptoken.y)
                        orig_ey = ptoken.y
                        endx = startx + orig_length
                        cd.append(Line(endx, endy))
                    elif ptoken.letter == 'Z':
                        orig_ex = sx1
                        orig_ey = sy1
                        orig_length = math.sqrt((orig_sx - orig_ex)**2 +
                                                (orig_sy - orig_ey)**2)
                        endx = startx + orig_length
                        cd.append(Line(endx, endy))
                    elif ptoken.letter == 'C':
                        bez = ptoken.to_bez()  # [[x0,y0][x1,y1][x2,y2][x3,y3]]
                        bez.insert(0, [prev.x, prev.y])
                        orig_ex = bez[3][0]  #x3
                        orig_ey = bez[3][1]  #y3
                        orig_length = inkex.bezier.bezierlength(bez)
                        endx = startx + orig_length
                        cd.append(Line(endx, endy))
                    else:
                        raise inkex.AbortExtension(
                            "Unknown letter - {0}".format(ptoken.letter))
                nodecnt = nodecnt + 1
                if ptoken.letter != 'M':
                    if nodecnt == ntotal:
                        self.drawline(str(cd), "hline{0}".format(path_num),
                                      self.svg.get_current_layer(), sstr)
                        path_num = path_num + 1
                    xoffset = xoffset + orig_length
                    prev.x = orig_ex
                    prev.y = orig_ey
                else:
                    prev.x = orig_sx
                    prev.y = orig_sy
                last_letter = ptoken.letter
예제 #15
0
    def test_to_line(self):
        self.assertEqual(Vert(3).to_line(Vector2d(5, 11)), Line(5, 3))
        self.assertEqual(Horz(3).to_line(Vector2d(5, 11)), Line(3, 11))

        self.assertEqual(vert(3).to_line(Vector2d(5, 11)), Line(5, 14))
        self.assertEqual(horz(3).to_line(Vector2d(5, 11)), Line(8, 11))