def surface_normals(r,phi,theta,grid,gtype='spher'): """ Numerically compute surface normals of a grid (in absence of analytical alternative). Also computes the surface elements, making L{surface_elements} obsolete. """ if gtype=='spher': raise NotImplementedError elif gtype=='delaunay': raise NotImplementedError elif gtype=='triangular': #-- compute the angle between the surface normal and the radius vector x,y,z = vectors.spher2cart_coord(r,phi,theta) centers = np.zeros((len(grid.convex_hull),3)) normals = np.zeros((len(grid.convex_hull),3)) sizes = np.zeros(len(grid.convex_hull)) #vertx,verty,vertz = points.T #-- compute centers,normals and sizes for i,indices in enumerate(grid.convex_hull): #-- center is triangle's barycenter centers[i] = [x[indices].sum()/3,y[indices].sum()/3,z[indices].sum()/3] #-- size is size of triangle a = sqrt((x[indices[0]]-x[indices[1]])**2 + (y[indices[0]]-y[indices[1]])**2 + (z[indices[0]]-z[indices[1]])**2) b = sqrt((x[indices[0]]-x[indices[2]])**2 + (y[indices[0]]-y[indices[2]])**2 + (z[indices[0]]-z[indices[2]])**2) c = sqrt((x[indices[1]]-x[indices[2]])**2 + (y[indices[1]]-y[indices[2]])**2 + (z[indices[1]]-z[indices[2]])**2) s = 0.5*(a+b+c) sizes[i] = sqrt( s*(s-a)*(s-b)*(s-c)) #-- normal is cross product of two sides side1 = [x[indices[1]]-x[indices[0]],y[indices[1]]-y[indices[0]],z[indices[1]]-z[indices[0]]] side2 = [x[indices[2]]-x[indices[0]],y[indices[2]]-y[indices[0]],z[indices[2]]-z[indices[0]]] normals[i] = np.cross(side1,side2) #-- make sure the normal is pointed outwards normal_r,normal_phi,normal_theta = vectors.cart2spher(centers.T,normals.T) normal_r = np.abs(normal_r) centers_sph = vectors.cart2spher_coord(*centers.T) normals = np.array(vectors.spher2cart(centers_sph,(normal_r,normal_phi,normal_theta))) #-- normalise and compute angles normals_T = normals.T normals = normals_T / vectors.norm(normals_T) #cos_gamma = vectors.cos_angle(a,normals) print centers.shape,sizes.shape,normals.shape return centers, sizes, normals#, cos_gamma
mlab.figure(size=(1000, 800)) mlab.gcf().scene.disable_render = True if l == 0 or l == 1: asl = 0.1 else: asl = 0.01 old_center = None for i, t in enumerate(np.linspace(0, 2 * pi, 100)): print k, l, m, i r, th, ph = surface(theta, phi, l, m, t, asl=asl, k=k) center, size, normal = local.surface_normals( r, ph, th, grid, gtype='triangular') if i == 0: colors = r r_c, phi_c, theta_c = vectors.cart2spher_coord( *center.T) colors_ = r_c mlab.clf() mlab.points3d(center.T[0], center.T[1], center.T[2], colors_, scale_factor=0.05, scale_mode='none', colormap='RdBu', vmin=colors_.min(), vmax=colors_.max()) #mlab.quiver3d(center.T[0],center.T[1],center.T[2],normal.T[0],normal.T[1],normal.T[2],colormap='spectral',scale_mode='none') mlab.colorbar()
def surface_normals(r, phi, theta, grid, gtype='spher'): """ Numerically compute surface normals of a grid (in absence of analytical alternative). Also computes the surface elements, making L{surface_elements} obsolete. """ if gtype == 'spher': raise NotImplementedError elif gtype == 'delaunay': raise NotImplementedError elif gtype == 'triangular': #-- compute the angle between the surface normal and the radius vector x, y, z = vectors.spher2cart_coord(r, phi, theta) centers = np.zeros((len(grid.convex_hull), 3)) normals = np.zeros((len(grid.convex_hull), 3)) sizes = np.zeros(len(grid.convex_hull)) #vertx,verty,vertz = points.T #-- compute centers,normals and sizes for i, indices in enumerate(grid.convex_hull): #-- center is triangle's barycenter centers[i] = [ x[indices].sum() / 3, y[indices].sum() / 3, z[indices].sum() / 3 ] #-- size is size of triangle a = sqrt((x[indices[0]] - x[indices[1]])**2 + (y[indices[0]] - y[indices[1]])**2 + (z[indices[0]] - z[indices[1]])**2) b = sqrt((x[indices[0]] - x[indices[2]])**2 + (y[indices[0]] - y[indices[2]])**2 + (z[indices[0]] - z[indices[2]])**2) c = sqrt((x[indices[1]] - x[indices[2]])**2 + (y[indices[1]] - y[indices[2]])**2 + (z[indices[1]] - z[indices[2]])**2) s = 0.5 * (a + b + c) sizes[i] = sqrt(s * (s - a) * (s - b) * (s - c)) #-- normal is cross product of two sides side1 = [ x[indices[1]] - x[indices[0]], y[indices[1]] - y[indices[0]], z[indices[1]] - z[indices[0]] ] side2 = [ x[indices[2]] - x[indices[0]], y[indices[2]] - y[indices[0]], z[indices[2]] - z[indices[0]] ] normals[i] = np.cross(side1, side2) #-- make sure the normal is pointed outwards normal_r, normal_phi, normal_theta = vectors.cart2spher( centers.T, normals.T) normal_r = np.abs(normal_r) centers_sph = vectors.cart2spher_coord(*centers.T) normals = np.array( vectors.spher2cart(centers_sph, (normal_r, normal_phi, normal_theta))) #-- normalise and compute angles normals_T = normals.T normals = normals_T / vectors.norm(normals_T) #cos_gamma = vectors.cos_angle(a,normals) print(centers.shape, sizes.shape, normals.shape) return centers, sizes, normals #, cos_gamma
for m in range(0,l+1,1): mlab.figure(size=(1000,800)) mlab.gcf().scene.disable_render = True if l==0 or l==1: asl = 0.1 else: asl = 0.01 old_center=None for i,t in enumerate(np.linspace(0,2*pi,100)): print k,l,m,i r,th,ph = surface(theta,phi,l,m,t,asl=asl,k=k) center,size,normal = local.surface_normals(r,ph,th,grid,gtype='triangular') if i==0: colors = r r_c,phi_c,theta_c = vectors.cart2spher_coord(*center.T) colors_ = r_c mlab.clf() mlab.points3d(center.T[0],center.T[1],center.T[2],colors_,scale_factor=0.05,scale_mode='none',colormap='RdBu',vmin=colors_.min(),vmax=colors_.max()) #mlab.quiver3d(center.T[0],center.T[1],center.T[2],normal.T[0],normal.T[1],normal.T[2],colormap='spectral',scale_mode='none') mlab.colorbar() if i>=1: vx,vy,vz = center.T[0]-old_center.T[0],\ center.T[1]-old_center.T[1],\ center.T[2]-old_center.T[2] v = np.sqrt(vx**2+vy**2+vz**2) mlab.quiver3d(center.T[0],center.T[1],center.T[2],\ vx,vy,vz,scalars=v,colormap='spectral',scale_mode='scalar')