一个封闭的多边形网格是否翻转?

3

我有一个3D建模应用程序。目前,我正在双面绘制网格,但是当物体关闭时,我想切换到单面绘制。

如果多边形网格是闭合的(没有边界边缘/完全周期),似乎我应该总能确定对象当前是否翻转,并自动更正。

翻转意味着我的法线指向物体内部而不是外部。翻转是由于我的绕组规则与当前的正面设置不匹配引起的,但我直接从几何计算法线,因此查看法线是检测它的简单方法。

我想到的一件事是取包围盒,找到最高点,并查看其法线指向上还是下 - 如果向下,则对象被翻转了。

但是这种解决方案似乎可能会在退化几何或浮点错误方面存在误差,因为我只会查看一个点。我想我可以获得所有6个轴对齐的范围,但这似乎是一个稍微好一点的权宜之计,而不是一个正确的解决方案。

有没有一种强大而简单的方法来解决这个问题?强大而困难的方法也可以.. :)


我认为你应该更好地解释一下“翻转”的含义,即是沿着x、y还是z轴翻转? - Frans Bouma
1
我认为他的意思是,如果法线指向内部(因为它们应该指向外部)。 - Jim Buck
你正在编写应用程序,因此您可以引入所有三角形都遵守“右手定则”的约定吗?即:如果您将您的右手从点0卷曲到点2处,则法线会指向您的拇指方向。 - e.James
如果您按照这个规则创建对象,也许就可以完全避免反转测试。 - e.James
作为一个通用建模应用程序,很难禁止用户做错事情。由于表面是开放的,我认为是否翻转它没有正确答案,两种方式都是正确的。而且用户可以轻松地从开放表面转换为封闭表面,所以我认为最好的方法是在出现问题后进行修复。 - tfinniga
2个回答

5
这是一种稳健但缓慢的方法来获取结果:
从质心偏移一个边界框的角落(强制它保证在多边形网格之外),然后创建一个线段从该角落到网格上任何一个三角形的中心点。
测量该线段与三角形法线之间的角度。
将该线段与网格的每个三角形面相交(包括您用于生成该线段的三角形)。
如果有奇数次相交,则法线和线段之间的角度应该小于180。 如果有偶数次相交,则角度应该大于180。
如果有偶数次相交,则应翻转数字。
对于非常复杂的表面,这应该有效,但必须封闭,否则会出现问题。

2

我正在将网格渲染为双面的。

你为什么要这样做呢?如果你正在使用OpenGL,那么有一个更好的方法可以让你省去所有的工作。使用以下代码:

glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);

通过这种方法,所有的多边形都是双面的。
您想使用单面照明的唯一原因是,如果您有一个开放或部分倒置的网格,并且希望通过使其无光来指示其内部的哪个部分属于内部。

一般来说,您提出的问题是几何处理中的一个开放性问题,据我所知,没有一种确定方向的绝对有效的通用方法。正如您所建议的那样,有些启发式方法几乎总是有效。
另一种方法类似于著名的点在多边形算法:选择网格上的一个顶点,并朝法线方向射出一条射线。如果射线击中偶数个面,则法线指向外部;如果奇数,则法线指向内部。请注意不要将起点计算为交点。该方法仅适用于网格是封闭流形的情况,并且如果射线恰好穿过两个多边形之间,则可能会出现一些边缘情况,因此您可能需要多次执行并采取领先投票。


感谢您的回答。 为了澄清,我正在为现有图形管道编写新的几何类型。 我只提供镶嵌网格和一些绘图选项。 在这种情况下,我试图匹配其他几何类型的行为,对于封闭对象,它们绘制单面,以便在相机在内部时可以看到外部。 它仍然绘制等参数线,因此您可以知道自己的位置,但是如果我的绕组反向,看起来会很糟糕。 - tfinniga
1
在OpenGL中打开双面光照会对性能产生影响。如果有避免需要的方法,那么它可能是有益的。如果您将使用着色器而不是FF管道,则还会有一些影响-在着色器中处理双面光照要少得多。 - Reed Copsey

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