将顶点法线转换为面法线

5
我有一个三角形多面体(不一定是凸的),并且有以下信息:
每个顶点的位置列表。 定义每个面的顶点三元组列表。 每个顶点法线的列表(这里的顶点法线是从每个顶点开始通过平均每个顶点周围的面法线(见下文)计算出的向量)。
我想要计算面法线列表(垂直于每个面的标准化向量,指向外部)。

很好,如果你想要计算的话,为什么不去计算呢?你使用了Newell方法吗(http://www.opengl.org/wiki/Calculating_a_Surface_Normal)? - mmgp
我想使用它,但我不知道多面体的“外部”方向,因此无法确定采取叉积的顺序。理想情况下,应该有一些方法使用顶点法线来确定哪个叉积是正确的,但我不确定如何做到这一点。 - user1873329
一种本地定义方向的方法是考虑从k-邻域(给定点最近的k个点的集合)进行PCA,但这可能不会给出全局一致的方向。我还记得Nina Amenta关于通过Voronoi极点和其他方法进行估计的几篇作品,你有没有查看过这位作者或任何相关内容? - mmgp
一个简单的建议是在每个顶点上对已有的3个法线进行平均。如果该值不够精确,则自己计算面法线,并保持与平均法线匹配的方向。 - nbonneel
2个回答

6
您可以通过将交叉法线与其中一个顶点法线或三个顶点的平均法线点积来简单确定交叉法线的方向。
下面是伪代码:
Vec3 CalcNormalOfFace( Vec3 pPositions[3], Vec3 pNormals[3] )
{
    Vec3 p0 = pPositions[1] - pPositions[0];
    Vec3 p1 = pPositions[2] - pPositions[0];
    Vec3 faceNormal = crossProduct( p0, p1 );

    Vec3 vertexNormal = pNormals[0]; // or you can average 3 normals.
    float dot = dotProduct( faceNormal, vertexNormal );

    return ( dot < 0.0f ) ? -faceNormal : faceNormal;
}

0

使用原生的three.js代码,使用三个顶点abc来实现:

您可以从THREE.Face3和几何体顶点中获取abc

var a = geometry.vertices[ face.a ];
var b = geometry.vertices[ face.b ];
var c = geometry.vertices[ face.c ];

然后你执行:

var normal = new THREE.Vector3().crossVectors( 
    new THREE.Vector3().subVectors( b, a ), 
    new THREE.Vector3().subVectors( c, a ) 
).normalize();

但是在THREE.Geometry类中也有方便的方法来为您进行顶点和面计算:computeVertexNormalscomputeFaceNormals


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接