计算面法线和绕组

时间:2016-11-06 21:34:05

标签: c++ 3d geometry computational-geometry normals

给定具有定义顶点(x,y,z)的凸多面体,用于指定多面体的面。

如何计算多面体每个面的曲面法线?

我需要曲面法线才能计算顶点法线以执行Gouraud shading。我能找到的关于如何做到这一点的唯一线索是Newell的方法,但我如何确保法线是向外法线而不是向内?谢谢你的帮助。

2 个答案:

答案 0 :(得分:4)

计算面部正常

您必须计算跨越包含给定面的平面的两个向量的叉积。它为您提供该面部的(非单位)法线向量。你必须将它标准化,你就完成了。

如果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

  

右手规则指出矢量的方向交叉   产品是通过将 u v 从尾到尾确定的,   使右手变平,向 u 的方向延伸,并且   然后将手指按角度 v 的方向卷曲   用。然后拇指指向交叉(u,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 |
  • 决定因素> 0: x3位于由CCW点+
  • 定义的平面的{ x0, x1, x2 }
  • 决定因素< 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 }相反。

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

答案 1 :(得分:1)

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