将曲面曲面映射到面?

时间:2016-04-28 10:15:29

标签: python matplotlib surface

我试图将表面曲率(平均值,高斯曲率和主曲率)值映射到曲面。我已经计算了人工生成的3D表面(例如圆柱体)的曲率值。我想要获得的3D表面就像这样mean curvature mapped to surface。有人可以指导我如何获得这个吗?

我正在创建的曲面的代码是:



import math
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

xindex = []
yindex = []
zindex = []
x = []
y = []
z = []
count = 1
surfaceSt = []
import numpy
numpy.set_printoptions(threshold=numpy.nan)
#surfaceStX = numpy.empty((10,36))
#surfaceStY = numpy.empty((10,36))
#surfaceStZ = numpy.empty((10,36))
surfaceStZ  = []
surfaceStX = []
surfaceStY = []
for i in range(1,21):
    if i < 11:
        x = []
        y = []
        z = []
        pt = []
        ptX = []
        ptY = []
        ptZ = []
        for t in range(0,360,10):
            x = i*math.sin(math.radians(t))
            y = i*math.cos(math.radians(t))
            z = i-1
            ptX.append(x)
            ptY.append(y)
            ptZ.append(z)
            pt.append([x,y,z])
        ptX.append(ptX[0])
        ptY.append(ptY[0])
        ptZ.append(ptZ[0])
        surfaceStX.append(ptX)
        surfaceStY.append(ptY)
        surfaceStZ.append(ptZ)
#        numpy.append(surfaceStX,ptX)
#        numpy.append(surfaceStY,ptY)
#        numpy.append(surfaceStZ,ptZ)
    

        #ax.scatter(x,y,z)
    elif i >= 11:
        x = []
        y = []
        z = []
        pt = []
        ptX = []
        ptY = []
        ptZ = []
        for t in range(0,360,10):
            x = (i-count)*math.sin(math.radians(t))
            y = (i-count)*math.cos(math.radians(t))
            z = i-1
            ptX.append(x)
            ptY.append(y)
            ptZ.append(z)
            pt.append([x,y,z])
        ptX.append(ptX[0])
        ptY.append(ptY[0])
        ptZ.append(ptZ[0])
        surfaceStX.append(ptX)
        surfaceStY.append(ptY)
        surfaceStZ.append(ptZ)
        count +=2
        
        

X = numpy.array(surfaceStX)
Y = numpy.array(surfaceStY)
Z = numpy.array(surfaceStZ)

ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,shade = 'True' )
from surfaceCurvature import surface_curvature
Pcurvature,Gcurvature,Mcurvature = surface_curvature(X,Y,Z)
plt.show()
&#13;
&#13;
&#13;

我的表面曲率计算如下(礼貌:https://github.com/sujithTSR/surface-curvature):

&#13;
&#13;
    def surface_curvature(X,Y,Z):

	(lr,lb)=X.shape

	#print lr
	#print "awfshss-------------"
	#print lb
#First Derivatives
	Xv,Xu=np.gradient(X)
	Yv,Yu=np.gradient(Y)
	Zv,Zu=np.gradient(Z)

#Second Derivatives
	Xuv,Xuu=np.gradient(Xu)
	Yuv,Yuu=np.gradient(Yu)
	Zuv,Zuu=np.gradient(Zu)   

	Xvv,Xuv=np.gradient(Xv)
	Yvv,Yuv=np.gradient(Yv)
	Zvv,Zuv=np.gradient(Zv) 

#2D to 1D conversion 
#Reshape to 1D vectors
	Xu=np.reshape(Xu,lr*lb)
	Yu=np.reshape(Yu,lr*lb)
	Zu=np.reshape(Zu,lr*lb)
	Xv=np.reshape(Xv,lr*lb)
	Yv=np.reshape(Yv,lr*lb)
	Zv=np.reshape(Zv,lr*lb)
	Xuu=np.reshape(Xuu,lr*lb)
	Yuu=np.reshape(Yuu,lr*lb)
	Zuu=np.reshape(Zuu,lr*lb)
	Xuv=np.reshape(Xuv,lr*lb)
	Yuv=np.reshape(Yuv,lr*lb)
	Zuv=np.reshape(Zuv,lr*lb)
	Xvv=np.reshape(Xvv,lr*lb)
	Yvv=np.reshape(Yvv,lr*lb)
	Zvv=np.reshape(Zvv,lr*lb)

	Xu=np.c_[Xu, Yu, Zu]
	Xv=np.c_[Xv, Yv, Zv]
	Xuu=np.c_[Xuu, Yuu, Zuu]
	Xuv=np.c_[Xuv, Yuv, Zuv]
	Xvv=np.c_[Xvv, Yvv, Zvv]

# First fundamental Coeffecients of the surface (E,F,G)
	
	E=np.einsum('ij,ij->i', Xu, Xu) 
	F=np.einsum('ij,ij->i', Xu, Xv) 
	G=np.einsum('ij,ij->i', Xv, Xv) 

	m=np.cross(Xu,Xv,axisa=1, axisb=1) 
	p=np.sqrt(np.einsum('ij,ij->i', m, m)) 
	n=m/np.c_[p,p,p]

# Second fundamental Coeffecients of the surface (L,M,N), (e,f,g)
	L= np.einsum('ij,ij->i', Xuu, n) #e
	M= np.einsum('ij,ij->i', Xuv, n) #f
	N= np.einsum('ij,ij->i', Xvv, n) #g


# Gaussian Curvature
	K=(L*N-M**2)/(E*G-F**2)
	K=np.reshape(K,lr*lb)

# Mean Curvature
	H = (E*N + G*L - 2*F*M)/((E*G - F**2))
	H = np.reshape(H,lr*lb)

# Principle Curvatures
	Pmax = H + np.sqrt(H**2 - K)
	Pmin = H - np.sqrt(H**2 - K)
#[Pmax, Pmin]
	Principle = [Pmax,Pmin]
	return Principle,K,H
&#13;
&#13;
&#13;

编辑1:

我根据armatita提供的链接尝试了一些方法。以下是我的代码:

&#13;
&#13;
    '''
    Creat half cylinder
    '''
    import numpy
    import matplotlib.pyplot as plt
    import math
    ptX= []
    ptY = []
    ptZ = []
    ptX1 = []
    ptY1 = []
    ptZ1 = []
    for i in range(0,10):
        x = []
        y = []
        z = []
        for t in range(0,200,20):
            x.append(10*math.cos(math.radians(t)))
            y.append(10*math.sin(math.radians(t)))
            z.append(i)
            x1= 5*math.cos(math.radians(t))
            y1 = 5*math.sin(math.radians(t))
            z1 = i
            ptX1.append(x1)
            ptY1.append(y1)
            ptZ1.append(z1)
        ptX.append(x)
        ptY.append(y)
        ptZ.append(z)

    X = numpy.array(ptX)
    Y = numpy.array(ptY)
    Z = numpy.array(ptZ)     

    fig = plt.figure()
    ax = fig.add_subplot(111,projection = '3d')
    from surfaceCurvature import surface_curvature
    p,g,m= surface_curvature(X,Y,Z)
    n = numpy.reshape(m,numpy.shape(X))
    ax.plot_surface(X,Y,Z, rstride=1, cstride=1)
    plt.show()

    '''
    Map mean curvature to color
    '''
    import numpy as np
    X1 = X.ravel()
    Y1 = Y.ravel()
    Z1 = Z.ravel()

    from scipy.interpolate import RectBivariateSpline
    

    # Define the points at the centers of the faces:
    y_coords, x_coords = np.unique(Y1), np.unique(X1)
    y_centers, x_centers = [ arr[:-1] + np.diff(arr)/2 for arr in (y_coords,      x_coords)]

    # Convert back to a 2D grid, required for plot_surface:
    #Y1 = Y.reshape(y_coords.size, -1)
    #X1 = X.reshape(-1, x_coords.size)
    #Z1 = Z.reshape(X.shape)
    C = m.reshape(X.shape)

    C -= C.min()
    C /= C.max()
    interp_func = RectBivariateSpline(x_coords, y_coords, C.T, kx=1, ky=1)
&#13;
&#13;
&#13;

I get the following error:
raise TypeError('y dimension of z must have same number of y')
TypeError: y dimension of z must have same number of elements as y

所有尺寸都相同。任何人都能说出我的实施出了什么问题吗?

1 个答案:

答案 0 :(得分:0)

我认为你需要弄清楚你需要什么。看看你的代码,我注意到你正在生成没有用的变量。此外,您似乎有一个计算曲面曲率的函数,但是您尝试使用np.unique函数进行一些计算,我无法在此处看到此目的(这就是出现该错误的原因)。

所以让我们假设:

  • 您有一个函数可以返回每个单元格的曲率值。
  • 您可以使用X,Y和Z网格绘制该表面。

使用您的代码,并假设您m变量是曲率(这也在您的代码中),如果我这样做:

import numpy
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import math

# Here would be the surface_curvature function

X = numpy.array(ptX)
Y = numpy.array(ptY)
Z = numpy.array(ptZ)   
p,g,m= surface_curvature(X,Y,Z)
C = m.reshape(X.shape)

C -= C.min()
C /= C.max() 

fig = plt.figure()
ax = fig.add_subplot(111,projection = '3d')
n = numpy.reshape(m,numpy.shape(X))
ax.plot_surface(X,Y,Z,facecolors = cm.jet(C), rstride=1, cstride=1)
plt.show()

,我得到了这个:

Value mapped to color in matpotlib surface

这是映射到matplotlib曲面中颜色的值。如果您构建的C不是实际曲率,则需要将其替换为。