added "examples" folder
parent
385dbb7196
commit
dcd4896fd6
|
@ -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)
|
|
@ -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))
|
|
@ -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])
|
Loading…
Reference in New Issue