def curveat(curve, t): return node(bezierpointatt(((node.x, node.y) for node in curve), t)) # This function takes in a list of nodes and returns # a list of numbers between 0 and 1 corresponding to the relative positions # of said nodes (assuming consecutive nodes are linked by straight lines). # The first item is always 0.0 and the last one 1.0. def chords(nodes):
def csp_at_t(sp1,sp2,t): bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) return bezmisc.bezierpointatt(bez,t)
def computePointsXY(self, pathId, offsets, globalOffset=0.0): #offsets.sort() if they have random order, but objects should be sorted respectively to them if self.selected[pathId].get( 'd'): #determine path parameters and transform it mat = [[1, 0, 0], [0, 1, 0]] m = simpletransformed.parseTransform( self.selected[pathId].get('transform')) m = simpletransformed.composeTransform(mat, m) csp = cubicsuperpath.parsePath(self.selected[pathId].get('d')) simpletransformed.applyTransformToPath(m, csp) else: inkex.debug( "Only paths are supported as a guide. Make sure your path is in back of other objects." ) return None retval = [] offsetP = 0 curveLengths = [] totalLength = 0.0 last_subpath = 0 for csp_i in xrange(len(csp)): last_subpath = csp_i for i in xrange(len(csp[csp_i]) - 1): #For every segment of a path #determine its length curveLengths.append( bezmisc.bezierlength( (csp[csp_i][i][1], csp[csp_i][i][2], csp[csp_i][i + 1][0], csp[csp_i][i + 1][1]))) #Compute total lenth of a path by sum of each part totalLength = totalLength + curveLengths[-1] if totalLength >= ( offsets[offsetP] + globalOffset ): #If offset belongs to current path's part while ( offsets[offsetP] + globalOffset ) <= totalLength: #for all offsets that belong to current path's part dlength = totalLength - ( offsets[offsetP] + globalOffset ) #distance between part start and offset t = 1 - dlength / curveLengths[ -1] #I don't understand bezier basics... seems that this is right #Compute x,y and alpha as atan(slope) x, y = bezmisc.bezierpointatt( (csp[csp_i][i][1], csp[csp_i][i][2], csp[csp_i][i + 1][0], csp[csp_i][i + 1][1]), t) dx, dy = bezmisc.bezierslopeatt( (csp[csp_i][i][1], csp[csp_i][i][2], csp[csp_i][i + 1][0], csp[csp_i][i + 1][1]), t) try: alpha = math.atan( dy / dx ) #FIXME: divsion by zero on straight lines and 90deg. rotation except: alpha = 0.0 retval.append([x, y, alpha]) #Append to result offsetP = offsetP + 1 if offsetP > (len(offsets) - 1): #If no more offsets return value return retval #If total sum of distances between objects are greater than curve length, # then put one more object that beyond the curve in last valid position # and others left in their places if len(retval) < len(offsets): #for i in xrange(len(retval),len(offsets)): #to place all reminded objects x, y = bezmisc.bezierpointatt( (csp[last_subpath][-2][1], csp[last_subpath][-2][2], csp[last_subpath][-1][0], csp[last_subpath][-1][1]), 1.0) retval.append([x, y, 0.0]) return retval
def bezlinearize(bez, npts): return [bezmisc.bezierpointatt(bez, t) for t in seq(0,1,npts)]
def curveat(curve, t): return node(bezierpointatt(((node.x, node.y) for node in curve), t))
def csp_at_t(sp1, sp2, t): bez = (sp1[1][:], sp1[2][:], sp2[0][:], sp2[1][:]) return bezmisc.bezierpointatt(bez, t)
def duplicate(self, points): i = 0 while i < 1: x, y = bezmisc.bezierpointatt(points, i) self.copy_pattern(x, y) i += 0.001
def approx_curve(self, points): for four in take_N(points, 4): # TODO: automatically set number of samples depending on length for t in sample(0, 1, 50): yield bezmisc.bezierpointatt(four, t)
def bezlinearize(bez, npts): return [bezmisc.bezierpointatt(bez, t) for t in seq(0, 1, npts)]