def extend(self, normsubpaths):
"""extend path by normsubpaths or pathitems"""
for anormsubpath in normsubpaths:
# use append to properly handle regular path items as well as normsubpaths
self.append(anormsubpath)
python类Path()的实例源码
def join(self, other):
"""join other normsubpath inplace
Both normpaths must contain at least one normsubpath.
The last normsubpath of self will be joined to the first
normsubpath of other.
"""
other = other.normpath()
if not self.normsubpaths:
raise NormpathException("cannot join to empty path")
if not other.normsubpaths:
raise PathException("cannot join empty path")
self.normsubpaths[-1].join(other.normsubpaths[0])
self.normsubpaths.extend(other.normsubpaths[1:])
def path(self):
"""return path corresponding to normpath"""
pathitems = []
for normsubpath in self.normsubpaths:
pathitems.extend(normsubpath.pathitems())
return path.path(*pathitems)
def split_pt(self, params):
"""split path at param(s) or arc length(s) in pts and return list of normpaths"""
try:
for param in params:
break
except:
params = [params]
return self._split_pt(self._convertparams(params, self.arclentoparam_pt))
def split(self, params):
"""split path at param(s) or arc length(s) and return list of normpaths"""
try:
for param in params:
break
except:
params = [params]
return self._split_pt(self._convertparams(params, self.arclentoparam))
def tangent_pt(self, params, length_pt):
"""return tangent vector of path at param(s) or arc length(s) in pts
If length in pts is not None, the tangent vector will be scaled to
the desired length.
"""
return self._tangent(self._convertparams(params, self.arclentoparam_pt), length_pt)
def omitends(self, box1, box2):
"""intersects a path with the boxes' paths"""
# cut off the start of self
# XXX how can decoration of this box1.path() be handled?
sp = self.intersect(box1.path())[0]
if sp:
self.normsubpaths = self.split(sp[-1:])[1].normsubpaths
# cut off the end of self
sp = self.intersect(box2.path())[0]
if sp:
self.normsubpaths = self.split(sp[:1])[0].normsubpaths
def shortenpath(self, dists):
"""shortens a path by the given distances"""
# XXX later, this should be done by extended boxes instead of intersecting with circles
# cut off the start of self
center = self.atbegin_pt()
cutpath = path.circle_pt(center[0], center[1], dists[0])
try:
cutpath = cutpath.normpath()
except normpath.NormpathException:
pass
else:
sp = self.intersect(cutpath)[0]
self.normsubpaths = self.split(sp[-1:])[1].normsubpaths
# cut off the end of self
center = self.atend_pt()
cutpath = path.circle_pt(center[0], center[1], dists[1])
try:
cutpath = cutpath.normpath()
except normpath.NormpathException:
pass
else:
sp = self.intersect(cutpath)[0]
if sp:
self.normsubpaths = self.split(sp[:1])[0].normsubpaths
################
## classes
################
def __init__(self, box1, box2, boxdists=[0,0]):
self.box1 = box1
self.box2 = box2
connector_pt.__init__(self,
[path.normsubpath([path.normline_pt(self.box1.center[0], self.box1.center[1],
self.box2.center[0], self.box2.center[1])], closed=0)])
self.omitends(box1, box2)
self.shortenpath(boxdists)
def normpath_selfintersections(self, np, epsilon): # <<<
"""return all self-intersection points of normpath np.
This does not include the intersections of a single normcurve with itself,
but all intersections of one normpathitem with a different one in the path"""
n = len(np)
linearparams = []
parampairs = []
paramsriap = {}
for nsp_i in range(n):
for nsp_j in range(nsp_i, n):
for nspitem_i in range(len(np[nsp_i])):
if nsp_j == nsp_i:
nspitem_j_range = range(nspitem_i+1, len(np[nsp_j]))
else:
nspitem_j_range = range(len(np[nsp_j]))
for nspitem_j in nspitem_j_range:
intsparams = np[nsp_i][nspitem_i].intersect(np[nsp_j][nspitem_j], epsilon)
if intsparams:
for intsparam_i, intsparam_j in intsparams:
if ( (abs(intsparam_i) < epsilon and abs(1-intsparam_j) < epsilon) or
(abs(intsparam_j) < epsilon and abs(1-intsparam_i) < epsilon) ):
continue
npp_i = normpath.normpathparam(np, nsp_i, float(nspitem_i)+intsparam_i)
npp_j = normpath.normpathparam(np, nsp_j, float(nspitem_j)+intsparam_j)
linearparams.append(npp_i)
linearparams.append(npp_j)
paramsriap[id(npp_i)] = len(parampairs)
paramsriap[id(npp_j)] = len(parampairs)
parampairs.append((npp_i, npp_j))
linearparams.sort()
return linearparams, parampairs, paramsriap
# >>>