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
Example #2
0
    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 []
Example #4
0
 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
Example #9
0
 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
Example #10
0
 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]
         ]
Example #21
0
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
Example #24
0
 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
Example #26
0
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)