def plot(self): ''' plot obstacles from the world Example ------- >>> from pylayers.simul.simulnet import * >>> S=Simul() >>> S.the_world.plot() ''' X = self._obstacles xv = X.values() tahe = [] for i in range(len(xv)): for u in range(len(xv[i])): tahe.append(xv[i][u]) tahe = np.array(tahe) ta = tahe[:, 0, :] he = tahe[:, 1, :] plu.displot(ta.T, he.T)
def plot(self): ''' plot obstacles from the world Example ------- >>> from pylayers.simul.simulnet import * >>> S=Simul() >>> S.the_world.plot() ''' X = self._obstacles xv = X.values() tahe = [] for i in range(len(xv)): for u in range(len(xv[i])): tahe.append(xv[i][u]) tahe=np.array(tahe) ta = tahe[:, 0, :] he = tahe[:, 1, :] plu.displot(ta.T,he.T)
def new_state(self): """ layout editor state machine Parameters ---------- 'l' : select activelayer 'i' : back to init state 'j' : vertical and horizontal scaling 'e' : edit segment 'b' : edit segment keyboard 'CTRL + t' : translate structure 'h' : add subsegment 'd | Del' : delete subsegment 'r | F5' : refresh 'o' : toggle overlay (<> CP mode) set origin (CP mode) 'm' : toggle mode (point or segment) 'n' : toggle node label display 'z' : change display parameters 'CTRL+q' : quit 'x | CTRL+s' : save .str2 and .ini file 'w' : display all layers 'v' : flip layout w.r.t y axis 'f' : toggle points nodes display 'g' : toggle segments nodes display '=' : increment layer '$' : decrement layer """ fig = plt.gcf() ax = plt.gca() sl = self.L.sl cold = pyu.coldict() #print "In State ",self.state #print "In Event ",self.evt # # flip layout in y # if self.evt == ',': for k in self.ddoc.keys(): print k,self.ddoc[k] if self.evt == 'v': for n in self.L.Gs.pos: self.L.Gs.pos[n]=(self.L.Gs.pos[n][0],-self.L.Gs.pos[n][1]) self.update_state() return # # translation of layout (open a box) # # if self.evt == 't' : # offx,offy = offsetbox() # for n in self.L.Gs.pos: # self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]+offx,self.L.Gs.pos[n][1]+offy) # self.update_state() # return if self.evt=='escape': self.state='Init' self.update_state() self.fig.canvas.draw() return if self.evt=='ctrl+z': self.bundo=True print len(self.L.Gs) if len (self.undoGs) >2: oGs=self.undoGs.pop(-1) oGs=self.undoGs.pop(-1) self.L.Gs=oGs self.L.g2npy() self.update_state() self.bundo=False return if self.evt=='t': if 'SM' in self.state: self.update_state() # fig=plt.gcf() # ax=plt.gca() if self.selected == 'pt': self.plotselptseg(self.selectseg,color='r') PP=self.L.pt[:,self.L.tahe[:,self.L.tgs[self.selectseg]]] if PP.shape[-1]!=0: self.fig,self.ax=plu.displot(PP[:,0],PP[:,1],fig=self.fig,ax=self.ax,color='r',linewidth=3,alpha=0.4) plt.draw() self.selected='seg' self.state='SMS' else: self.fig,self.ax= self.plotselptseg(self.selectpt) self.selected='pt' self.state='SMP' self.ax.title.set_text(self.statename[self.state]) # self.update_state() if self.evt == '3': self.L._show3() return # Choose layers to visualized # if self.evt == 'l': listchoices = self.L.name.keys() self.L.display['layers'] = multchoicebox('message', 'titre', listchoices) self.state = 'Init' self.update_state() return # # 'f' toggle points nodes display # if self.evt=='f': self.L.display['nodes'] = not self.L.display['nodes'] print self.L.display['nodes'] self.update_state() return # # 'g' toggle segment nodes dislay # if self.evt=='g': self.L.display['ednodes'] = not self.L.display['ednodes'] print self.L.display['ednodes'] self.update_state() return # # '=' Increment layer # if self.evt=='=': N = len(self.L.display['layerset']) index = self.L.display['layerset'].index(self.L.display['activelayer']) self.L.display['activelayer'] = self.L.display['layerset'][(index+1) % N] self.current_layer = self.L.display['activelayer'] print self.current_layer self.update_state() return # # '=' Decrement layer # if self.evt=='$': N = len(self.L.display['layerset']) index = self.L.display['layerset'].index(self.L.display['activelayer']) self.L.display['activelayer'] = self.L.display['layerset'][(index-1) % N] self.current_layer = self.L.display['activelayer'] self.update_state() return # # 'i' : Back to init state # if self.evt == 'i': self.state = 'Init' self.update_state() return # # 'e' # if state == Init # egalize points coordinates # # if state == SS # edit segment properties # if self.evt == 'e': if (self.state == 'Init'): # # averaging one point coordinate along the smallest dimension # x1 = self.ax.get_xbound() y1 = self.ax.get_ybound() # get node list and edge list ndlist, edlist = self.L.get_zone([x1[0],x1[1],y1[0],y1[1]]) for k,nd in enumerate(ndlist): try: tp = np.vstack((tp,np.array(self.L.Gs.pos[nd]))) except: tp = np.array(self.L.Gs.pos[nd]) mtp = np.sum(tp,axis=0)/(k+1) stp = np.sqrt(np.sum((tp-mtp)*(tp-mtp),axis=0)/(k+1)) # if the standard deviation is lower than 10cm # averaging coordinates along the shortest axis if min(stp) < 0.10: ind = np.where(stp==min(stp))[0][0] for nd in ndlist: x = self.L.Gs.pos[nd][0] y = self.L.Gs.pos[nd][1] if ind ==0: self.L.Gs.pos[nd]=(mtp[0],y) if ind ==1: self.L.Gs.pos[nd]=(x,mtp[1]) plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return() if (self.state == 'SS') | (self.state =='SSS'): self.L.edit_segment(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SP1': self.L.edit_point(self.selected_pt1) self.state = 'Init' self.update_state() return if self.state == 'SMS': outdata=self.L.edit_segment(self.selectseg[0]) [self.L.edit_segment(s,outdata=outdata,gui=False) for s in self.selectseg] self.update_state() return # # "b" : enter a segment node value with keyboard # if self.evt == 'b': if self.state == 'Init': self.nsel = eval(raw_input("seg number :")) #self.L.edit_segment(nseg) self.state='SS' self.update_state() return # # j : vertical and horizontal scaling (Init) # if self.evt == 'j': if self.state == 'Init': vscale,hscale = offsetbox(text1='Enter scaling values', text2=('vscale','hscale'), default=('1.0','1.0') ) for n in self.L.Gs.pos: self.L.Gs.pos[n]=(self.L.Gs.pos[n][0],self.L.Gs.pos[n][1]*vscale) plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return # Init # h : horizontal scaling factor # add subsegment (SS) # if self.evt == 'h': # if self.state == 'Init': # hscale = eval(raw_input("horizontal scaling factor : ")) # for n in self.L.Gs.pos: # self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]*hscale,self.L.Gs.pos[n][1]) # plt.axis('tight') # fig,ax = self.show(fig,ax,clear=True) # self.update_state() # return() if self.state == 'SS': result = self.L.add_subseg(self.selected_edge1,self.current_layer) if result: self.state = 'SSS' else : self.state = 'Init' self.update_state() return # # d : delete # if self.evt == 'd' or self.evt =='delete': if self.state == 'SP1': self.state = 'Init' self.L.del_points(self.selected_pt1) self.update_state() return if self.state == 'SS': self.L.del_segment(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SSS': self.L.del_subseg(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state=='SMP': # get boundary of the region if hasattr(self,'selectpt'): ptlist = self.selectpt self.selectpt=[] self.selectseg=[] self.L.del_points(ptlist) self.state = 'Init' self.update_state() return else : print 'no selected region' if self.state=='SMS': seglist = self.selectseg self.selectpt=[] self.selectseg=[] self.L.del_segment(seglist) self.state = 'Init' self.update_state() return else : print 'no selected region' # # r : Refresh # if self.evt == 'r' or self.evt == 'f5': #plt.axis('tight') plt.axis(self.L.display['box']) self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.state = 'Init' self.update_state() return # # o : Toggle overlay # if self.evt == 'o' and not self.ctrl_is_held: self.state='Init' self.update_state() if self.L.display['overlay']: self.L.display['overlay'] = False self.update_state() else: self.L.display['overlay'] = True self.update_state() return if self.evt == 'o' : self.set_origin = True if self.evt == 'f2': self.state = "CP" self.update_state() return # # m : Toggle mode edition Point | Segment # if self.evt == 'm': if self.state == "Init": self.state = "CP" elif self.state == "CP": self.state = "Init" self.update_state() return # # 'z' : change display parameters # if self.evt == 'z': self.L.displaygui() self.fig,self.ax = self.show(fig=self.fig,ax=self.ax,clear=True) return # # 'q' : quit interactive mode # # if self.evt == 'q': # plt.rcParams.update(self.rcconf) # fig.canvas.mpl_disconnect(self.L.cid1) # fig.canvas.mpl_disconnect(self.L.cid2) # return if self.evt == 'ctrl+q': plt.rcParams.update(self.rcconf) self.fig.canvas.mpl_disconnect(self.L.cid1) self.fig.canvas.mpl_disconnect(self.L.cid2) plt.close() return # # 'x' save structure # if self.evt == 'x' or self.evt =='ctrl+s': racine, ext = os.path.splitext(self.L.filename) filename = racine + '.str2' fileini = racine + '.ini' # Commented because ss_ce not updated #self.L.savestr2(filename) self.L.saveini(fileini) print "structure saved in ", filename print "structure saved in ", fileini return # # 'n' : toggle node label display # if self.evt == 'n': self.L.display['ndlabel'] = not self.L.display['ndlabel'] self.L.display['edlabel'] = not self.L.display['edlabel'] print self.L.display['activelayer'] self.fig,ax = self.show(fig=self.fig,ax=self.ax,clear=True) self.fig.canvas.draw() return # # "w" : display all layers # if self.evt == 'w': # display all layer self.L.display['activelayer'] = self.L.name.keys() print self.L.display['activelayer'] self.fig,self.ax = self.show(fig=self.fig,ax=self.ax,clear=True) return self.fig,self.ax # # Left clic and selected node is a point # if (self.evt == 'lclic') & (self.nsel < 0): # # select point 1 : Init -> SP1 # if self.state=='Init': # yellow point self.state = 'SP1' self.update_state() return # # select point 2 : SP1 --> SP2 # if self.state=='SP1': if self.nsel != self.selected_pt1: # green point self.state = 'SP2' self.update_state() return else: self.state = 'Init' # yellow point self.update_state() return # # Create point on selected segment orthogonaly to segment starting in # selected point # # Not finished # if self.state=='SS': # get the connection of the selected segment connect = self.L.Gs.node[self.selected_edge1]['connect'] if (self.nsel != connect[0]) & (self.nsel != connect[1]): self.L.add_nfpe(self.nsel,self.nsel,self.selected_edge1,self.selected_edge2) pass # # Left clic and selected node is a segment # if (self.evt == 'lclic') & (self.nsel > 0): if self.state=='Init': self.state = 'SS' self.update_state() return if self.state=='SS': self.nsel = self.selected_edge1 segdico = self.L.Gs.node[self.nsel] if 'ss_name' in segdico: self.state = 'SSS' else: self.state = 'CPS' self.update_state() return # # Right clic and selected node is a point # if (self.evt == 'rclic') & (self.nsel < 0): if self.state=='SP1': if self.nsel==self.selected_pt1: self.state = 'Init' self.update_state() return # # Right clic and selected node is a segment # if (self.evt == 'rclic') & (self.nsel > 0): if self.state=='SS': self.state = 'Init' self.update_state() return if self.state=='SSS': self.state = 'SS' self.update_state() return if self.state == 'CP': # create point on edge self.state = 'CPS' self.update_state() return if (self.state == 'CPS') & (self.nsel!= self.selected_edge1): # create point on edge self.state = 'CPSS' self.update_state() return # # Left clic # if (self.evt == 'lclic') and not (self.shift_is_held or self.alt_is_held or self.ctrl_is_held ): # add free node # or set origin if self.state == 'CP': if self.set_origin: offx = self.ptsel[0] offy = self.ptsel[1] print offx,offy xmin,xmax,ymin,ymax = self.L.display['box'] self.L.display['box'] = [xmin-offx,xmax-offx,ymin-offy,ymax-offy] self.set_origin=False self.set_x=True plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return if self.set_x: offx = self.ptsel[0] val = eval(enterbox('enter x value')) ratio = val/offx print ratio xmin,xmax,ymin,ymax = self.L.display['box'] self.L.display['box'] = [ratio*xmin,ratio*xmax,ymin,ymax] self.set_x=False self.set_y=True plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return if self.set_y: offx = self.ptsel[1] val = eval(enterbox('enter y value')) ratio = val/offx print ratio xmin,xmax,ymin,ymax = self.L.display['box'] self.L.display['box'] = [xmin,xmax,ratio*ymin,ratio*ymax] self.set_y=False plt.axis('tight') self.fig,self.ax = self.show(self.fig,self.ax,clear=True) self.update_state() return else: self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return if self.state == 'SP2': ta = self.selected_pt1 he = self.selected_pt2 segexist = self.L.isseg(ta,he) print segexist # if segment do not already exist, create it if not segexist: self.nsel = self.L.add_segment(ta, he,name=self.current_layer) else: print "segment ("+str(ta)+","+str(he)+") already exists" self.L.g2npy() self.state = 'Init' self.update_state() return # create point on segment if self.state == 'CPS': pt_new = geu.ptonseg(self.pta1, self.phe1, self.ptsel) pd1 = pt_new - self.pta1 pd2 = self.phe1 - self.pta1 alpha = np.sqrt(np.dot(pd1, pd1)) / np.sqrt(np.dot(pd2, pd2)) if (pt_new != []): # calculate alpha self.L.add_pons(self.selected_edge1, 1. - alpha) self.current_layer = self.L.Gs.node[self.selected_edge1]['name'] self.state = 'Init' self.update_state() return # # Right Clic event # if (self.evt == 'rclic') or (self.evt == 'lclic' and self.ctrl_is_held ): if self.state == 'CP': try: self.ptsel[0] = self.pt_previous[0] self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return except: return if self.state=='SP2': if self.nsel == self.selected_pt1: self.p1[0].set_visible(False) self.p2[0].set_visible(False) self.nsel = self.selected_pt2 self.state = 'SP1' self.update_state() return if self.nsel == self.selected_pt2: self.p1[0].set_visible(False) self.p2[0].set_visible(False) self.nsel = self.selected_pt1 self.state = 'SP1' self.update_state() return # # right click : back to SS from CPS # if self.state == 'CPS': self.state = 'SS' self.update_state() return # # right click : back to CPS from CPSS # if self.state == 'CPSS': self.state = 'CPS' self.update_state(self.fig,self.ax) return # # Center Clic event # if (self.evt == 'cclic') or (self.evt == 'lclic' and self.shift_is_held ): if self.state == 'CP': try: self.ptsel[1] = self.pt_previous[1] self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return except: return # # Left clic and selected node is a point # def point_select_callback(eclick, erelease): 'eclick and erelease are the press and release events' self.update_state() if not (self.shift_is_held or self.ctrl_is_held): self.selectpt=[] self.selectseg=[] x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata # print x1,x2,y1,y2 if x1>x2: x1,x2=x2,x1 if y1>y2: y1,y2=y2,y1 # try: selectpt,selectseg = self.L.get_zone([x1,x2,y1,y2]) if not self.ctrl_is_held: self.selectpt.extend(selectpt) self.selectseg.extend(selectseg) self.selectseg=filter(lambda x: self.L.Gs.node[x]['connect'][0] in self.selectpt and self.L.Gs.node[x]['connect'][1] in self.selectpt, self.selectseg) self.selectpt=np.unique(self.selectpt).tolist() self.selectseg=np.unique(self.selectseg).tolist() else: [self.selectpt.pop(self.selectpt.index(x)) for x in selectpt if x in self.selectpt] [self.selectseg.pop(self.selectseg.index(x)) for x in selectseg if x in self.selectseg] # except: # print 'empty selection' print self.selectpt,self.selectseg self.plotselptseg(self.selectpt) self.selected='pt' print self.state def toggle_selector(event): if toggle_selector.RS.active: toggle_selector.RS.set_active(False) if not toggle_selector.RS.active: toggle_selector.RS.set_active(True) if self.evt == 'f1': # avoid conflict between zoom and selection # fm=plt.get_current_fig_manager() # if fm.toolbar._active == 'PAN': # fm.toolbar.pan() # if fm.toolbar._active == 'ZOOM': # fm.toolbar.zoom() self.state='SMP' toggle_selector.RS = RectangleSelector(self.ax, point_select_callback, drawtype='box', useblit=True, button=[1,3], # don't use middle button minspanx=5, minspany=5, spancoords='pixels') self.selector = toggle_selector.RS self.update_state() if self.evt == 'f9': print self.selectpt, self.selectseg
def belong_seg(self, pta, phe, prob=True, visu=False): """ test if segment belong to cone Parameters ---------- pta : np.array (2xNseg) phe : np.array (2xNseg) Returns ------- typ : int 0 : no visibility 1 : full visibility 2 : he.v 3 : ta.v 4 : ta.u 5 : he.u 6 : inside proba : float geometric probability Notes ----- A segment belongs to the cone if not all termination points lie in the same side outside the cone. See Also -------- outside_point """ if visu: f, a = self.show() plu.displot(pta, phe, fig=f, ax=a) plt.show() vc = (self.u + self.v) / 2 #vcn = vc/np.sqrt(np.dot(vc,vc)) w = vc / np.sqrt(np.dot(vc, vc)) w = w.reshape(2, 1) #w = np.array([vcn[1],-vcn[0]]) ptama = pta - self.apex[:, None] phema = phe - self.apex[:, None] dtaw = np.sum(ptama * w, axis=0) dhew = np.sum(phema * w, axis=0) blta = (dtaw >= 0) blhe = (dhew >= 0) #if 'seg1' in self.__dict__: # pa = self.seg1[:,0].reshape(2,1) # pb = (self.seg1[:,0]+w).reshape(2,1) #else: # pa = self.apex.reshape(2,1) # pb = pa+w.reshape(2,1) #blta = geu.isleft(pa,pb,pta) #blhe = geu.isleft(pa,pb,phe) # segment candidate for being above segment 1 (,Nseg) boup = blta & blhe # type of segment if prob: proba = np.zeros(np.shape(pta)[1]) else: proba = [] typ = np.zeros(np.shape(pta)[1]) # is tail out ? bo1 | bo2 # btaol : boolean tail out left # btaor : boolean tail out right # bheol : boolean head out left # bheor : boolean head out right # # among upper segment check position wrt cone #btaol,btaor = self.outside_point(pta) #bheol,bheor = self.outside_point(phe) btaor, btaol = self.outside_point(pta) bheor, bheol = self.outside_point(phe) # tail and head are they out cone on the same side ? # if the two termination points are not on the same side of the cone # --> segment is in. # boin = (~((btaol&bheol)|(btaor&bheor)))&boup # full interception (proba to reach = 1) bfull = ((btaol & bheor) | (btaor & bheol)) & boup if prob: proba[bfull] = 1 typ[bfull] = 1 #(he-apex).v btalhein = (btaol & ~bheol & ~bheor) & boup if (prob and not (btalhein == False).all()): v2 = phe[:, btalhein] - self.apex.reshape(2, 1) vn2 = v2 / np.sqrt(np.sum(v2 * v2, axis=0)) vvn2 = np.dot(self.v, vn2) # paranoid verification of scalar product \in [-1,1] vvn2 = np.minimum(vvn2, np.ones(len(vvn2))) vvn2 = np.maximum(vvn2, -np.ones(len(vvn2))) pr2 = np.arccos(vvn2) / self.angle proba[btalhein] = pr2 typ[btalhein] = 2 #(tai-apex).v bheltain = (bheol & ~btaol & ~btaor) & boup if (prob and not (bheltain == False).all()): v3 = pta[:, bheltain] - self.apex.reshape(2, 1) vn3 = v3 / np.sqrt(np.sum(v3 * v3, axis=0)) vvn3 = np.dot(self.v, vn3) vvn3 = np.minimum(vvn3, np.ones(len(vvn3))) vvn3 = np.maximum(vvn3, -np.ones(len(vvn3))) pr3 = np.arccos(vvn3) / self.angle proba[bheltain] = pr3 typ[bheltain] = 3 #ta.u bhertain = (bheor & ~btaol & ~btaor) & boup if (prob and not (bhertain == False).all()): v4 = pta[:, bhertain] - self.apex.reshape(2, 1) vn4 = v4 / np.sqrt(np.sum(v4 * v4, axis=0)) vvn4 = np.dot(self.u, vn4) vvn4 = np.minimum(vvn4, np.ones(len(vvn4))) vvn4 = np.maximum(vvn4, -np.ones(len(vvn4))) pr4 = np.arccos(vvn4) / self.angle proba[bhertain] = pr4 typ[bhertain] = 4 #he.u btarhein = (btaor & ~bheol & ~bheor) & boup if (prob and not (btarhein == False).all()): v5 = phe[:, btarhein] - self.apex.reshape(2, 1) vn5 = v5 / np.sqrt(np.sum(v5 * v5, axis=0)) vvn5 = np.dot(self.u, vn5) vvn5 = np.minimum(vvn5, np.ones(len(vvn5))) vvn5 = np.maximum(vvn5, -np.ones(len(vvn5))) pr5 = np.arccos(vvn5) / self.angle proba[btarhein] = pr5 typ[btarhein] = 5 #ta.he btainhein = (~btaol & ~btaor & ~bheol & ~bheor) & boup if (prob and not (btainhein == 0).all()): va = pta[:, btainhein] - self.apex.reshape(2, 1) vb = phe[:, btainhein] - self.apex.reshape(2, 1) vna = va / np.sqrt(np.sum(va * va, axis=0)) vnb = vb / np.sqrt(np.sum(vb * vb, axis=0)) # dot product vna,vnb vnab = np.sum(vna * vnb, axis=0) vnab = np.minimum(vnab, np.ones(len(vnab))) vnab = np.maximum(vnab, -np.ones(len(vnab))) pr6 = np.arccos(vnab) / self.angle proba[btainhein] = pr6 typ[btainhein] = 6 return (typ, proba)
def new_state(self): """ layout editor state machine Parameters ---------- 'l' : select activelayer 'i' : back to init state 'j' : vertical and horizontal scaling 'e' : edit segment 'b' : edit segment keyboard 'CTRL + t' : translate structure 'h' : add subsegment 'd |Del' : delete subsegment 'r |F5' : refresh 'o' : toggle overlay (<> CP mode) set origin (CP mode) 'm' : toggle mode (point or segment) 'n' : toggle node label display 'z' : change display parameters 'CTRL+q' : quit 'x |CTRL+s' : save .str2 and .ini file 'w' : display all layers 'v' : flip layout w.r.t y axis 'f' : toggle points nodes display 'g' : toggle segments nodes display '=' : increment layer '$' : decrement layer """ fig = plt.gcf() ax = plt.gca() sl = self.L.sl cold = pyu.coldict() #print "In State ",self.state #print "In Event ",self.evt # # flip layout in y # if self.evt == ',': for k in self.ddoc.keys(): print(k, self.ddoc[k]) if self.evt == 'v': for n in self.L.Gs.pos: self.L.Gs.pos[n] = (self.L.Gs.pos[n][0], -self.L.Gs.pos[n][1]) self.update_state() return # # translation of layout (open a box) # # if self.evt == 't' : # offx,offy = offsetbox() # for n in self.L.Gs.pos: # self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]+offx,self.L.Gs.pos[n][1]+offy) # self.update_state() # return if self.evt == 'escape': self.state = 'Init' self.update_state() self.fig.canvas.draw() return if self.evt == 'ctrl+z': self.bundo = True print(len(self.L.Gs)) if len(self.undoGs) > 2: oGs = self.undoGs.pop(-1) oGs = self.undoGs.pop(-1) self.L.Gs = oGs self.L.g2npy() self.update_state() self.bundo = False return if self.evt == 't': if 'SM' in self.state: self.update_state() # fig=plt.gcf() # ax=plt.gca() if self.selected == 'pt': self.plotselptseg(self.selectseg, color='r') PP = self.L.pt[:, self.L.tahe[:, self.L.tgs[self.selectseg]]] if PP.shape[-1] != 0: self.fig, self.ax = plu.displot(PP[:, 0], PP[:, 1], fig=self.fig, ax=self.ax, color='r', linewidth=3, alpha=0.4) plt.draw() self.selected = 'seg' self.state = 'SMS' else: self.fig, self.ax = self.plotselptseg(self.selectpt) self.selected = 'pt' self.state = 'SMP' self.ax.title.set_text(self.statename[self.state]) # self.update_state() if self.evt == '3': self.L._show3() return # Choose layers to visualized # if self.evt == 'l': listchoices = self.L.name.keys() self.L.display['layers'] = multchoicebox('message', 'titre', listchoices) self.state = 'Init' self.update_state() return # # 'f' toggle points nodes display # if self.evt == 'f': self.L.display['nodes'] = not self.L.display['nodes'] print(self.L.display['nodes']) self.update_state() return # # 'g' toggle segment nodes dislay # if self.evt == 'g': self.L.display['ednodes'] = not self.L.display['ednodes'] print(self.L.display['ednodes']) self.update_state() return # # '=' Increment layer # if self.evt == '=': N = len(self.L.display['layerset']) index = self.L.display['layerset'].index( self.L.display['activelayer']) self.L.display['activelayer'] = self.L.display['layerset'][(index + 1) % N] self.current_layer = self.L.display['activelayer'] print(self.current_layer) self.update_state() return # # '=' Decrement layer # if self.evt == '$': N = len(self.L.display['layerset']) index = self.L.display['layerset'].index( self.L.display['activelayer']) self.L.display['activelayer'] = self.L.display['layerset'][(index - 1) % N] self.current_layer = self.L.display['activelayer'] print(self.current_layer) self.update_state() return # # 'i' : Back to init state # if self.evt == 'i': self.state = 'Init' self.update_state() return # # 'e' # if state == Init # egalize points coordinates # # if state == SS # edit segment properties # if self.evt == 'e': if (self.state == 'Init'): # # averaging one point coordinate along the smallest dimension # x1 = self.ax.get_xbound() y1 = self.ax.get_ybound() # get node list and edge list ndlist, edlist = self.L.get_zone([x1[0], x1[1], y1[0], y1[1]]) for k, nd in enumerate(ndlist): try: tp = np.vstack((tp, np.array(self.L.Gs.pos[nd]))) except: tp = np.array(self.L.Gs.pos[nd]) mtp = np.sum(tp, axis=0) / (k + 1) stp = np.sqrt( np.sum((tp - mtp) * (tp - mtp), axis=0) / (k + 1)) # if the standard deviation is lower than 10cm # averaging coordinates along the shortest axis if min(stp) < 0.10: ind = np.where(stp == min(stp))[0][0] for nd in ndlist: x = self.L.Gs.pos[nd][0] y = self.L.Gs.pos[nd][1] if ind == 0: self.L.Gs.pos[nd] = (mtp[0], y) if ind == 1: self.L.Gs.pos[nd] = (x, mtp[1]) plt.axis('tight') self.fig, self.ax = self.show(self.fig, self.ax, clear=True) self.update_state() return () if (self.state == 'SS') | (self.state == 'SSS'): self.L.edit_segment(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SP1': self.L.edit_point(self.selected_pt1) self.state = 'Init' self.update_state() return if self.state == 'SMS': outdata = self.L.edit_segment(self.selectseg[0]) [ self.L.edit_segment(s, outdata=outdata, gui=False) for s in self.selectseg ] self.update_state() return # # "b" : enter a segment node value with keyboard # if self.evt == 'b': if self.state == 'Init': self.nsel = eval(raw_input("seg number :")) #self.L.edit_segment(nseg) self.state = 'SS' self.update_state() return # # j : vertical and horizontal scaling (Init) # if self.evt == 'j': if self.state == 'Init': vscale = eval(enterbox('enter vscale', argDefaultText='1.0')) hscale = eval(enterbox('enter hscale', argDefaultText='1.0')) for n in self.L.Gs.pos: self.L.Gs.pos[n] = (self.L.Gs.pos[n][0] * hscale, self.L.Gs.pos[n][1] * vscale) plt.axis('tight') self.fig, self.ax = self.show(self.fig, self.ax, clear=True) self.update_state() return # Init # h : horizontal scaling factor # add subsegment (SS) # if self.evt == 'h': # if self.state == 'Init': # hscale = eval(raw_input("horizontal scaling factor : ")) # for n in self.L.Gs.pos: # self.L.Gs.pos[n]=(self.L.Gs.pos[n][0]*hscale,self.L.Gs.pos[n][1]) # plt.axis('tight') # fig,ax = self.show(fig,ax,clear=True) # self.update_state() # return() if self.state == 'SS': result = self.L.add_subseg(self.selected_edge1, self.current_layer) if result: self.state = 'SSS' else: self.state = 'Init' self.update_state() return # # d : delete # if self.evt == 'd' or self.evt == 'delete': if self.state == 'SP1': self.state = 'Init' self.L.del_points(self.selected_pt1) self.update_state() return if self.state == 'SS': self.L.del_segment(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SSS': self.L.del_subseg(self.selected_edge1) self.state = 'Init' self.update_state() return if self.state == 'SMP': # get boundary of the region if hasattr(self, 'selectpt'): ptlist = self.selectpt self.selectpt = [] self.selectseg = [] self.L.del_points(ptlist) self.state = 'Init' self.update_state() return else: print('no selected region') if self.state == 'SMS': seglist = self.selectseg self.selectpt = [] self.selectseg = [] self.L.del_segment(seglist) self.state = 'Init' self.update_state() return else: print('no selected region') # # r : Refresh # if self.evt == 'r' or self.evt == 'f5': #plt.axis('tight') plt.axis(self.L.display['box']) self.fig, self.ax = self.show(self.fig, self.ax, clear=True) self.state = 'Init' self.update_state() return # # o : Toggle overlay # if self.evt == 'o' and not self.ctrl_is_held: self.state = 'Init' self.update_state() if self.L.display['overlay']: self.L.display['overlay'] = False self.update_state() else: self.L.display['overlay'] = True self.update_state() return if self.evt == 'o': self.set_origin = True # # F2 : Create point # if self.evt == 'f2': self.state = "CP" self.update_state() return # # m : Toggle mode edition Point | Segment # if self.evt == 'm': if self.state == "Init": self.state = "CP" elif self.state == "CP": self.state = "Init" self.update_state() return # # 'z' : change display parameters # if self.evt == 'z': self.L.displaygui() self.fig, self.ax = self.show(fig=self.fig, ax=self.ax, clear=True) return # # 'q' : quit interactive mode # # if self.evt == 'q': # plt.rcParams.update(self.rcconf) # fig.canvas.mpl_disconnect(self.L.cid1) # fig.canvas.mpl_disconnect(self.L.cid2) # return if self.evt == 'ctrl+q': plt.rcParams.update(self.rcconf) self.fig.canvas.mpl_disconnect(self.L.cid1) self.fig.canvas.mpl_disconnect(self.L.cid2) plt.close() return # # 'x' save structure # if self.evt == 'x' or self.evt == 'ctrl+s': racine, ext = os.path.splitext(self.L.filename) filename = racine + '.str2' fileini = racine + '.ini' # Commented because ss_ce not updated #self.L.savestr2(filename) self.L.saveini(fileini) print("structure saved in ", filename) print("structure saved in ", fileini) return # # 'n' : toggle node label display # if self.evt == 'n': self.L.display['ndlabel'] = not self.L.display['ndlabel'] self.L.display['edlabel'] = not self.L.display['edlabel'] print(self.L.display['activelayer']) self.fig, ax = self.show(fig=self.fig, ax=self.ax, clear=True) self.fig.canvas.draw() return # # "w" : display all layers # if self.evt == 'w': # display all layer self.L.display['activelayer'] = self.L.name.keys() print(self.L.display['activelayer']) self.fig, self.ax = self.show(fig=self.fig, ax=self.ax, clear=True) return self.fig, self.ax # # Left clic and selected node is a point # if (self.evt == 'lclic') & (self.nsel < 0): # # select point 1 : Init -> SP1 # if self.state == 'Init': # yellow point self.state = 'SP1' self.update_state() return # # select point 2 : SP1 --> SP2 # if self.state == 'SP1': if self.nsel != self.selected_pt1: # green point self.state = 'SP2' self.update_state() return else: self.state = 'Init' # yellow point self.update_state() return # # Create point on selected segment orthogonaly to segment starting in # selected point # # Not finished # if self.state == 'SS': # get the connection of the selected segment connect = self.L.Gs.node[self.selected_edge1]['connect'] if (self.nsel != connect[0]) & (self.nsel != connect[1]): self.L.add_nfpe(self.nsel, self.nsel, self.selected_edge1, self.selected_edge2) pass # # Left clic and selected node is a segment # if (self.evt == 'lclic') & (self.nsel > 0): if self.state == 'Init': self.state = 'SS' self.update_state() return if self.state == 'SS': self.nsel = self.selected_edge1 segdico = self.L.Gs.node[self.nsel] if 'ss_name' in segdico: self.state = 'SSS' else: self.state = 'CPS' self.update_state() return # # Right clic and selected node is a point # if (self.evt == 'rclic') & (self.nsel < 0): if self.state == 'SP1': if self.nsel == self.selected_pt1: self.state = 'Init' self.update_state() return # # Right clic and selected node is a segment # if (self.evt == 'rclic') & (self.nsel > 0): if self.state == 'SS': self.state = 'Init' self.update_state() return if self.state == 'SSS': self.state = 'SS' self.update_state() return if self.state == 'CP': # create point on edge self.state = 'CPS' self.update_state() return if (self.state == 'CPS') & (self.nsel != self.selected_edge1): # create point on edge self.state = 'CPSS' self.update_state() return # # Left clic # if (self.evt == 'lclic') and not (self.shift_is_held or self.alt_is_held or self.ctrl_is_held): # add free node # or set origin if self.state == 'CP': if self.set_origin: offx = self.ptsel[0] offy = self.ptsel[1] print(offx, offy) xmin, xmax, ymin, ymax = self.L.display['box'] self.L.display['box'] = [ xmin - offx, xmax - offx, ymin - offy, ymax - offy ] self.set_origin = False self.set_x = True plt.axis('tight') self.fig, self.ax = self.show(self.fig, self.ax, clear=True) self.update_state() return if self.set_x: offx = self.ptsel[0] val = eval(enterbox('enter x value')) ratio = val / offx print(ratio) xmin, xmax, ymin, ymax = self.L.display['box'] self.L.display['box'] = [ ratio * xmin, ratio * xmax, ymin, ymax ] self.set_x = False self.set_y = True plt.axis('tight') self.fig, self.ax = self.show(self.fig, self.ax, clear=True) self.update_state() return if self.set_y: offx = self.ptsel[1] val = eval(enterbox('enter y value')) ratio = val / offx print(ratio) xmin, xmax, ymin, ymax = self.L.display['box'] self.L.display['box'] = [ xmin, xmax, ratio * ymin, ratio * ymax ] self.set_y = False plt.axis('tight') self.fig, self.ax = self.show(self.fig, self.ax, clear=True) self.update_state() return else: self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return if self.state == 'SP2': ta = self.selected_pt1 he = self.selected_pt2 segexist = self.L.isseg(ta, he) print(segexist) # if segment do not already exist, create it if not segexist: self.nsel = self.L.add_segment(ta, he, name=self.current_layer) else: print("segment (" + str(ta) + "," + str(he) + ") already exists") self.L.g2npy() self.state = 'Init' self.update_state() return # create point on segment if self.state == 'CPS': pt_new = geu.ptonseg(self.pta1, self.phe1, self.ptsel) pd1 = pt_new - self.pta1 pd2 = self.phe1 - self.pta1 alpha = np.sqrt(np.dot(pd1, pd1)) / np.sqrt(np.dot(pd2, pd2)) if (pt_new != []): # calculate alpha self.L.add_pons(self.selected_edge1, 1. - alpha) self.current_layer = self.L.Gs.node[ self.selected_edge1]['name'] self.state = 'Init' self.update_state() return # # Right Clic event # if (self.evt == 'rclic') or (self.evt == 'lclic' and self.ctrl_is_held): if self.state == 'CP': try: self.ptsel[0] = self.pt_previous[0] self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return except: return if self.state == 'SP2': if self.nsel == self.selected_pt1: self.p1[0].set_visible(False) self.p2[0].set_visible(False) self.nsel = self.selected_pt2 self.state = 'SP1' self.update_state() return if self.nsel == self.selected_pt2: self.p1[0].set_visible(False) self.p2[0].set_visible(False) self.nsel = self.selected_pt1 self.state = 'SP1' self.update_state() return # # right click : back to SS from CPS # if self.state == 'CPS': self.state = 'SS' self.update_state() return # # right click : back to CPS from CPSS # if self.state == 'CPSS': self.state = 'CPS' self.update_state(self.fig, self.ax) return # # Center Clic event # if (self.evt == 'cclic') or (self.evt == 'lclic' and self.shift_is_held): if self.state == 'CP': try: self.ptsel[1] = self.pt_previous[1] self.L.add_fnod(tuple(self.ptsel)) self.pt_previous = self.ptsel self.update_state() return except: return # # Left clic and selected node is a point # def point_select_callback(eclick, erelease): 'eclick and erelease are the press and release events' self.update_state() if not (self.shift_is_held or self.ctrl_is_held): self.selectpt = [] self.selectseg = [] x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata # print x1,x2,y1,y2 if x1 > x2: x1, x2 = x2, x1 if y1 > y2: y1, y2 = y2, y1 # try: selectpt, selectseg = self.L.get_zone([x1, x2, y1, y2]) if not self.ctrl_is_held: self.selectpt.extend(selectpt) self.selectseg.extend(selectseg) self.selectseg = filter( lambda x: self.L.Gs.node[x]['connect'][0] in self.selectpt and self.L.Gs.node[x]['connect'][1] in self.selectpt, self.selectseg) self.selectpt = np.unique(self.selectpt).tolist() self.selectseg = np.unique(self.selectseg).tolist() else: [ self.selectpt.pop(self.selectpt.index(x)) for x in selectpt if x in self.selectpt ] [ self.selectseg.pop(self.selectseg.index(x)) for x in selectseg if x in self.selectseg ] # except: # print 'empty selection' print(self.selectpt, self.selectseg) self.plotselptseg(self.selectpt) self.selected = 'pt' print(self.state) def toggle_selector(event): if toggle_selector.RS.active: toggle_selector.RS.set_active(False) if not toggle_selector.RS.active: toggle_selector.RS.set_active(True) if self.evt == 'f1': #avoid conflict between zoom and selection # fm=plt.get_current_fig_manager() # if fm.toolbar._active == 'PAN': # fm.toolbar.pan() # if fm.toolbar._active == 'ZOOM': # fm.toolbar.zoom() self.state = 'SMP' toggle_selector.RS = RectangleSelector( self.ax, point_select_callback, drawtype='box', useblit=True, button=[1, 3], # don't use middle button minspanx=5, minspany=5, spancoords='pixels') self.selector = toggle_selector.RS self.update_state() if self.evt == 'f9': print(self.selectpt, self.selectseg)
def belong_seg(self,pta,phe,prob=True,visu=False): """ test if segment belong to cone Parameters ---------- pta : np.array (2xNseg) phe : np.array (2xNseg) Returns ------- typ : int 0 : no visibility 1 : full visibility 2 : he.v 3 : ta.v 4 : ta.u 5 : he.u 6 : inside proba : float geometric probability Notes ----- A segment belongs to the cone if not all termination points lie in the same side outside the cone. See Also -------- outside_point """ if visu: f,a = self.show() plu.displot(pta,phe,fig=f,ax=a) plt.show() vc = (self.u+self.v)/2 #vcn = vc/np.sqrt(np.dot(vc,vc)) w = vc/np.sqrt(np.dot(vc,vc)) w = w.reshape(2,1) #w = np.array([vcn[1],-vcn[0]]) ptama = pta - self.apex[:,None] phema = phe - self.apex[:,None] dtaw = np.sum(ptama*w,axis=0) dhew = np.sum(phema*w,axis=0) blta = (dtaw>=0)|(np.isclose(dtaw,0.)) blhe = (dhew>=0)|(np.isclose(dhew,0.)) #if 'seg1' in self.__dict__: # pa = self.seg1[:,0].reshape(2,1) # pb = (self.seg1[:,0]+w).reshape(2,1) #else: # pa = self.apex.reshape(2,1) # pb = pa+w.reshape(2,1) #blta = geu.isleft(pa,pb,pta) #blhe = geu.isleft(pa,pb,phe) # segment candidate for being above segment 1 (,Nseg) boup = blta & blhe # type of segment if prob: proba = np.zeros(np.shape(pta)[1]) else : proba =[] typ = np.zeros(np.shape(pta)[1]) # is tail out ? bo1 | bo2 # btaol : boolean tail out left # btaor : boolean tail out right # bheol : boolean head out left # bheor : boolean head out right # # among upper segment check position wrt cone #btaol,btaor = self.outside_point(pta) #bheol,bheor = self.outside_point(phe) btaor,btaol = self.outside_point(pta) bheor,bheol = self.outside_point(phe) # tail and head are they out cone on the same side ? # if the two termination points are not on the same side of the cone # --> segment is in. # boin = (~((btaol&bheol)|(btaor&bheor)))&boup # full interception (proba to reach = 1) bfull = ((btaol&bheor)|(btaor&bheol))&boup if prob : proba[bfull] = 1 typ[bfull] = 1 #(he-apex).v btalhein = (btaol & ~bheol & ~bheor)&boup if (prob and not (btalhein==False).all()): v2 = phe[:,btalhein]-self.apex.reshape(2,1) vn2 = v2/np.sqrt(np.sum(v2*v2,axis=0)) vvn2 = np.dot(self.v,vn2) # paranoid verification of scalar product \in [-1,1] vvn2 = np.minimum(vvn2,np.ones(len(vvn2))) vvn2 = np.maximum(vvn2,-np.ones(len(vvn2))) pr2 = np.arccos(vvn2)/self.angle proba[btalhein] = pr2 typ[btalhein] = 2 #(ta-apex).v bheltain = (bheol & ~btaol & ~btaor)&boup if (prob and not (bheltain==False).all()): v3 = pta[:,bheltain]-self.apex.reshape(2,1) vn3 = v3/np.sqrt(np.sum(v3*v3,axis=0)) vvn3 = np.dot(self.v,vn3) vvn3 = np.minimum(vvn3,np.ones(len(vvn3))) vvn3 = np.maximum(vvn3,-np.ones(len(vvn3))) pr3 = np.arccos(vvn3)/self.angle proba[bheltain] = pr3 typ[bheltain] = 3 #ta.u bhertain = (bheor & ~btaol & ~btaor)&boup if (prob and not(bhertain==False).all()): v4 = pta[:,bhertain]-self.apex.reshape(2,1) vn4 = v4/np.sqrt(np.sum(v4*v4,axis=0)) vvn4 = np.dot(self.u,vn4) vvn4 = np.minimum(vvn4,np.ones(len(vvn4))) vvn4 = np.maximum(vvn4,-np.ones(len(vvn4))) pr4 = np.arccos(vvn4)/self.angle proba[bhertain] = pr4 typ[bhertain] = 4 #he.u btarhein = (btaor & ~bheol & ~bheor)&boup if (prob and not(btarhein==False).all()): v5 = phe[:,btarhein]-self.apex.reshape(2,1) vn5 = v5/np.sqrt(np.sum(v5*v5,axis=0)) vvn5 = np.dot(self.u,vn5) vvn5 = np.minimum(vvn5,np.ones(len(vvn5))) vvn5 = np.maximum(vvn5,-np.ones(len(vvn5))) pr5 = np.arccos(vvn5)/self.angle proba[btarhein] = pr5 typ[btarhein] = 5 #ta.he btainhein = (~btaol & ~btaor & ~bheol & ~bheor)&boup if (prob and not (btainhein==0).all()): va = pta[:,btainhein]-self.apex.reshape(2,1) vb = phe[:,btainhein]-self.apex.reshape(2,1) vna = va/np.sqrt(np.sum(va*va,axis=0)) vnb = vb/np.sqrt(np.sum(vb*vb,axis=0)) # dot product vna,vnb vnab = np.sum(vna*vnb,axis=0) vnab = np.minimum(vnab,np.ones(len(vnab))) vnab = np.maximum(vnab,-np.ones(len(vnab))) pr6 = np.arccos(vnab)/self.angle proba[btainhein] = pr6 typ[btainhein] = 6 return(typ,proba)