【问题标题】:How to calculate the normals of a box?如何计算盒子的法线?
【发布时间】:2017-08-10 02:26:18
【问题描述】:

我正在尝试创建一种算法来计算模型/网格的法线。人们一直告诉我使用两个向量之间的叉积,起初这似乎是个好主意,直​​到我发现它可能并不总是有效。例如,想象一个盒子,它的正面位于原点,背面朝下 Z 轴。这是一张图片:

我为糟糕的笔迹道歉,但这不应该有任何意义。如您所见,我穿过 v 和 u 以获得指向正 z 轴的法线。但是,如果我使用相同的计算来计算背面的法线,那么显然法线将是指向形状内部的向量。结果是我有不准确的法线来计算灯光的亮度。我希望法线始终背对模型。

我知道必须有更好的方法来计算法线,但我不知道它是什么。谁能向我建议另一种算法来计算可以摆脱这个问题的法线?如果没有,那么必须有一种方法来检查法线是否面向对象/模型内部。如果是这样,那么您能否在答案中提出它以及我会在哪里找到关于它的解释,因为我很想对这些方法的工作原理有一个直觉。

【问题讨论】:

  • 叉积总是有方向的。记住你的右手法则。如果u x v 给你一个指向意外方向的向量,那么v x u 会给你一个大小相同但方向相反的向量。
  • 叉积是有方向的,看起来你只是在错误的方向上得到了正确的向量。也许这只是代表人脸的点的存储顺序问题?
  • 是的,问题确实发生在以错误的顺序存储我的脸,但我不知道如何检测它是否在飞机后面,然后以不同的方式存储顺序。我认为这是整个问题的开始。有什么建议我将如何检测到,因为这个点在另一个平面后面,那么也许我们只是反转叉积?
  • 我的印象是,也许还有其他计算法线的方法可以知道,如果法线面向模型,则反转法线。
  • 这是一个奇怪的问题,我首先想到的是用一个圆圈来封装对象,然后检查哪个法线(脸部的正面和背面)首先与它相交。但是,这不适用于复杂的形状。对于他们,我会尝试将它们导入 3DMax 或 Blender。

标签: algorithm graphics


【解决方案1】:

大多数软件包遵循可配置的循环排序三角形索引 - 顺时针或逆时针。因此,它们导出的所有网格都具有自洽的顺序,只要您的程序使用相同的约定,您就不必担心。


话虽如此,我想您想知道在索引顺序不一致的假设(?)情况下该怎么办。

我们可以使用的一种方法是 ray-intersection。重要的定理是光源在网格外的光线只会与网格相交偶数次,如果在网格内,则为奇数次。

为此,我们可以执行以下操作:

  • 使用上面的叉积计算“正常”(并对其进行标准化)=> N
  • 取三角形上的任意一点(最好是中点)
  • 将这个点沿法线增加一些小的 epsilon 值(取决于您的浮点格式和模型的大小 - 我会说 1e-4 用于单精度和 1e-8 用于双精度) => P
  • 将这条射线[dir = N, src = P]与网格中的所有个三角形相交(一个很好的算法是Möller–Trumbore
  • 如果相交数为偶数,则光线从网格外部开始;这意味着法线点从网格向外(因为您从表面上的一个点增加了它的源)。 - 当然,反之亦然。

次要 (-ish ?) 题外话:对上述内容的一种幼稚方法,即遍历网格中的所有三角形,将是 O(n) - 因此整个过程将具有 二次时间复杂度。这对于 非常 约 20 个三角形的小网格(例如一个盒子)来说非常好,但对于任何更大的网格来说都不理想!

您可以使用空间细分技术来降低此交叉步骤的成本:

  • K-D 树/八叉树:这些需要O(n log n)(对于最佳算法,即-参见Ingo Wald's paper)来构造,但如果处理得当,交叉点保证是O(log n)。那么整体复杂度将是O(n log n),这几乎是你能得到的最好的了
  • 网格:这只是将搜索空间和三角形划分为更小的框。构造是O(n),并且内存效率更高。相交时间仍为O(n),但常数因子比naive方法小。

【讨论】:

    【解决方案2】:

    叉积不可交换,因此v x uu x v 不同。事实上,它们将完全相反。

    对于正面,你想取u x v(假设你在一个right-hand coordinate system),背面你想穿过v x u

    有关交叉向量如何工作的更多信息,请参阅right-hand rule

    【讨论】:

    • 嘿,感谢您的回答,但这绝对不是我遇到的问题。我知道叉积不是可交换的,我知道我可以通过反转叉积来解决这个问题。然而,这不是我关心的。我在这里担心的是,如果我只是收到构成模型的三角形的位置数据,我将不得不根据该位置数据确定法线,但它也必须背对模型。这意味着我必须知道,叉积会给我留下一个一开始就背对或朝向我的模型的法线。
    • 通常三角形只以一种方式绘制。听起来背面的三角形是以错误的顶点顺序绘制的。 en.wikipedia.org/wiki/Triangle_strip
    • 哇,这条评论改变了游戏规则。像搅拌机这样的建模软件是否遵守这个约定?如果确实如此,那么也许我毕竟不需要担心它。我只需要在生成我自己的时候小心我遵循这个约定。
    • 通常在索引中建模软件导出,我想知道索引的顺序是否将采用上述方式。上面描述的是三角形条带而不是索引,所以我想知道它是否会以正确的顺序导出,这样如果我做点积它应该可以工作并且脸远离他的模型。
    猜你喜欢
    • 1970-01-01
    • 2019-06-23
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多