I don't want to edit the code too much during with the draft PR. Since it can get annoying. But, this code should be added to Path. I offered it up to svgpathtools and the code is actually pretty nice.
def approximate_arcs_with_cubics(self, error=0.1):
"""
Iterates through this path and replaces any Arcs with cubic bezier curves.
"""
tau = pi * 2
sweep_limit = degrees(tau * error)
for s in range(len(self)-1, -1, -1):
segment = self[s]
if not isinstance(segment, Arc):
continue
arc_required = int(ceil(abs(segment.delta) / sweep_limit))
self[s:s+1] = list(segment.as_cubic_curves(arc_required))
def approximate_arcs_with_quads(self, error=0.1):
"""
Iterates through this path and replaces any Arcs with quadratic bezier curves.
"""
tau = pi * 2
sweep_limit = degrees(tau * error)
for s in range(len(self)-1, -1, -1):
segment = self[s]
if not isinstance(segment, Arc):
continue
arc_required = int(ceil(abs(segment.delta) / sweep_limit))
self[s:s+1] = list(segment.as_quad_curves(arc_required))
And the test coverage added to TestPath, though maybe modify svgelements proper.
def test_approx_quad(self):
n = 100
for i in range(n):
arc = random_arc()
if arc.radius.real > 2000 or arc.radius.imag > 2000:
continue # Random Arc too large, by autoscale.
path1 = Path(arc)
path2 = Path(*path1)
path2.approximate_arcs_with_quads(error=0.05)
d = abs(path1.length() - path2.length())
# Error less than 1% typically less than 0.5%
self.assertAlmostEqual(d, 0.0, delta=20)
def test_approx_cubic(self):
n = 100
for i in range(n):
arc = random_arc()
if arc.radius.real > 2000 or arc.radius.imag > 2000:
continue # Random Arc too large, by autoscale.
path1 = Path(arc)
path2 = Path(*path1)
path2.approximate_arcs_with_cubics(error=0.1)
d = abs(path1.length() - path2.length())
# Error less than 0.1% typically less than 0.001%
self.assertAlmostEqual(d,0.0, delta=2)
I don't want to edit the code too much during with the draft PR. Since it can get annoying. But, this code should be added to
Path
. I offered it up tosvgpathtools
and the code is actually pretty nice.And the test coverage added to TestPath, though maybe modify
svgelements
proper.