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:
|
else:
|
||||||
isy = 1j*sy
|
isy = 1j*sy
|
||||||
|
|
||||||
def transform(z, origin=origin):
|
def _scale(z):
|
||||||
zeta = z - origin
|
if sy is None:
|
||||||
return sx*zeta.real + isy*zeta.imag + origin
|
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):
|
if isinstance(curve, Path):
|
||||||
return Path(*[scale(seg, sx, sy, 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([transform(z) for z in curve.bpoints()])
|
return scale_bezier(curve)
|
||||||
elif isinstance(curve, Arc):
|
elif isinstance(curve, Arc):
|
||||||
if sy is None or sy == sx:
|
if sy is None or sy == sx:
|
||||||
return Arc(start=transform(curve.start),
|
return Arc(start=sx*(curve.start - origin) + origin,
|
||||||
radius=transform(curve.radius, origin=0),
|
radius=sx*curve.radius,
|
||||||
rotation=curve.rotation,
|
rotation=curve.rotation,
|
||||||
large_arc=curve.large_arc,
|
large_arc=curve.large_arc,
|
||||||
sweep=curve.sweep,
|
sweep=curve.sweep,
|
||||||
end=transform(curve.end))
|
end=sx*(curve.end - origin) + origin)
|
||||||
else:
|
else:
|
||||||
raise Exception("For `Arc` objects, only scale transforms "
|
raise Exception("\nFor `Arc` objects, only scale transforms "
|
||||||
"with sx==sy are implemented.")
|
"with sx==sy are implemented.\n")
|
||||||
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.")
|
||||||
|
|
|
@ -7,6 +7,7 @@ import numpy as np
|
||||||
|
|
||||||
# Internal dependencies
|
# Internal dependencies
|
||||||
from svgpathtools import *
|
from svgpathtools import *
|
||||||
|
from svgpathtools.path import _NotImplemented4ArcException
|
||||||
|
|
||||||
# An important note for those doing any debugging:
|
# An important note for those doing any debugging:
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
|
@ -780,39 +781,86 @@ class TestPath(unittest.TestCase):
|
||||||
isinstance(curve, Path) and
|
isinstance(curve, Path) and
|
||||||
any(isinstance(seg, Arc) for seg in curve))
|
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
|
# 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)
|
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)
|
ans = scale_a_point(pt, sx, None, origin)
|
||||||
self.assertAlmostEqual(ans,
|
curve_scaled = curve.scaled(sx, origin=origin)
|
||||||
curve.scaled(sx, origin=origin).point(t))
|
# res = curve_scaled.point(t)
|
||||||
|
if isinstance(curve, Path):
|
||||||
# the cases with sx != sy are not yet imp
|
res = curve_scaled[seg_idx].point(seg_t)
|
||||||
if isinstance(curve, Arc):
|
else:
|
||||||
continue
|
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
|
# case where `sx != sy`, and no `origin` given
|
||||||
ans = scale_a_point(pt, sx, sy)
|
ans = scale_a_point(pt, sx, sy)
|
||||||
if has_arc:
|
if has_arc: # the cases with sx != sy are not yet imp for arcs
|
||||||
self.assertRaises(Exception, curve.scaled(sx, sy).point(t))
|
with self.assertRaises(Exception):
|
||||||
|
curve.scaled(sx, sy).point(t)
|
||||||
else:
|
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
|
# case where `sx != sy`, and random `origin` given
|
||||||
ans = scale_a_point(pt, sx, sy, origin)
|
ans = scale_a_point(pt, sx, sy, origin)
|
||||||
if has_arc:
|
if has_arc: # the cases with sx != sy are not yet imp for arcs
|
||||||
self.assertRaises(Exception,
|
with self.assertRaises(Exception):
|
||||||
curve.scaled(sx, sy, origin).point(t))
|
curve.scaled(sx, sy, origin).point(t)
|
||||||
else:
|
else:
|
||||||
self.assertAlmostEqual(ans,
|
curve_scaled = curve.scaled(sx, sy, origin)
|
||||||
curve.scaled(sx, sy, origin).point(t))
|
# 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
|
# more tests for scalar (i.e. `sx == sy`) case
|
||||||
for curve in test_curves:
|
for curve in test_curves:
|
||||||
# scale by 2 around (100, 100)
|
# 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
|
# expected length
|
||||||
len_orig = curve.length()
|
len_orig = curve.length()
|
||||||
|
@ -829,7 +877,7 @@ class TestPath(unittest.TestCase):
|
||||||
# scale by 0.3 around (0, -100)
|
# scale by 0.3 around (0, -100)
|
||||||
# the 'almost equal' test fails at the 7th decimal place for
|
# the 'almost equal' test fails at the 7th decimal place for
|
||||||
# some length and position tests here.
|
# 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
|
# expected length
|
||||||
len_orig = curve.length()
|
len_orig = curve.length()
|
||||||
|
|
Loading…
Reference in New Issue