From 929202aa62fdfac9043f2a49f4a38349cd297786 Mon Sep 17 00:00:00 2001 From: Sebastian Kuzminsky Date: Fri, 19 Jun 2020 19:45:56 -0600 Subject: [PATCH] Cache arc length (#82) * add Arc.__hash__() This function returns a hash of the Arc parameters, providing a kind of Arc object fingerprint. * Arc: cache segment length Computing the length of an Arc segment takes a relatively long time. This commit teaches the Arc class to remember its segment length, to avoid recomputing it. It invalidates the cache and recomputes the segment length if any of the Arc parameters have changed. --- svgpathtools/path.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/svgpathtools/path.py b/svgpathtools/path.py index dccfc0e..34c6765 100644 --- a/svgpathtools/path.py +++ b/svgpathtools/path.py @@ -1327,6 +1327,9 @@ class Arc(object): self.end = end self.autoscale_radius = autoscale_radius + self.segment_length_hash = None + self.segment_length = None + # Convenience parameters self.phi = radians(self.rotation) self.rot_matrix = exp(1j*self.phi) @@ -1334,6 +1337,9 @@ class Arc(object): # Derive derived parameters self._parameterize() + def __hash__(self): + return hash((self.start, self.radius, self.rotation, self.large_arc, self.sweep, self.end)) + def __repr__(self): params = (self.start, self.radius, self.rotation, self.large_arc, self.sweep, self.end) @@ -1626,6 +1632,19 @@ class Arc(object): integration, and in that case it's simpler to just do a geometric approximation, as for cubic bezier curves.""" assert 0 <= t0 <= 1 and 0 <= t1 <= 1 + + if t0 == 0 and t1 == 1: + h = hash(self) + if self.segment_length_hash is None or self.segment_length_hash != h: + self.segment_length_hash = h + if _quad_available: + self.segment_length = quad(lambda tau: abs(self.derivative(tau)), + t0, t1, epsabs=error, limit=1000)[0] + else: + self.segment_length = segment_length(self, t0, t1, self.point(t0), + self.point(t1), error, min_depth, 0) + return self.segment_length + if _quad_available: return quad(lambda tau: abs(self.derivative(tau)), t0, t1, epsabs=error, limit=1000)[0]