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
Beispiel #2
0
                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()
Beispiel #3
0
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')