diff --git a/examples/compute-many-points-quickly-using-numpy-arrays.py b/examples/compute-many-points-quickly-using-numpy-arrays.py new file mode 100644 index 0000000..590821a --- /dev/null +++ b/examples/compute-many-points-quickly-using-numpy-arrays.py @@ -0,0 +1,56 @@ +"""The goal of this gist is to show how to compute many points on a path +quickly using NumPy arrays. I.e. there's a much faster way than using, say +[some_path.point(t) for t in many_tvals]. The example below assumes the +`Path` object is composed entirely of `CubicBezier` objects, but this can +easily be generalized to paths containing `Line` and `QuadraticBezier` objects +also. +Note: The relevant matrix transformation for quadratics can be found in the +svgpathtools.bezier module.""" + +import numpy as np +from svgpathtools import * + + +class HigherOrderBezier: + def __init__(self, bpoints): + self.bpts = bpoints + + def bpoints(self): + return self.bpts + + def point(self, t): + return bezier_point(self.bpoints(), t) + + def __repr__(self): + return str(self.bpts) + + +def random_bezier(degree): + if degree <= 3: + return bpoints2bezier(polynomial2bezier(np.random.rand(degree + 1))) + else: + return HigherOrderBezier(np.random.rand(degree + 1)) + + +def points_in_each_seg_slow(path, tvals): + return [seg.poly()(tvals) for seg in path] + + +def points_in_each_seg(path, tvals): + """Compute seg.point(t) for each seg in path and each t in tvals.""" + A = np.matrix([[-1, 3, -3, 1], # transforms cubic bez to standard poly + [ 3, -6, 3, 0], + [-3, 3, 0, 0], + [ 1, 0, 0, 0]]) + B = [seg.bpoints() for seg in path] + return np.dot(B, np.dot(A, np.power(tvals, [[3],[2],[1],[0]]))) + + +if __name__ == '__main__': + num_segs = 1000 + testpath = Path(*[random_bezier(3) for dummy in range(num_segs)]) + tvals = np.linspace(0, 1, 10) + + pts = points_in_each_seg(testpath, tvals) + pts_check = points_in_each_seg_slow(testpath, tvals) + print np.max(pts - pts_check) diff --git a/examples/determine-if-svg-path-is-contained-in-other-path-example.py b/examples/determine-if-svg-path-is-contained-in-other-path-example.py new file mode 100755 index 0000000..2a01632 --- /dev/null +++ b/examples/determine-if-svg-path-is-contained-in-other-path-example.py @@ -0,0 +1,39 @@ +""" +An example of how to determine if an svg path is contained in another +svg path in Python. + +Note: for discontinuous paths you can use the svgpathtools +Path.continuous_subpaths() method to split a paths into a list of its +continuous subpaths. +""" + +from svgpathtools import * + +def path1_is_contained_in_path2(path1, path2): + assert path2.isclosed() # This question isn't well-defined otherwise + if path2.intersect(path1): + return False + + # find a point that's definitely outside path2 + xmin, xmax, ymin, ymax = path2.bbox() + B = (xmin + 1) + 1j*(ymax + 1) + + A = path1.start # pick an arbitrary point in path1 + AB_line = Path(Line(A, B)) + number_of_intersections = len(AB_line.intersect(path2)) + if number_of_intersections % 2: # if number of intersections is odd + return True + else: + return False + + +# Test examples +closed_path = Path(Line(0,5), Line(5,5+5j), Line(5+5j, 0)) +path_that_is_contained = Path(Line(1+1j, 2+2j)) +print(path1_is_contained_in_path2(path_that_is_contained, closed_path)) + +path_thats_not_contained = Path(Line(10+10j, 20+20j)) +print(path1_is_contained_in_path2(path_thats_not_contained, closed_path)) + +path_that_intersects = Path(Line(2+1j, 10+10j)) +print(path1_is_contained_in_path2(path_that_intersects, closed_path)) diff --git a/examples/distance-between-two-svg-paths-example.py b/examples/distance-between-two-svg-paths-example.py new file mode 100755 index 0000000..57e2749 --- /dev/null +++ b/examples/distance-between-two-svg-paths-example.py @@ -0,0 +1,17 @@ +from svgpathtools import * + +# create some example paths +path1 = CubicBezier(1,2+3j,3-5j,4+1j) +path2 = path1.rotated(60).translated(3) + +# find minimizer +from scipy.optimize import fminbound +def dist(t): + return path1.radialrange(path2.point(t))[0][0] +T2 = fminbound(dist, 0, 1) + +# Let's do a visual check +pt2 = path2.point(T2) +T1 = path1.radialrange(pt2)[0][1] +pt1 = path1.point(T1) +disvg([path1, path2, Line(pt1, pt2)], 'grb', nodes=[pt1, pt2])