【问题标题】:Computing face normals and winding计算面法线和缠绕
【发布时间】:2017-03-20 04:23:52
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      计算人脸法线

      您必须计算跨越包含给定面的平面的两个向量的叉积。它为您提供了该面的(非单位)法线向量。您必须对其进行规范化,然后就完成了。

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

      右手定则表明向量交叉的方向 产品是通过将 uv 尾对尾放置来确定的, 将右手压扁,向u方向伸展,然后 然后将手指向 v 角度的方向弯曲 与 u。然后拇指指向cross(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 } 定义的平面的 + 一侧
      • 行列式 x3 位于由 CCW 点 { x0, x1, x2 } 定义的平面的 - 一侧
      • 行列式 = 0: x3{ x0, x1, x2 } 共面

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

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

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

      【讨论】:

      • 感谢您的回答。
      • 还有一个建议:对于每个多面体,将x3 设置为多面体的中心(这在模型空间中尤其容易,原点是中心),所以每当你得到一个负矩阵,你知道x3在负侧,这意味着向外的方向将是正侧。
      猜你喜欢
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 2015-12-24
      相关资源
      最近更新 更多