mathandy / svgpathtools

A collection of tools for manipulating and analyzing SVG Path objects and Bezier curves.
MIT License
558 stars 142 forks source link

No such elliptic arc exists: Regression between 1.4.1 and 1.4.2 #171

Closed yaqwsx closed 2 years ago

yaqwsx commented 2 years ago

I have the following simple script:

import svgpathtools
import sys

document = svgpathtools.Document(sys.argv[1])
paths = document.paths()

When I run it on SVG below:

test Zipped version

The stack trace is:

 File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/document.py", line 261, in paths
    return flattened_paths(self.tree.getroot(), group_filter,
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/document.py", line 143, in flattened_paths
    path = transform(parse_path(converter(path_elem)), path_tf)
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 309, in transform
    return transform_segments_together(curve, transformation)
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 191, in transform_segments_together
    transformed_segs = [transformation(seg) for seg in path]
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 191, in <listcomp>
    transformed_segs = [transformation(seg) for seg in path]
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 308, in <lambda>
    transformation = lambda seg: transform(seg, tf)
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 339, in transform
    return Arc(new_start, radius=new_radius, rotation=curve.rotation + rot,
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 1448, in __init__
    self._parameterize()
  File "/home/xmrazek7/.local/lib/python3.8/site-packages/svgpathtools/path.py", line 1503, in _parameterize
    raise ValueError("No such elliptic arc exists.")
ValueError: No such elliptic arc exists.
yaqwsx commented 2 years ago

It seems to me like a float rounding error (the SVG uses large numbers). The problem is in this code:

https://github.com/mathandy/svgpathtools/blob/a78ecf42902708261024a13405199161e477f6d2/svgpathtools/path.py#L1494-L1503

In version 1.4.1 all radius_check values are 1.0, however, in version 1.4.2 there are arcs for which the value of radius_check is 1.0000000000000004 which triggers the error path.

However, I am not familiar with the code base enough to be able to track down the problem nor be confident that adding an epsilon in the condition is suitable or not.

yaqwsx commented 2 years ago

Hi, any update on this? I would like to help, however, I don't have enough inside this fairly large codebase to actually be able to trace down the root cause of wrongly computing radius_check.

mathandy commented 2 years ago

Thanks for reporting this @yaqwsx! This is now fixed in v1.5.1.

yaqwsx commented 2 years ago

Thanks! I will test it in the upcoming weeks.

mathandy commented 2 years ago

Great. Just FYI, I'll be adding some regression tests (see #179). If you have any SVGs you'd like included, please attach them to a comment on that thread.

yaqwsx commented 2 years ago

Thanks, it seems that it works nicely! I updated my tools to use the newest release.