fixed scaled (before cleanup)
parent
2cb56c50c5
commit
fd521748fa
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<svg baseProfile="full" height="600px" version="1.1" viewBox="161.5 79.0 152.0 242.0" width="377px" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs/>
|
||||
<path d="M 300.0,100.0 C 100.0,100.0 200.0,200.0 200.0,300.0" fill="none" stroke="blue" stroke-width="0.2"/>
|
||||
<path d="M 175.0,162.5 L 175.0,236.805280985" fill="none" stroke="green" stroke-width="0.2"/>
|
||||
<path d="M 175.0,162.5 L 249.305280985,162.5" fill="none" stroke="pink" stroke-width="0.2"/>
|
||||
<circle cx="175.0" cy="162.5" fill="#ff0000" r="1.0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 618 B |
|
@ -225,25 +225,31 @@ def scale(curve, sx, sy=None, origin=0j):
|
|||
else:
|
||||
isy = 1j*sy
|
||||
|
||||
def transform(z, origin=origin):
|
||||
zeta = z - origin
|
||||
return sx*zeta.real + isy*zeta.imag + origin
|
||||
def _scale(z):
|
||||
if sy is None:
|
||||
return sx*z
|
||||
return sx*z.real + isy*z.imag
|
||||
|
||||
def scale_bezier(bez):
|
||||
p = [_scale(c) for c in bez2poly(bez)]
|
||||
p[-1] += origin - _scale(origin)
|
||||
return poly2bez(p)
|
||||
|
||||
if isinstance(curve, Path):
|
||||
return Path(*[scale(seg, sx, sy, origin) for seg in curve])
|
||||
elif is_bezier_segment(curve):
|
||||
return bpoints2bezier([transform(z) for z in curve.bpoints()])
|
||||
return scale_bezier(curve)
|
||||
elif isinstance(curve, Arc):
|
||||
if sy is None or sy == sx:
|
||||
return Arc(start=transform(curve.start),
|
||||
radius=transform(curve.radius, origin=0),
|
||||
return Arc(start=sx*(curve.start - origin) + origin,
|
||||
radius=sx*curve.radius,
|
||||
rotation=curve.rotation,
|
||||
large_arc=curve.large_arc,
|
||||
sweep=curve.sweep,
|
||||
end=transform(curve.end))
|
||||
end=sx*(curve.end - origin) + origin)
|
||||
else:
|
||||
raise Exception("For `Arc` objects, only scale transforms "
|
||||
"with sx==sy are implemented.")
|
||||
raise Exception("\nFor `Arc` objects, only scale transforms "
|
||||
"with sx==sy are implemented.\n")
|
||||
else:
|
||||
raise TypeError("Input `curve` should be a Path, Line, "
|
||||
"QuadraticBezier, CubicBezier, or Arc object.")
|
||||
|
|
|
@ -7,6 +7,7 @@ import numpy as np
|
|||
|
||||
# Internal dependencies
|
||||
from svgpathtools import *
|
||||
from svgpathtools.path import _NotImplemented4ArcException
|
||||
|
||||
# An important note for those doing any debugging:
|
||||
# ------------------------------------------------
|
||||
|
@ -780,39 +781,86 @@ class TestPath(unittest.TestCase):
|
|||
isinstance(curve, Path) and
|
||||
any(isinstance(seg, Arc) for seg in curve))
|
||||
|
||||
# find seg which t lands on for failure reporting
|
||||
seg = curve
|
||||
if isinstance(curve, Path):
|
||||
seg_idx, seg_t = curve.T2t(t)
|
||||
seg = curve[seg_idx]
|
||||
_fail_msg = "Failure!\nseg {}\n".format(seg)
|
||||
|
||||
# case where no `sy` and no `origin` given
|
||||
curve_scaled = curve.scaled(sx)
|
||||
# res = curve_scaled.point(t)
|
||||
if isinstance(curve, Path):
|
||||
res = curve_scaled[seg_idx].point(seg_t)
|
||||
else:
|
||||
res = curve_scaled.point(t)
|
||||
ans = scale_a_point(pt, sx, None)
|
||||
self.assertAlmostEqual(ans, curve.scaled(sx).point(t))
|
||||
fail_msg = _fail_msg + ("curve.scaled({}, {}, {}) = \n{}\n"
|
||||
"".format(sx, None, None, curve_scaled))
|
||||
# fail_msg += "curve.point({}) = {}".format(t, res)
|
||||
fail_msg += "seg_scaled.point({}) = {}\n".format(seg_t, res)
|
||||
fail_msg += "ans = {}".format(ans)
|
||||
self.assertAlmostEqual(ans, res, places=4, msg=fail_msg)
|
||||
|
||||
# case where no `sy` and random `origin` given
|
||||
# case where random `origin` given but no `sy`
|
||||
ans = scale_a_point(pt, sx, None, origin)
|
||||
self.assertAlmostEqual(ans,
|
||||
curve.scaled(sx, origin=origin).point(t))
|
||||
|
||||
# the cases with sx != sy are not yet imp
|
||||
if isinstance(curve, Arc):
|
||||
continue
|
||||
curve_scaled = curve.scaled(sx, origin=origin)
|
||||
# res = curve_scaled.point(t)
|
||||
if isinstance(curve, Path):
|
||||
res = curve_scaled[seg_idx].point(seg_t)
|
||||
else:
|
||||
res = curve_scaled.point(t)
|
||||
fail_msg = _fail_msg + ("curve.scaled({}, {}, {}) = \n{}\n"
|
||||
"".format(sx, None, origin, curve_scaled))
|
||||
# fail_msg += "curve.point({}) = {}\n".format(t, res)
|
||||
fail_msg += "seg_scaled.point({}) = {}\n".format(seg_t, res)
|
||||
fail_msg += "ans = {}".format(ans)
|
||||
self.assertAlmostEqual(ans, res, places=4, msg=fail_msg)
|
||||
|
||||
# case where `sx != sy`, and no `origin` given
|
||||
ans = scale_a_point(pt, sx, sy)
|
||||
if has_arc:
|
||||
self.assertRaises(Exception, curve.scaled(sx, sy).point(t))
|
||||
if has_arc: # the cases with sx != sy are not yet imp for arcs
|
||||
with self.assertRaises(Exception):
|
||||
curve.scaled(sx, sy).point(t)
|
||||
else:
|
||||
self.assertAlmostEqual(ans, curve.scaled(sx, sy).point(t))
|
||||
curve_scaled = curve.scaled(sx, sy)
|
||||
seg_scaled = seg.scaled(sx, sy)
|
||||
# res = curve_scaled.point(t)
|
||||
if isinstance(curve, Path):
|
||||
res = curve_scaled[seg_idx].point(seg_t)
|
||||
else:
|
||||
res = curve_scaled.point(t)
|
||||
fail_msg = _fail_msg + ("curve.scaled({}, {}, {}) = \n{}\n"
|
||||
"".format(sx, sy, None, curve_scaled))
|
||||
# fail_msg += "curve.point({}) = {}\n".format(t, res)
|
||||
fail_msg += "seg_scaled.point({}) = {}\n".format(seg_t, res)
|
||||
fail_msg += "ans = {}".format(ans)
|
||||
self.assertAlmostEqual(ans, res, places=4, msg=fail_msg)
|
||||
|
||||
# case where `sx != sy`, and random `origin` given
|
||||
ans = scale_a_point(pt, sx, sy, origin)
|
||||
if has_arc:
|
||||
self.assertRaises(Exception,
|
||||
curve.scaled(sx, sy, origin).point(t))
|
||||
if has_arc: # the cases with sx != sy are not yet imp for arcs
|
||||
with self.assertRaises(Exception):
|
||||
curve.scaled(sx, sy, origin).point(t)
|
||||
else:
|
||||
self.assertAlmostEqual(ans,
|
||||
curve.scaled(sx, sy, origin).point(t))
|
||||
curve_scaled = curve.scaled(sx, sy, origin)
|
||||
# res = curve_scaled.point(t)
|
||||
if isinstance(curve, Path):
|
||||
res = curve_scaled[seg_idx].point(seg_t)
|
||||
else:
|
||||
res = curve_scaled.point(t)
|
||||
fail_msg = _fail_msg + ("curve.scaled({}, {}, {}) = \n{}\n"
|
||||
"".format(sx, sy, origin, curve_scaled))
|
||||
# fail_msg += "curve.point({}) = {}\n".format(t, res)
|
||||
fail_msg += "seg_scaled.point({}) = {}\n".format(seg_t, res)
|
||||
fail_msg += "ans = {}".format(ans)
|
||||
self.assertAlmostEqual(ans, res, places=4, msg=fail_msg)
|
||||
|
||||
# more tests for scalar (i.e. `sx == sy`) case
|
||||
for curve in test_curves:
|
||||
# scale by 2 around (100, 100)
|
||||
scaled_curve = curve.scaled(2.0, complex(100, 100))
|
||||
scaled_curve = curve.scaled(2.0, origin=complex(100, 100))
|
||||
|
||||
# expected length
|
||||
len_orig = curve.length()
|
||||
|
@ -829,7 +877,7 @@ class TestPath(unittest.TestCase):
|
|||
# scale by 0.3 around (0, -100)
|
||||
# the 'almost equal' test fails at the 7th decimal place for
|
||||
# some length and position tests here.
|
||||
scaled_curve = curve.scaled(0.3, complex(0, -100))
|
||||
scaled_curve = curve.scaled(0.3, origin=complex(0, -100))
|
||||
|
||||
# expected length
|
||||
len_orig = curve.length()
|
||||
|
|
Loading…
Reference in New Issue