三角网格的顶点曲率计算(平均曲率和高斯曲率)

参考:

https://blog.csdn.net/weixin_44210987/article/details/113279727

https://blog.csdn.net/qq_36686437/article/details/116369956

https://blog.csdn.net/qq_36686437/article/details/105559280

https://blog.csdn.net/ModestBean/article/details/89438082

三维空间中的曲率:三维曲面偏离平面的程度           

                             

曲面曲率:
在曲面上取一点P,曲面在P点的法线为n,过n可以有无限多个剖切平面,每个剖切平面与曲面相交,交线为一条平面曲线。平面结论:圆上弯曲程度相同,任意一点曲率相等,越弯曲曲率越大,直线曲率为0。

不同的剖切平面上的平面曲线在P点的曲率半径一般是不相等的。

主曲率:曲面上有无数个不同方向的曲线,曲面上的点不同方向具有不同曲率,其中最大值和最小值为称为主曲率 k1 和k2,极值方向称为主方向。数学上可证名k1和k2互相垂直。

高斯曲率:两主曲率乘积,反映曲面在不同方向弯曲程度是否相同。高斯曲率为正,为球面。高斯曲率为负双曲面。

平均曲率:两主曲率算数平均数(k1+k2)/2,反映曲面凹凸程度。平均曲率为正,局部凹。平均曲率为负,局部凸。
 

曲率计算过程:

1. 找出所有的公共边,以及包含他们的两个三角形面片。

保存公共边起始-终点顶点编号(VerticeID, VerticeID)、三角形面片(TriaID,TriaID)编号、单位化的公共边向量edgeVector=[vx, vy,vz] 以及公共边向量长度distances。

2. 求相邻两个三角形面片法向量的cos夹角beta,并符号化。

符号化:

相邻三角形法向量叉乘之后的向量cp,与edgeVector 进行点乘,若结果大于0,sign=1;等于0,sign=0;小于0,sign=-1.

### 右手系法则下,

两个三角形为凸,则cp与edgeVector夹角为0, sign=1;

两个三角形为凹,则cp与edgeVector夹角为180, sign=-1;
两个三角形呈一条线,它们的法向量平行,cp==0, sign=0;

3. 构建曲率公式:

T =f(edgeVector, beta,sign,distance)

4. 矩阵分解,求特征向量和特征值。

特征值最小的为最小曲率, 

特征值最大的为法向量, 

特征值第二大的的为最大曲率

            Cmean = (Cmin+Cmax)/2
            Cgauss = Cmin*Cmax

   

2. input:
        vertices: [nx3]
        faces:[n,3]
        normals:[n,3]
    
    calculate:
        edgeVector:相邻三角形的公共边单位向量。[3,ne], ne为公共边数量
        beta:相邻两个三角形法向量的cos角。[1,ne]
        Tv:曲率公式
    return:
        Umin, Umax, Cmin, Cmax, Cmean, Cgauss
        依次为最小最大切向量,最小最大曲率,平均曲率,高斯曲率。

import numpy as np
from numpy import linalg as LA
import sys


'''
计算平均曲率和高斯曲率

'''

def getCommonEdges(faces):
    '''
    input:
        faces:[nx3]
    return:
        commonEdges: indexes of vertices in common edges, [nx2]
        facePairs:  triangle pairs where they locate in ,[nx2]
    '''

    # faces = np.array([[1,2,3],[3,2,4],[5,2,1]])
    faces = faces-1### python 索引 从 0 开始
    numFace = faces.shape[0]
    edgeStart = faces.flatten() 
    edgeEnd = faces[:,[1,2,0]].flatten() 
    edges = np.vstack((edgeStart, edgeEnd)) #[2,n]
    faceId = np.tile(np.arange(numFace),(3,1)).transpose().flatten().tolist()

    commonEdges = []
    facePires = []
    numEdges= edges.shape[1]
    for i in range(numEdges):
        curEdge = edges[:,i].tolist()
        # print(curEdge)
        ind1 = np.where(edges[1,:] == curEdge[0])[0]
        ind2 = np.where(edges[0,:] == curEdge[1])[0]
        index = list(set(ind1).intersection(set(ind2)))
        if len(index):
            commonEdges.append(curEdge)
            facePires.append([faceId[i], faceId[index[0]]])
    
    commonEdges=np.array(commonEdges)
    facePires = np.array(facePires)

    ###### 去除冗余:edgeStart

你可能感兴趣的:(三角网格的顶点曲率计算(平均曲率和高斯曲率))