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