svgpathtools
svgpathtools copied to clipboard
Arcs with rotation transforms are not properly interpreted
Setup
python 3.8.6 svgpathtools master (45dc873f82fba28ae905eb4262446cc54908a8a8)
Expected
Arc with rotation transform are interpreted correctly:
E.g.:
[...]
<g>
<g transform="translate(40,40)">
<path style="fill:none;stroke:#666" d="M12 -12 A12 12 0 0 1 -12 -12"/>
</g>
<g transform="translate(80,40) rotate(36)">
<path style="fill:none;stroke:#666" d="M12 -12 A12 12 0 0 1 -12 -12"/>
</g>
</g>
<g transform="translate(40,80)">
<path style="fill:none;stroke:#666" d="M12 -12 A12 12 0 0 1 -12 -12"/>
</g>
<g transform="translate(80,80)">
<g transform="rotate(36)">
<path style="fill:none;stroke:#666" d="M12 -12 A12 12 0 0 1 -12 -12"/>
</g>
</g>
[...]
Full test file: arc_with_rotate.svg.zip
Displayed by macOS:

Actual
Arcs with a rotation transform (the ones on the right in this example) are deformed when loaded with svgpathtools.
import math
import matplotlib.pyplot as plt
import numpy as np
import svgpathtools as svg
doc = svg.Document("arc_with_rotate.svg")
paths = doc.paths()
quantization = 1
for elem in paths:
step = int(math.ceil(elem.length() / quantization))
coords = np.empty(step + 1, dtype=complex)
coords[0] = elem.point(0)
for i in range(step):
coords[i + 1] = elem.point((i + 1) / step)
plt.plot(np.real(coords), np.imag(coords), "-")
plt.axis("equal")
plt.gca().invert_yaxis()
plt.show()
This simple test case is fixed by the following modification:
--- a/svgpathtools/path.py
+++ b/svgpathtools/path.py
@@ -288,7 +288,7 @@ def transform(curve, tf):
elif isinstance(curve, Arc):
new_start = to_complex(tf.dot(to_point(curve.start)))
new_end = to_complex(tf.dot(to_point(curve.end)))
- new_radius = to_complex(tf.dot(to_vector(curve.radius)))
+ new_radius = curve.radius
if tf[0][0] * tf[1][1] >= 0.0:
new_sweep = curve.sweep
else:
However, I am unsure if this induces other regressions.