Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug in transform handling #111

Closed
SebKuzminsky opened this issue May 15, 2020 · 3 comments · Fixed by #112 or #201
Closed

bug in transform handling #111

SebKuzminsky opened this issue May 15, 2020 · 3 comments · Fixed by #112 or #201

Comments

@SebKuzminsky
Copy link
Contributor

I'm playing around with the new Document and group/transform feature that @mxgrey added, and I love it -- it's a huge usability improvement.

But I think I've found a bug.

Here's my input SVG:
bones.svg.txt
bones

The 5 paths in that SVG are in a group that uses this transform:

<g id="Sketch" transform="translate(18.120601,518.120601) scale(1,-1)">

Loading that SVG via svg2paths2() and Document reveals the problem:

In [1]: import svgpathtools

In [2]: paths, attr, svg_attr = svgpathtools.svg2paths2('bones.svg')

In [3]: paths[0]
Out[3]: 
Path(Arc(start=(63-1.55117330333e-12j), radius=(15+15j), rotation=0.0, large_arc=True, sweep=True, end=(93+6.20469321331e-12j)),
     Line(start=(93+6.20469321331e-12j), end=(93+350j)),
     Arc(start=(93+350j), radius=(15+15j), rotation=0.0, large_arc=True, sweep=True, end=(63+350j)),
     Line(start=(63+350j), end=(63+0j)))

In [4]: doc = svgpathtools.Document('bones.svg')

In [5]: results = doc.flatten_all_paths()

In [6]: results[0]
Out[6]: 
FlattenedPath(path=Path(Arc(start=(81.120601+518.120601j), radius=(15+15j), rotation=0.0, large_arc=True, sweep=True, end=(111.120601+518.120601j)),
     Line(start=(111.120601+518.120601j), end=(111.120601+168.120601j)),
     Arc(start=(111.120601+168.120601j), radius=(15+15j), rotation=0.0, large_arc=True, sweep=True, end=(81.120601+168.120601j)),
     Line(start=(81.120601+168.120601j), end=(81.120601+518.120601j))), element=<Element '{http://www.w3.org/2000/svg}path' at 0x7fe75ede9050>, transform=array([[  1.      ,   0.      ,  18.120601],
       [  0.      ,  -1.      , 518.120601],
       [  0.      ,   0.      ,   1.      ]]))

In [7]: results[0].path
Out[7]: 
Path(Arc(start=(81.120601+518.120601j), radius=(15+15j), rotation=0.0, large_arc=True, sweep=True, end=(111.120601+518.120601j)),
     Line(start=(111.120601+518.120601j), end=(111.120601+168.120601j)),
     Arc(start=(111.120601+168.120601j), radius=(15+15j), rotation=0.0, large_arc=True, sweep=True, end=(81.120601+168.120601j)),
     Line(start=(81.120601+168.120601j), end=(81.120601+518.120601j)))

In [8]: output = [result.path for result in results]

In [9]: svgpathtools.paths2svg.wsvg(paths=output)

The arcs turned inside out! This is what the flattened paths look like:
disvg_output.svg.txt
disvg_output svg

I haven't debugged it, but I'm going to guess that the negative Y scale may be implicated here.

@swolebro
Copy link

Yuuuuup, hit this one myself yesterday, and arrived at the same conclusion as you. Just wanted to chime in and give you that vote of confidence.

(If only I had seen your ticket earlier! Hahah.)

@tatarize
Copy link
Contributor

tatarize commented Jun 4, 2020

Yeah, I can also confirm mathwise that for each of the scale_x or scale_y parameters you have negative, you must negate the sweep. So if they are both flipped you negate twice and get positive sweep.

@SebKuzminsky
Copy link
Contributor Author

SebKuzminsky commented Jun 6, 2020

Yup, that's exactly what the linked PR does: flip the sweep if either but not both are negative.

https://github.com/mathandy/svgpathtools/pull/112/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants