def centres(self): ''' Needed for area weighted averages ''' from okean import calc elements = [] for e in self.q.IKLE2: element = [] for n in e: element.append((self.x[n], self.y[n])) elements.append(element) elements = np.asarray(elements) X = elements[:, :, 0] Y = elements[:, :, 1] n = len(X) Cx = np.zeros(n, 'f') Cy = np.zeros(n, 'f') A = np.zeros(n, 'f') inp = np.zeros(n, 'bool') for i in range(n): A[i] = calc.poly_area(X[i], Y[i]) Cx[i], Cy[i] = calc.poly_centroid(X[i], Y[i]) # check if centre is inside polygon: inp[i] = calc.inpolygon(Cx[i], Cy[i], X[i], Y[i]) self.xc = Cx self.yc = Cy if any(~inp): A = np.ma.masked_where(~inp, A) self.area = A self.inp = inp
def centres(self): ''' Needed for area weighted averages ''' from okean import calc elements = [] for e in self.q.IKLE2: element = [] for n in e: element.append((self.x[n],self.y[n])) elements.append(element) elements=np.asarray(elements) X=elements[:,:,0] Y=elements[:,:,1] n=len(X) Cx=np.zeros(n,'f') Cy=np.zeros(n,'f') A=np.zeros(n,'f') inp=np.zeros(n,'bool') for i in range(n): A[i]=calc.poly_area(X[i],Y[i]) Cx[i],Cy[i]=calc.poly_centroid(X[i],Y[i]) # check if centre is inside polygon: inp[i]=calc.inpolygon(Cx[i],Cy[i],X[i],Y[i]) self.xc=Cx self.yc=Cy if any(~inp): A=np.ma.masked_where(~inp,A) self.area=A self.inp=inp
def fillout(x,y,lims,color=False,**kargs): ''' Fill outside polygon. Fill the region between the polygon x,y and the rectangle lims (x0,x1,y0,y1). If no color is provided, the final polygon (ready to be used with pl.fill) is returned. Otherwise, pl.fill is done using alguments color and kargs. In this case, will be used the current axes or the one provided by key ax. Example: x=np.array([0,1,1,0.5]) y=np.array([0,-.1,1.1,1]) fillout(x,y,[-2,2,-2,2],'g',edgecolor='none') ''' from okean.calc import poly_area if poly_area(x,y)<0: x,y=x[::-1],y[::-1] xi,xe,yi,ye=lims i=np.where(x==x.min())[0][0] x=np.concatenate([x[i:], x[:i+1]]) y=np.concatenate([y[i:], y[:i+1]]) tmpx=np.array([xi, xi, xe, xe, xi, xi, x[0]]) tmpy=np.array([y[0], ye, ye, yi, yi, y[0], y[0]]) x=np.concatenate([tmpx, x]) y=np.concatenate([tmpy, y]) if color is False: return x,y else: ax=kargs.pop('ax',pl.gca()) o=ax.fill(x,y,color,**kargs) return x,y,o
def _chull(x,y,rmax,maxr='auto',method='circ'): status=0 X=[] Y=[] segs=[] if method=='kdt' and rmax>len(x): print(rmax,'Max k is %d'%len(x)) return X,Y,1 if method=='kdt': from scipy import spatial points=np.vstack((x,y)).T tree = spatial.cKDTree(points) else: tree=None # 1st element: i=np.where(y==y.max())[0][0] X+=[x[i]] Y+=[y[i]] stop=False for j in range(x.size*2): if j==0: x0,y0=x.min()-1,Y[-1] #rprev=0 rprev=rmax else: x0,y0=X[-2],Y[-2] xi,yi=X[-1],Y[-1] xx,yy,i=find_next(X,Y,x0,y0,xi,yi,x,y,rmax=rmax,rmax_prev=rprev,method=method,kdt=tree) rprev=rmax rmax2=rmax if method!='kdt': inverted_path=(xx==x0)&(yy==y0) if inverted_path: print('inverted...') while (xx is None) or (maxr and inverted_path): print('- looking for next inside while',rmax2) rmax2=rmax2*1.1 if rmax2<=maxr: xx,yy,i=find_next(X,Y,x0,y0,xi,yi,x,y,rmax=rmax2,rmax_prev=rprev,method=method) rprev=rmax2 inverted_path=(xx==x0)&(yy==y0) else: break if xx is None: print('cannot locate next point!') status=1 break X+=[xx] Y+=[yy] if len(X)>2: if method=='kdt': is_closed=(xx,yy)==(X[0],Y[0]) if is_closed: X=X[:-1] Y=Y[:-1] else: is_closed=(xi,yi,xx,yy)==(X[0],Y[0],X[1],Y[1]) if is_closed: X=X[:-2] Y=Y[:-2] if is_closed: print('DONE: polygon is closed!') print('AREA=',calc.poly_area(np.asarray(X),np.asarray(Y))) break # current segment: seg=X[-2],X[-1],Y[-2],Y[-1] if seg in segs: print('ERROR: repeating segment !') status=1 break segs+=[seg] # close polygon if not status: X=np.hstack((X,X[0])) Y=np.hstack((Y,Y[0])) return X,Y,status