implemented (almost) full SVG scale transform functionality

pull/54/head
Andy Port 2018-05-30 19:07:58 -07:00 committed by GitHub
parent ee656c7de0
commit 72d7467896
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 45 additions and 28 deletions

View File

@ -207,25 +207,42 @@ def translate(curve, z0):
"QuadraticBezier, CubicBezier, or Arc object.") "QuadraticBezier, CubicBezier, or Arc object.")
def scale_uniform(curve, factor, origin=0j): def scale(curve, sx, sy=None, origin=0j):
"""Uniformly scales `curve` by scalar `factor` around `origin`. """Scales `curve`, about `origin`, by diagonal matrix `[[sx,0],[0,sy]]`.
Note: scale_uniform(curve, s, origin).point(t) == Notes:
((curve.point(t) - origin) * factor) + origin ------
* If `sy` is not specified, it is assumed to be equal to `sx` and
a scalar transformation of `curve` about `origin` will be returned.
I.e.
scale(curve, sx, origin).point(t) ==
((curve.point(t) - origin) * sx) + origin
""" """
def _scale_point(z, s, origin): if sy is None:
return ((z - origin) * s) + origin isy = 1j*sx
else:
isy = 1j*sy
def transform(z, sx=sx, sy=sy, origin=origin):
zeta = z - origin
return x*zeta.real + isy*zeta.imag + origin
if isinstance(curve, Path): if isinstance(curve, Path):
return Path(*[scale_uniform(seg, factor, origin) for seg in curve]) return Path(*[scale(seg, sx, sy, origin) for seg in curve])
elif is_bezier_segment(curve): elif is_bezier_segment(curve):
return bpoints2bezier([_scale_point(bpt, factor, origin) for bpt in curve.bpoints()]) return bpoints2bezier([transform(z) for z in curve.bpoints()])
elif isinstance(curve, Arc): elif isinstance(curve, Arc):
new_start = _scale_point(curve.start, factor, origin) if y is None or y == x:
new_end = _scale_point(curve.end, factor, origin) return Arc(start=transform(curve.start),
return Arc(new_start, radius=curve.radius * factor, rotation=curve.rotation, radius=transform(radius, origin=0),
large_arc=curve.large_arc, sweep=curve.sweep, end=new_end) rotation=curve.rotation,
large_arc=curve.large_arc,
sweep=curve.sweep,
end=transform(curve.end))
else:
raise Excpetion("For `Arc` objects, only scale transforms "
"with sx==sy are implemenented.")
else: else:
raise TypeError("Input `curve` should be a Path, Line, " raise TypeError("Input `curve` should be a Path, Line, "
"QuadraticBezier, CubicBezier, or Arc object.") "QuadraticBezier, CubicBezier, or Arc object.")
@ -661,9 +678,9 @@ class Line(object):
that self.translated(z0).point(t) = self.point(t) + z0 for any t.""" that self.translated(z0).point(t) = self.point(t) + z0 for any t."""
return translate(self, z0) return translate(self, z0)
def scaled_uniform(self, factor, origin=None): def scaled(self, sx, sy=None, origin=0j):
"""Returns copy of self scaled by `factor` about `origin`.""" """Scale transform. See `scale` function for further explanation."""
return scale_uniform(self, factor, origin=origin) return scale(self, sx=sx, sy=sy, origin=origin)
class QuadraticBezier(object): class QuadraticBezier(object):
@ -909,9 +926,9 @@ class QuadraticBezier(object):
that self.translated(z0).point(t) = self.point(t) + z0 for any t.""" that self.translated(z0).point(t) = self.point(t) + z0 for any t."""
return translate(self, z0) return translate(self, z0)
def scaled_uniform(self, factor, origin=None): def scaled(self, sx, sy=None, origin=0j):
"""Returns copy of self scaled by `factor` about `origin`.""" """Scale transform. See `scale` function for further explanation."""
return scale_uniform(self, factor, origin=origin) return scale(self, sx=sx, sy=sy, origin=origin)
class CubicBezier(object): class CubicBezier(object):
@ -1153,9 +1170,9 @@ class CubicBezier(object):
that self.translated(z0).point(t) = self.point(t) + z0 for any t.""" that self.translated(z0).point(t) = self.point(t) + z0 for any t."""
return translate(self, z0) return translate(self, z0)
def scaled_uniform(self, factor, origin=None): def scaled(self, sx, sy=None, origin=0j):
"""Returns copy of self scaled by `factor` about `origin`.""" """Scale transform. See `scale` function for further explanation."""
return scale_uniform(self, factor, origin=origin) return scale(self, sx=sx, sy=sy, origin=origin)
class Arc(object): class Arc(object):
@ -1722,9 +1739,9 @@ class Arc(object):
that self.translated(z0).point(t) = self.point(t) + z0 for any t.""" that self.translated(z0).point(t) = self.point(t) + z0 for any t."""
return translate(self, z0) return translate(self, z0)
def scaled_uniform(self, factor, origin=None): def scaled(self, sx, sy=None, origin=0j):
"""Returns copy of self scaled by `factor` about `origin`.""" """Scale transform. See `scale` function for further explanation."""
return scale_uniform(self, factor, origin=origin) return scale(self, sx=sx, sy=sy, origin=origin)
def is_bezier_segment(x): def is_bezier_segment(x):
@ -2283,6 +2300,6 @@ class Path(MutableSequence):
that self.translated(z0).point(t) = self.point(t) + z0 for any t.""" that self.translated(z0).point(t) = self.point(t) + z0 for any t."""
return translate(self, z0) return translate(self, z0)
def scaled_uniform(self, factor, origin=None): def scaled(self, sx, sy=None, origin=0j):
"""Returns copy of self scaled by `factor` about `origin`.""" """Scale transform. See `scale` function for further explanation."""
return scale_uniform(self, factor, origin=origin) return scale(self, sx=sx, sy=sy, origin=origin)