def slideNeighbor(self,poly,_type): print("检索类型",_type,"...") self.break_points_list=[] self.t_lists=[] self.getBreakPointList(self.horizontal_positive,self.slide_horizontal_positive,_type,-1) self.getBreakPointList(self.horizontal_negative,self.slide_horizontal_negative,_type,-1) self.getBreakPointList(self.horizontal_positive,self.slide_horizontal_negative,_type,1) self.getBreakPointList(self.horizontal_negative,self.slide_horizontal_positive,_type,1) # 计算面积的最合适位置 self.t_lists=self.chooseFeasible(self.t_lists,_type) self.t_lists=self.deleteDuplicated(self.t_lists) min_area_t=self.overlapCompare() print("min_area_t:",min_area_t) if abs(min_area_t)<precision_error: print("0 未检索到更优位置") return False # 进行平移位置 if _type=="vertical": GeoFunc.slidePoly(self.cur_polys[self.max_miu_index],0,min_area_t) else: GeoFunc.slidePoly(self.cur_polys[self.max_miu_index],min_area_t,0) # 更新PolyList、正负边、重合情况 self.updatePolyList() self.updateEdgesPN() print("1 检索到更优位置") self.showResult(current=True) return True
def placePoly(self, index): adjoin = self.polygons[index] # 是否垂直 if self.vertical == True: ifr = packing.PackingUtil.getInnerFitRectangle( self.polygons[index], self.width, self.length) else: ifr = packing.PackingUtil.getInnerFitRectangle( self.polygons[index], self.length, self.width) differ_region = Polygon(ifr) for main_index in range(0, index): main = self.polygons[main_index] if self.NFPAssistant == None: nfp = NFP(main, adjoin).nfp else: nfp = self.NFPAssistant.getDirectNFP(main, adjoin) nfp_poly = Polygon(nfp) try: differ_region = differ_region.difference(nfp_poly) except: print('NFP failure, areas of polygons are:') self.showAll() for poly in main, adjoin: print(Polygon(poly).area) self.showPolys([main] + [adjoin] + [nfp]) print('NFP loaded from: ', self.NFPAssistant.history_path) differ = GeoFunc.polyToArr(differ_region) differ_index = self.getBottomLeft(differ) refer_pt_index = GeoFunc.checkTop(adjoin) GeoFunc.slideToPoint(self.polygons[index], adjoin[refer_pt_index], differ[differ_index])
def intersection(line1,line2): # 如果可以直接计算出交点 Line1=LineString(line1) Line2=LineString(line2) inter=Line1.intersection(Line2) if inter.is_empty==False: mapping_inter=mapping(inter) if mapping_inter["type"]=="LineString": inter_coor=mapping_inter["coordinates"][0] else: inter_coor=mapping_inter["coordinates"] return inter_coor # 对照所有顶点是否相同 res=[] for pt1 in line1: for pt2 in line2: if GeoFunc.almostEqual(pt1,pt2)==True: # print("pt1,pt2:",pt1,pt2) res=pt1 if res!=[]: return res # 计算是否存在almostContain for pt in line1: if GeoFunc.almostContain(line2,pt)==True: return pt for pt in line2: if GeoFunc.almostContain(line1,pt)==True: return pt return []
def processRegion(region): area = [] if region.geom_type == "Polygon": area = GeoFunc.polyToArr(region) # 最终结果只和顶点相关 else: for shapely_item in list(region): if shapely_item.area > bias: area = area + GeoFunc.polyToArr(shapely_item) return area
def shrink(self): self.new_height = self.height*0.95 print("收缩边界%s" % self.new_height) for poly in self.cur_polys: top_index = GeoFunc.checkTop(poly) delta = self.new_height-poly[top_index][1] # 如果有重叠就平移 if delta < 0: GeoFunc.slidePoly(poly,0,delta) self.updatePolyList()
def getInnerFitRectangle(poly,x,y): left_index,bottom_index,right_index,top_index=GeoFunc.checkBound(poly) # 获得边界 new_poly=GeoFunc.getSlide(poly,-poly[left_index][0],-poly[bottom_index][1]) # 获得平移后的结果 refer_pt=[new_poly[top_index][0],new_poly[top_index][1]] ifr_width=x-new_poly[right_index][0] ifr_height=y-new_poly[top_index][1] IFR=[refer_pt,[refer_pt[0]+ifr_width,refer_pt[1]],[refer_pt[0]+ifr_width,refer_pt[1]+ifr_height],[refer_pt[0],refer_pt[1]+ifr_height]] return IFR
def run(self): self.cur_polys.append(GeoFunc.getSlide(self.polys[0], 1000, 1000)) # 加入第一个形状 self.border_left, self.border_right, self.border_bottom, self.border_top = 0, 0, 0, 0 # 初始化包络长方形 self.border_height, self.border_width = 0, 0 for i in range(1, len(self.polys)): # 更新所有的边界情况 self.updateBound() # 计算NFP的合并情况 feasible_border = Polygon(self.cur_polys[0]) for fixed_poly in self.cur_polys: nfp = self.NFPAssistant.getDirectNFP(fixed_poly, self.polys[i]) feasible_border = feasible_border.union(Polygon(nfp)) # 获得所有可行的点 feasible_point = self.chooseFeasiblePoint(feasible_border) # 获得形状的左右侧宽度 poly_left_pt, poly_bottom_pt, poly_right_pt, poly_top_pt = GeoFunc.checkBoundPt( self.polys[i]) poly_left_width, poly_right_width = poly_top_pt[0] - poly_left_pt[ 0], poly_right_pt[0] - poly_top_pt[0] # 逐一遍历NFP上的点,选择可行且宽度变化最小的位置 min_change = 999999999999 target_position = [] for pt in feasible_point: change = min_change if pt[0] - poly_left_width >= self.border_left and pt[ 0] + poly_right_width <= self.border_right: # 形状没有超出边界,此时min_change为负 change = min(self.border_left - pt[0], self.border_left - pt[0]) elif min_change > 0: # 形状超出了左侧或右侧边界,若变化大于0,则需要选择左右侧变化更大的值 change = max(self.border_left - pt[0] + poly_left_width, pt[0] + poly_right_width - self.border_right) else: # 有超出且min_change<=0的时候不需要改变 pass if change < min_change: min_change = change target_position = pt # 平移到最终的位置 reference_point = self.polys[i][GeoFunc.checkTop(self.polys[i])] self.cur_polys.append( GeoFunc.getSlide(self.polys[i], target_position[0] - reference_point[0], target_position[1] - reference_point[1])) self.slideToBottomLeft() self.showResult()
def feasibleVector(self,all_vectors,touching_edges): ''' 该段代码需要重构,过于复杂 ''' res_vector=[] # print("\nall_vectors:",all_vectors) for vector in all_vectors: feasible=True # print("\nvector:",vector,"\n") for touching in touching_edges: vector1=[] vector2=[] # 判断方向并进行转向 if touching["stationary_start"]==True: vector1=touching["vector1"] else: vector1=[-touching["vector1"][0],-touching["vector1"][1]] if touching["orbiting_start"]==True: vector2=touching["vector2"] else: vector2=[-touching["vector2"][0],-touching["vector2"][1]] vector12_product=GeoFunc.crossProduct(vector1,vector2) # 叉积,大于0在左侧,小于0在右侧,等于0平行 vector_vector1_product=GeoFunc.crossProduct(vector1,vector) # 叉积,大于0在左侧,小于0在右侧,等于0平行 vector_vector2_product=GeoFunc.crossProduct(vector2,vector) # 叉积,大于0在左侧,小于0在右侧,等于0平行 # 最后两种情况 if touching["type"]==4 and (vector_vector1_product*vector12_product)<0: feasible=False if touching["type"]==5 and (vector_vector2_product*(-vector12_product))>0: feasible=False # 正常的情况处理 if vector12_product>0: if vector_vector1_product<0 and vector_vector2_product<0: feasible=False if vector12_product<0: if vector_vector1_product>0 and vector_vector2_product>0: feasible=False # 平行情况,需要用原值逐一判断 if vector12_product==0: inter=GeoFunc.newLineInter(touching["edge1"],touching["edge2"]) if inter["geom_type"]=="LineString": if inter["length"]>0.01: # 如果有相交,则需要在左侧 if (touching["orbiting_start"]==True and vector_vector2_product<0) or (touching["orbiting_start"]==False and vector_vector2_product>0): feasible=False else: # 如果方向相同,且转化直线也平行,则其不能够取a的方向 if touching["orbiting_start"]==True != touching["stationary_start"]==False and vector_vector1_product==0: if touching["vector1"][0]*vector[0]>0: # 即方向相同 feasible=False if feasible==True: res_vector=vector break return res_vector
def getLength(self): _max = 0 for i in range(0, len(self.polygons)): if self.vertical == True: extreme_index = GeoFunc.checkTop(self.polygons[i]) extreme = self.polygons[i][extreme_index][1] else: extreme_index = GeoFunc.checkRight(self.polygons[i]) extreme = self.polygons[i][extreme_index][0] if extreme > _max: _max = extreme self.contain_length = _max # PltFunc.addLine([[0,self.contain_length],[self.width,self.contain_length]],color="blue") return _max
def testGCS(self): # polygons=[] # polygons.append(self.getTestPolys()[0]) # polygons.append(self.getTestPolys()[1]) polygons=self.getTestPolys() num = 1 # 形状收缩 for poly in polygons: for ver in poly: ver[0] = ver[0]*num ver[1] = ver[1]*num gcs = GCS(polygons) GeoFunc.slidePoly(polygons[0], 500, 500) gcs.showAll() gcs.GuidedCuckooSearch(1500, 10) gcs.showAll()
def extendInter(line1,line2): ''' 获得延长线的交点 ''' line1_extend=GeoFunc.extendLine(line1) line2_extend=GeoFunc.extendLine(line2) # 排查平行情况 k1=GeoFunc.getArc(line1_extend) k2=GeoFunc.getArc(line2_extend) if abs(k1-k2)<0.01: return [line1[1][0],line1[1][1]] inter=mapping(LineString(line1_extend).intersection(LineString(line2_extend))) if inter["type"]=="GeometryCollection" or inter["type"]=="LineString": return [line1[1][0],line1[1][1]] return [inter["coordinates"][0],inter["coordinates"][1]]
def pointLineDistance(point, line): point_x = point[0] point_y = point[1] line_s_x = line[0][0] line_s_y = line[0][1] line_e_x = line[1][0] line_e_y = line[1][1] if line_e_x - line_s_x == 0: return abs(point_x - line_s_x),[line_s_x-point_x,0] if line_e_y - line_s_y == 0: return abs(point_y - line_s_y),[0,line_s_y-point_y] k = (line_e_y - line_s_y) / (line_e_x - line_s_x) extend_line=[[point_x-1000,point_y-1000*(-1/k)],[point_x+1000,point_y+1000*(-1/k)]] inter=LineString(line).intersection(LineString(extend_line)) if inter.is_empty==True: dis1=math.pow((point_x-line_s_x)*(point_x-line_s_x)+(point_y-line_s_y)*(point_y-line_s_y), 0.5) dis2=math.pow((point_x-line_e_x)*(point_x-line_e_x)+(point_y-line_e_y)*(point_y-line_e_y), 0.5) if dis1>dis2: return dis2,[line_e_x-point_x,line_e_y-point_y] else: return dis1,[line_s_x-point_x,line_s_y-point_y] else: pt=GeoFunc.getPt(inter) dis=math.pow((point_x-pt[0])*(point_x-pt[0])+(point_y-pt[1])*(point_y-pt[1]), 0.5) return dis,[pt[0]-point[0],pt[1]-point[1]]
def getTargetEdges(self): self.target_edges = [[0] * len(self.polys) for _ in range(len(self.polys))] for i in range(len(self.polys)): for j in range(len(self.polys)): if i == j: continue nfp = self.getNFP(i, j) nfp_edges = GeoFunc.getPolyEdges(nfp) point = self.PLACEMENTPOINT[j] if Polygon(nfp).contains( Point(point)) and self._type == "separation": # 如果包含且是拆分,则寻找距离最近的那个 min_distance = 99999999999999 for edge in nfp_edges: left_distance = -self.getRightDistance(edge, point) if left_distance <= min_distance: min_distance = left_distance self.target_edges[i][j] = copy.deepcopy(edge) else: # 如果不包含或者是压缩,则选择最远的 max_distance = -0.00001 for edge in nfp_edges: right_distance = self.getRightDistance(edge, point) if right_distance >= max_distance: max_distance = right_distance self.target_edges[i][j] = copy.deepcopy(edge)
def updatePolyList(self): self.poly_list=[] for i,poly in enumerate(self.cur_polys): edges=GeoFunc.getPolyEdges(poly) poly_item={ "index":i, "pts":poly, "edges":edges, "horizontal":{ "positive":[], "negative":[], "neutral":[] }, "vertical":{ "positive":[], "negative":[], "neutral":[] }, } for edge in edges: netural=self.judgeNeutral(poly,edge) # 分别获得水平和垂直的计算结果 for i,cur in enumerate(["horizontal","vertical"]): if netural[i]==1: poly_item[cur]["positive"].append([edge[0],edge[1]]) elif netural[i]==-1: poly_item[cur]["negative"].append([edge[0],edge[1]]) else: poly_item[cur]["neutral"].append([edge[0],edge[1]]) self.poly_list.append(poly_item)
def getAllNFP(self): nfp_multi=False if nfp_multi==True: tasks=[(main,adjoin) for main in self.polys for adjoin in self.polys] res=pool.starmap(NFP,tasks) for k,item in enumerate(res): i=k//len(self.polys) j=k%len(self.polys) self.nfp_list[i][j]=GeoFunc.getSlide(item.nfp,-self.centroid_list[i][0],-self.centroid_list[i][1]) else: for i,poly1 in enumerate(self.polys): for j,poly2 in enumerate(self.polys): nfp=NFP(poly1,poly2).nfp #NFP(poly1,poly2).showResult() self.nfp_list[i][j]=GeoFunc.getSlide(nfp,-self.centroid_list[i][0],-self.centroid_list[i][1]) if self.store_nfp==True: self.storeNFP()
def detectTouching(self): touch_edges=[] stationary_edges,sliding_edges=self.getAllEdges() for edge1 in stationary_edges: for edge2 in sliding_edges: inter=GeoFunc.intersection(edge1,edge2) if inter!=[]: pt=[inter[0],inter[1]] # 交叉点 edge1_bound=(GeoFunc.almostEqual(edge1[0],pt) or GeoFunc.almostEqual(edge1[1],pt)) # 是否为边界 edge2_bound=(GeoFunc.almostEqual(edge2[0],pt) or GeoFunc.almostEqual(edge2[1],pt)) # 是否为边界 stationary_start=GeoFunc.almostEqual(edge1[0],pt) # 是否开始 orbiting_start=GeoFunc.almostEqual(edge2[0],pt) # 是否开始 touch_edges.append({ "edge1":edge1, "edge2":edge2, "vector1":self.edgeToVector(edge1), "vector2":self.edgeToVector(edge2), "edge1_bound":edge1_bound, "edge2_bound":edge2_bound, "stationary_start":stationary_start, "orbiting_start":orbiting_start, "pt":[inter[0],inter[1]], "type":0 }) return touch_edges
def __init__(self,polys,**kw): self.polys=PolyListProcessor.deleteRedundancy(copy.deepcopy(polys)) self.area_list,self.first_vec_list,self.centroid_list=[],[],[] # 作为参考 for poly in self.polys: P=Polygon(poly) self.centroid_list.append(GeoFunc.getPt(P.centroid)) self.area_list.append(int(P.area)) self.first_vec_list.append([poly[1][0]-poly[0][0],poly[1][1]-poly[0][1]]) self.nfp_list=[[0]*len(self.polys) for i in range(len(self.polys))] self.load_history=False self.history_path=None self.history=None if 'history_path' in kw: self.history_path=kw['history_path'] if 'load_history' in kw: if kw['load_history']==True: # 从内存中加载history 直接传递pandas的df对象 缩短I/O时间 if 'history' in kw: self.history=kw['history'] self.load_history=True self.loadHistory() self.store_nfp=False if 'store_nfp' in kw: if kw['store_nfp']==True: self.store_nfp=True self.store_path=None if 'store_path' in kw: self.store_path=kw['store_path'] if 'get_all_nfp' in kw: if kw['get_all_nfp']==True and self.load_history==False: self.getAllNFP() if 'fast' in kw: # 为BLF进行多进程优化 if kw['fast']==True: self.res=[[0]*len(self.polys) for i in range(len(self.polys))] #pool=Pool() for i in range(1,len(self.polys)): for j in range(0,i): # 计算nfp(j,i) #self.res[j][i]=pool.apply_async(getNFP,args=(self.polys[j],self.polys[i])) self.nfp_list[j][i]=GeoFunc.getSlide(getNFP(self.polys[j],self.polys[i]),-self.centroid_list[j][0],-self.centroid_list[j][1])
def getNFP(self, j, i): # j是固定位置,i是移动位置 row = j * 192 + i * 16 + self.poly_status[j][2] * 4 + self.poly_status[ i][2] bottom_pt = LPAssistant.getBottomPoint(self.polys[j]) delta_x, delta_y = bottom_pt[0], bottom_pt[1] nfp = GeoFunc.getSlide(json.loads(self.all_nfp["nfp"][row]), delta_x, delta_y) return nfp
def main(self): i=0 if self.rectangle: # 若矩形则直接快速运算 点的index为左下角开始逆时针旋转 width=self.sliding[1][0]-self.sliding[0][0] height=self.sliding[3][1]-self.sliding[0][1] self.nfp.append([self.stationary[0][0],self.stationary[0][1]]) self.nfp.append([self.stationary[1][0]+width,self.stationary[1][1]]) self.nfp.append([self.stationary[2][0]+width,self.stationary[2][1]+height]) self.nfp.append([self.stationary[3][0],self.stationary[3][1]+height]) else: while self.judgeEnd()==False and i<75: # 大于等于75会自动退出的,一般情况是计算出错 # while i<7: # print("########第",i,"轮##########") touching_edges=self.detectTouching() all_vectors=self.potentialVector(touching_edges) if len(all_vectors)==0: print("没有可行向量") self.error=-2 # 没有可行向量 break vector=self.feasibleVector(all_vectors,touching_edges) if vector==[]: print("没有计算出可行向量") self.error=-5 # 没有计算出可行向量 break self.trimVector(vector) if vector==[0,0]: print("未进行移动") self.error=-3 # 未进行移动 break GeoFunc.slidePoly(self.sliding,vector[0],vector[1]) self.nfp.append([self.sliding[self.locus_index][0],self.sliding[self.locus_index][1]]) i=i+1 inter=Polygon(self.sliding).intersection(Polygon(self.stationary)) if GeoFunc.computeInterArea(inter)>1: print("出现相交区域") self.error=-4 # 出现相交区域 break if i==75: print("超出计算次数") self.error=-1 # 超出计算次数
def getResult(self, placement_points): self.final_polys, self.final_poly_status = [], copy.deepcopy( self.poly_status) for i, poly in enumerate(self.polys): self.final_polys.append( GeoFunc.getSlide(poly, placement_points[i][0] - self.Xi[i], placement_points[i][1] - self.Yi[i])) self.final_poly_status[i][1] = [ placement_points[i][0], placement_points[i][1] ]
def getData(index): '''报错数据集有(空心):han,jakobs1,jakobs2 ''' '''形状过多暂时未处理:shapes、shirt、swim、trousers''' name = [ "ga", "albano", "blaz1", "blaz2", "dighe1", "dighe2", "fu", "han", "jakobs1", "jakobs2", "mao", "marques", "shapes", "shirts", "swim", "trousers" ] print("开始处理", name[index], "数据集") '''暂时没有考虑宽度,全部缩放来表示''' scale = [100, 0.5, 100, 100, 20, 20, 20, 10, 20, 20, 0.5, 20, 50] print("缩放", scale[index], "倍") df = pd.read_csv("data/" + name[index] + ".csv") polygons = [] for i in range(0, df.shape[0]): for j in range(0, df['num'][i]): poly = json.loads(df['polygon'][i]) GeoFunc.normData(poly, scale[index]) polygons.append(poly) return polygons
def getDirectNFP(self,poly1,poly2,**kw): if 'index' in kw: i=kw['index'][0] j=kw['index'][1] centroid=GeoFunc.getPt(Polygon(self.polys[i]).centroid) else: # 首先获得poly1和poly2的ID i=self.getPolyIndex(poly1) j=self.getPolyIndex(poly2) centroid=GeoFunc.getPt(Polygon(poly1).centroid) # 判断是否计算过并计算nfp if self.nfp_list[i][j]==0: nfp=NFP(poly1,poly2).nfp #self.nfp_list[i][j]=GeoFunc.getSlide(nfp,-centroid[0],-centroid[1]) if self.store_nfp==True: with open("record/nfp.csv","a+") as csvfile: writer = csv.writer(csvfile) writer.writerows([[poly1,poly2,nfp]]) return nfp else: return GeoFunc.getSlide(self.nfp_list[i][j],centroid[0],centroid[1])
def similarPoly(poly): ''' 求解凸多边形的近似多边形,凹多边形内凹部分额外处理 ''' change_len=10 extend_poly=poly+poly Poly=Polygon(poly) new_edges=[] # 计算直线平移 for i in range(len(poly)): line=[extend_poly[i],extend_poly[i+1]] new_line=GeoFunc.slideOutLine(line,Poly,change_len) new_edges.append(new_line) # 计算直线延长线 new_poly=[] new_edges.append(new_edges[0]) for i in range(len(new_edges)-1): inter=GeoFunc.extendInter(new_edges[i],new_edges[i+1]) new_poly.append(inter) GeoFunc.twoDec(new_poly) return new_poly
def MinimizeOverlap(self, oris, v, o): ''' oris: 允许旋转的角度集合 v: 多边形位置 实际已通过self.polygons得到 o: 旋转的角度 后期可考虑把多边形封装成类 ''' n_polys = self.n_polys it = 0 fitness = 999999 while it < self.n_mo: Q = np.random.permutation(range(n_polys)) for i in range(n_polys): curPoly = self.polygons[Q[i]] # 记录原始位置 top_index = GeoFunc.checkTop(curPoly) top = list(curPoly[top_index]) F = self.evaluate(Q[i]) # 以后考虑旋转 print('F of',Q[i],':',F) v_i = self.CuckooSearch(Q[i]) self.evaluate(Q[i], v_i) F_new = v_i.getF() print('new F of',Q[i],':',F) if F_new < F: print('polygon', Q[i], v_i.getXY()) else: # 平移回原位置 GeoFunc.slideToPoint(curPoly, curPoly[top_index], top) fitness_new = self.evaluateAll() if fitness_new == 0: return it # 可行解 elif fitness_new < fitness: fitness = fitness_new it = 0 self.updatePenalty() it = it+1 return it
def updateBound(self): ''' 更新包络长方形 ''' border_left, border_bottom, border_right, border_top = GeoFunc.checkBoundValue( self.cur_polys[-1]) if border_left < self.border_left: self.border_left = border_left if border_bottom < self.border_bottom: self.border_bottom = border_bottom if border_right > self.border_right: self.border_right = border_right if border_top > self.border_top: self.border_top = border_top self.border_height = self.border_top - self.border_bottom self.border_width = self.border_right - self.border_left
def tryNFP(): df = pd.read_csv("data/blaz1.csv") poly1 = json.loads(df['polygon'][1]) poly2 = json.loads(df['polygon'][4]) GeoFunc.normData(poly1, 50) GeoFunc.normData(poly2, 50) GeoFunc.slidePoly(poly1, 500, 500) nfp = NFP(poly1, poly2, show=True) print(nfp.nfp)
def potentialVector(self,touching_edges): all_vectors=[] for touching in touching_edges: # print("touching:",touching) aim_edge=[] # 情况1 if touching["edge1_bound"]==True and touching["edge2_bound"]==True: right,left,parallel=GeoFunc.judgePosition(touching["edge1"],touching["edge2"]) # print("right,left,parallel:",right,left,parallel) if touching["stationary_start"]==True and touching["orbiting_start"]==True: touching["type"]=0 if left==True: aim_edge=[touching["edge2"][1],touching["edge2"][0]] # 反方向 if right==True: aim_edge=touching["edge1"] if touching["stationary_start"]==True and touching["orbiting_start"]==False: touching["type"]=1 if left==True: aim_edge=touching["edge1"] if touching["stationary_start"]==False and touching["orbiting_start"]==True: touching["type"]=2 if right==True: aim_edge=[touching["edge2"][1],touching["edge2"][0]] # 反方向 if touching["stationary_start"]==False and touching["orbiting_start"]==False: touching["type"]=3 # 情况2 if touching["edge1_bound"]==False and touching["edge2_bound"]==True: aim_edge=[touching["pt"],touching["edge1"][1]] touching["type"]=4 # 情况3 if touching["edge1_bound"]==True and touching["edge2_bound"]==False: aim_edge=[touching["edge2"][1],touching["pt"]] touching["type"]=5 if aim_edge!=[]: vector=self.edgeToVector(aim_edge) if self.detectExisting(all_vectors,vector)==False: # 删除重复的向量降低计算复杂度 all_vectors.append(vector) return all_vectors
def updateSearchStatus(self): # 计算重叠情况 self.overlap_pair=[[0]*len(self.cur_polys) for i in range(len(self.cur_polys))] self.overlap_each=[0 for i in range(len(self.cur_polys))] for i in range(0,len(self.cur_polys)-1): for j in range(i+1,len(self.cur_polys)): Pi=Polygon(self.cur_polys[i]) Pj=Polygon(self.cur_polys[j]) overlap_area=GeoFunc.computeInterArea(Pi.intersection(Pj)) if overlap_area>precision_error: self.overlap_pair[i][j]=self.overlap_pair[i][j]+overlap_area self.overlap_pair[j][i]=self.overlap_pair[i][j] self.overlap_each[i]=self.overlap_each[i]+overlap_area self.overlap_each[j]=self.overlap_each[j]+overlap_area # 更新是否重叠 self.overlap=False for area in self.overlap_each: if area>0: self.overlap=True # 计算对应的Miu max_miu_pair=0 self.max_miu_pair_indx=[0,0] for i in range(0,len(self.cur_polys)): for j in range(0,len(self.cur_polys)): miu=self.overlap_pair[i][j]/(1+self.phi[i][j]) self.miu_each[i]=self.miu_each[i]+miu if miu>max_miu_pair: self.max_miu_pair_indx=[i,j] # 获得最大的Miu值 self.max_miu=0 self.max_miu_index=-1 for index,miu in enumerate(self.miu_each): if miu>self.max_miu: self.max_miu=miu self.max_miu_index=index
def getBreakPoints(self,edge,slide_edge,_type): int_type=0 if _type=="vertical": int_type=1 # 两条直线四个组合计算 break_points=[] self.getSlideT(slide_edge[0],edge,int_type,1,break_points) self.getSlideT(slide_edge[1],edge,int_type,1,break_points) self.getSlideT(edge[0],slide_edge,int_type,-1,break_points) self.getSlideT(edge[1],slide_edge,int_type,-1,break_points) # 必须是有两个交点 if len(break_points)<2: return print(break_points) break_points=self.deleteDuplicated(break_points) # 开始计算具体参数 t1=min(break_points[0],break_points[1]) t2=max(break_points[0],break_points[1]) sliding_result1=GeoFunc.getSlideLine(slide_edge,t1,0) sliding_result2=GeoFunc.getSlideLine(slide_edge,t2,0) if _type=="vertical": sliding_result1=GeoFunc.getSlideLine(slide_edge,0,t1) sliding_result2=GeoFunc.getSlideLine(slide_edge,0,t2) pt1=GeoFunc.intersection(sliding_result1,edge) # 可能为Tuple pt2=GeoFunc.intersection(sliding_result2,edge) # 可能为Tuple pt3=self.getHoriVerInter(pt1,sliding_result2,int_type) ratio=(LineString([pt1,pt2]).length)/(t2-t1) # 两条边的比例 sin_theta=abs(pt1[1-int_type]-pt2[1-int_type])/(LineString([pt1,pt2]).length) # 直线与水平的角度 A1=0.5*ratio*sin_theta B1=-2*t1*A1 C1=t1*t1*A1 # 计算A2 B2 C2 A2=0 B2=abs(pt1[1-int_type]-pt2[1-int_type]) # 平行四边形的高度 C2=Polygon([pt1,pt2,pt3]).area-B2*t2 # 三角形面积 return [[t1,A1,B1,C1],[t2,0,B2,C2]]
def __init__(self,poly1,poly2,**kw): self.stationary=copy.deepcopy(poly1) self.sliding=copy.deepcopy(poly2) start_point_index=GeoFunc.checkBottom(self.stationary) self.start_point=[poly1[start_point_index][0],poly1[start_point_index][1]] self.locus_index=GeoFunc.checkTop(self.sliding) # 如果不加list则original_top是指针 self.original_top=list(self.sliding[self.locus_index]) GeoFunc.slideToPoint(self.sliding,self.sliding[self.locus_index],self.start_point) self.start=True # 判断是否初始 self.nfp=[] self.rectangle=False if 'rectangle' in kw: if kw["rectangle"]==True: self.rectangle=True self.error=1 self.main() if 'show' in kw: if kw["show"]==True: self.showResult() # 计算完成之后平移回原始位置 GeoFunc.slideToPoint(self.sliding,self.sliding[self.locus_index],self.original_top)