def __calcupoly2(self, ptlistplus): """ 算出每个点的抛物线 :param ptlistplus: :return: abcdeflist """ abcdeflist = [] for i in range(1, self.L + 1): #i-1,i,i+1 s1 = self.calcuS(i - 1, ptlistplus) s2 = s1 + distance(ptlistplus[i - 1], ptlistplus[i]) s3 = s2 + distance(ptlistplus[i], ptlistplus[i + 1]) mat1 = np.mat([[1, s1, s1 * s1], [1, s2, s2 * s2], [1, s3, s3 * s3]]) matx = np.mat([[ptlistplus[i - 1][0]], [ptlistplus[i][0]], [ptlistplus[i + 1][0]]]) maty = np.mat([[ptlistplus[i - 1][1]], [ptlistplus[i][1]], [ptlistplus[i + 1][1]]]) inv = np.linalg.inv(mat1) matabc = np.dot(inv, matx) matabc = matabc.tolist() matabc = [a[0] for a in matabc] matdef = np.dot(inv, maty) matdef = matdef.tolist() matdef = [a[0] for a in matdef] abcdeflist.append(matabc + matdef) return abcdeflist
def __addcoor2(self, ptlistplus, aflist, tagclosed): coorlist = [] for i in range(-self.L, -1 + tagclosed): deltas = distance(self[i], self[i + 1]) s = self.__calcufirstS(ptlistplus) + self.calcuS(i) scorrect = 0 #用于处理闭合曲线最后一边的弦长问题 s2 = s k = 0 for k in range(0, 20): #用k控制s u = (s - s2) / deltas wl = (1 - u)**2 * (1 + 2 * u) wr = u**2 * (3 - 2 * u) pl = APoint( aflist[i][0] + aflist[i][1] * s + aflist[i][2] * s * s, aflist[i][3] + aflist[i][4] * s + aflist[i][5] * s * s) pr = APoint( aflist[i + 1][0] + aflist[i + 1][1] * s + aflist[i + 1][2] * s * s, aflist[i + 1][3] + aflist[i + 1][4] * s + aflist[i + 1][5] * s * s) if i == -1: pr = APoint( aflist[i + 1][0] + aflist[i + 1][1] * scorrect + aflist[i + 1][2] * scorrect * scorrect, aflist[i + 1][3] + aflist[i + 1][4] * scorrect + aflist[i + 1][5] * scorrect * scorrect) coorlist.append((wl * pl + wr * pr)[0]) coorlist.append((wl * pl + wr * pr)[1]) s += 0.05 * deltas scorrect += 0.05 * deltas coorlist.append(ptlistplus[self.L + tagclosed][0]) coorlist.append(ptlistplus[self.L + tagclosed][1]) return coorlist
def GrahamScan(self): vertex = [self.__findinitial()] lst = list(range(self.L)) lst.remove(vertex[0]) #剩余点序 anglelist = dict( zip(lst, [Vector(self[vertex[0]], self[i]).angle() for i in lst])) #剩余点序的angle lst.sort(key=lambda i: anglelist[i]) #将剩余点序按angle的从小到大排列 filterlist = [[lst[0]]] #将angle相同的剩余点序归类 for i in range(1, len(lst)): if anglelist[lst[i]] == anglelist[lst[i - 1]]: filterlist[-1].append(lst[i]) else: filterlist.append([lst[i]]) lst = [] for item in filterlist: #每类中只有一个元素即取该元素,每类中有多个元素取到p0最远的元素 if len(item) == 1: lst.append(item[0]) else: t = max(item, key=lambda i: distance(self[i], self[vertex[0]])) lst.append(t) vertex.append(lst[0]) vertex.append(lst[1]) for i in range(2, len(lst)): while Vector(self[vertex[-2]], self[vertex[-1]]).side( self[lst[i]]) != -1: vertex.pop() vertex.append(lst[i]) map1 = map(lambda i: self[i], vertex) return toLightWeightPolyline(map1)
def __circ_index(self, poi, r): """ 返回在以po为圆心,以r为半径内的点的序号,不含本身 """ ilist = [] d = 0 for i in range(0, self.L): d = distance(self[poi], self[i]) if d <= r and d: ilist.append(i) return ilist
def __rollnext(self, vertex, circ, r): """ r为每个点的搜索半径 """ def __keyangle(i): vec1 = Vector(self[vertex[-1]], self[vertex[-2]]) vec2 = Vector(self[vertex[-1]], self[i]) return vec1.angle(vec2) alpha = r / 2 #r为圆半径 if len(vertex) == 1: for i in circ: p1 = self[vertex[-1]] p2 = self[i] center = Vector(p1, p2).dist_intersect(alpha, alpha) #作圆 for j in circ: #对circ中的其他点 if j != i: if distance(self[j], center) < alpha: break else: return i, center raise ValueError("没找到下一点,请扩大半径") else: if len(circ) == 2: if circ[0] == vertex[-2]: return circ[1], center return circ[0], center else: circ.sort(key=__keyangle) #对圆中点排序 p1 = self[vertex[-1]] for i in circ: if i != vertex[-2]: p2 = self[i] center = Vector(p1, p2).dist_intersect(alpha, alpha) for j in circ: if j != i: if distance(self[j], center) < alpha: break else: return i, center raise ValueError("没找到下一点,请扩大半径")
def calcuS(self, n, ptlist=None): """ 计算n号点到0号点的累计弦长,如果ptlist为空,则计算self的累计弦长 """ sums = 0 if ptlist == None: ptlist = self if n < 0: n = n + len(ptlist) for i in range(0, n): sums += distance(ptlist[i], ptlist[i + 1]) return sums
def GetLongestDiagonalLine(self): """ 得到最长对角线起点和终点的坐标,长度 """ diagonal = [] length = self.L for j in range(2, length // 2 + 1): for i in range(length): s = distance(self[i], self[i + j - length]) diagonal.append((i, i + j - length, s)) diagonal.sort(key=lambda x: x[2]) longest = diagonal.pop() return self[longest[0]], self[longest[1]], longest[2]
def CalcuParam(ptlist,thetalist,tagclosed): pqlist=[]#排列方式[[p0 p1 p2 p3 q0 q1 q2 q3],...] for i in range(-len(ptlist),tagclosed-1): r=distance(ptlist[i],ptlist[i+1]) para=[] para.append(ptlist[i][0]) para.append(r*thetalist[i][0]) para.append(3*(ptlist[i+1][0]-ptlist[i][0])-r*(thetalist[i+1][0]+2*thetalist[i][0])) para.append(-2*(ptlist[i+1][0]-ptlist[i][0])+r*(thetalist[i+1][0]+thetalist[i][0])) para.append(ptlist[i][1]) para.append(r*thetalist[i][1]) para.append(3*(ptlist[i+1][1]-ptlist[i][1])-r*(thetalist[i+1][1]+2*thetalist[i][1])) para.append(-2*(ptlist[i+1][1]-ptlist[i][1])+r*(thetalist[i+1][1]+thetalist[i][1])) pqlist.append(para) return pqlist
def __calcuparam(self, thetalist, tagclosed): pqlist = [] # 排列方式[[p0 p1 p2 p3 q0 q1 q2 q3],...] for i in range(-len(self), tagclosed - 1): r = distance(self[i], self[i + 1]) para = [] para.append(self[i][0]) para.append(r * thetalist[i][0]) para.append(3 * (self[i + 1][0] - self[i][0]) - r * (thetalist[i + 1][0] + 2 * thetalist[i][0])) para.append(-2 * (self[i + 1][0] - self[i][0]) + r * (thetalist[i + 1][0] + thetalist[i][0])) para.append(self[i][1]) para.append(r * thetalist[i][1]) para.append(3 * (self[i + 1][1] - self[i][1]) - r * (thetalist[i + 1][1] + 2 * thetalist[i][1])) para.append(-2 * (self[i + 1][1] - self[i][1]) + r * (thetalist[i + 1][1] + thetalist[i][1])) pqlist.append(para) return pqlist
def norm(self): return distance(self, APoint(0, 0, 0))
def GetEdgeLength(self): edgelist = [] for i in range(-self.L, 0): edgelist.append((distance(self[i], self[i + 1]))) return edgelist
def distance_to(self, apoint: APoint): lenlist = [] for item in self: lenlist.append(distance(item, apoint)) return lenlist
def __calcufirstS(self, ptlistplus): return distance(ptlistplus[0], ptlistplus[1])