algorithm – 如何计算盒子的法线?

前端之家收集整理的这篇文章主要介绍了algorithm – 如何计算盒子的法线?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试创建一个算法来计算模型/网格的法线.人们一直在告诉我使用两个向量之间的交叉产品,这些看起来似乎是一个好主意,直​​到我发现它可能并不总是有效.例如,想象一个盒子,其正面位于原点,背面朝向Z轴.这是一张图片

我为坏的手写道歉,但这不应该有任何意义.如你所见,我越过v和u使法线指向正z轴.但是,如果我使用相同的计算来计算背面的法线,那么显然法线将是指向形状内部的矢量.结果是我有不准确的法线来计算灯光的亮度.我希望法线在任何时候都能远离模型.

我知道有更好的方法来计算正常情况,但我不知道它是什么.任何人都可以向我建议另一种计算正常的算法来解决这个问题吗?如果没有,则必须有一种方法来检查法线是否面向对象/模型内部.如果是这样,那么你能在答案中建议它吗?我会在哪里找到解释,因为我希望对这些方法的工作方式有一个直觉.

解决方法

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

话虽如此,我想你想知道在索引排序不一致的假设(?)情况下该怎么做.

我们可以使用的一种方法是射线交叉.重要的定理是,在网格外部的光源将仅与网格相交偶数次,如果在内部,则为奇数.

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

>使用上面的叉积计算“正常”(并将其标准化)=> ñ
>取三角形上的任意一点(最好是中点)
>沿着法线增加这个点的一些小的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),但常数因子远小于天真方法.

猜你在找的CSS相关文章