计算面法向量和面的方向。

5
给定一个具有定义顶点(x, y, z)的凸多面体,用来指定多面体的面。
如何计算多面体每个面的表面法线?
我需要表面法线以计算顶点法线来执行Gouraud shading。关于如何做到这一点,我只能找到Newell方法的线索,但是如何确保法线是外向而不是内向的呢?感谢任何帮助。
2个回答

7

计算面的法线向量

需要计算出跨越包含给定面的平面的两个向量的叉积,得到该面的(非单位)法向量。需要对其进行归一化处理即可完成计算。

如果x0x1x2是三角形面的顶点,则可以按以下方式计算法向量:

vector3 get_normal(vector3 x0, vector3 x1, vector3 x2)
{
    vector3 v0 = x0 - x2;
    vector3 v1 = x1 - x2;
    vector3 n = cross(v0, v1);

    return normalize(n);
}

注意,向量的叉积遵循right-hand rule
右手规则指出,向量的叉积方向是通过将尾对尾放置,展平右手,朝着的方向延伸,并沿着角度< v >与之间的方向卷曲手指。然后拇指指向的方向。
定向三角形
为了确保所有的法线都指向多面体内部/外部,三角形必须统一定向,这意味着所有的顶点必须按照逆时针(CCW)或顺时针(CW)的顺序排列。这也被称为计算机图形学中的绕组。
您可以通过计算下面矩阵的行列式来检查三角形的方向,其中x3是测试期间的视点。
| x0.x  x0.y  x0.z  1 |
| x1.x  x1.y  x1.z  1 |
| x2.x  x2.y  x2.z  1 |
| x3.x  x3.y  x3.z  1 |
  • determinant > 0: x3在由CCW点{ x0, x1, x2 }定义的平面的+一侧。
  • determinant < 0: x3在由CCW点{ x0, x1, x2 }定义的平面的-一侧。
  • determinant = 0: x3{ x0, x1, x2 }共面。

旋转顶点的顺序(通过将它们全部向左或向右移动)不会改变方向。因此,{ x0, x1, x2 }{ x2, x0, x1 }{ x1, x2, x0 }具有相同的方向。

但是,如果交换两个连续的元素的顺序,则也会交换到相反的方向。这意味着{ x0, x1, x2 }{ x1, x0, x2 }具有相反的方向。

使用这些信息,您可以轻松地定向您的三角形:使用谓词矩阵测试每个三角形。如果测试失败,只需交换任意两个连续的顶点元素的顺序,问题就解决了。


感谢您的回答。 - Yu-Jui Chen
另一个建议:对于每个多面体,将 x3 设置为多面体的中心(在模型空间中特别容易,因为原点是中心),这样每当您得到一个负矩阵时,就知道 x3 在负侧,这意味着外部方向将是正侧。 - plasmacel

3
一个简单的方法是首先通过平均所有顶点来计算多面体的重心C。由于多面体是凸的,因此它将在其内部。 然后对于每个面,通过面的任意两条边的叉积计算法线,并通过计算法线与V-C的点积确定法线的方向,其中V是面上的一个顶点;如果这个点积为负,则法线向内,因此取反(每个分量)以获得外向法线。

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