剔除内部三角形

4
我有一个数千个四边形的数组;这些四边形是4边3D多边形,我只知道四边形角落的坐标。
其中一部分四边形定义了3D形状的封闭外壳,其余四边形位于该封闭实体的内部。
如何确定哪些四边形是外壳的一部分,哪些是内部的一部分?这不是性能关键代码。
编辑:外壳形状的进一步限制
  • 形状内部没有孔,是单表面。
  • 它包含凸和凹的部分。
  • 我有一些已知在外壳内部的点。

关于形状有什么已知的信息?仅凭四边形的坐标是不够的。例如,请参阅http://en.wikipedia.org/wiki/Menger_sponge。 - deinst
你正在做的事听起来很棒。 - Ryan Bennett
鉴于任意四个非共面的点形成一个四边形,如果我理解你的意思正确的话,除非有另一个约束条件,比如说具有凸性,否则不可能解决问题。否则,无法确定给定边界四边形是属于物体还是孔的一部分。 - David Thornley
关于形状添加了更多信息。 - David Rutten
外表面的四边形是否连续,还是存在间隙? - Andrew
5个回答

4

如果您的形状自相交,则实现可能会很困难,但是如果您可以找到一个已知在表面上的四边形(可能是距质心最远的一个),则可以绘制出围绕它的同心圆形的四边形。然后找到该外部的一系列连续四边形组成的环,以此类推,直到到达“对面”。如果您的四边形相交或内部连接,则更加困难。我建议尝试拆开相交的部分,然后找到所有可能的光滑表面,并选择具有最大内部体积的表面。


这是一个有趣的方法。没有自相交,但内部的四边形与外壳四边形共享边缘。 - David Rutten
2
假设您确实找到了最外层的四边形,那么这也应该告诉您它的法向量指向表面。当您比较相邻的四边形时,您应该能够计算出它们的法向量。如果一条边恰好被三个四边形共享 - 已知在表面上的一个加上两个候选者,则具有较小角度的候选者的法线与已知表面四边形的法线之间的角度将是表面的一个,因为具有较大角度的四边形必须向固体内部推进。 - Douglas
这是解决问题的一个很好的方法。只是想补充一下你的建议:外壳基本上是一个在3D空间中折叠的简单四边形网格。因此,一旦确定了第一个外壳元素,就可以以“泛洪填充”的方式继续扫描相邻元素。 - ysap

2

这个怎么样?

计算四边形的法向量(称为“当前”四边形)。 使用该向量对所有剩余四边形进行交集测试。 如果它与正部分中的另一个四边形相交,则知道当前四边形是内部四边形。重复处理所有剩余四边形。

这假设四边形“面朝外”。


不是一个坏主意,但对于凹壳体来说行不通。而且我担心外壳的形状完全是自由形态的,有许多凹凸不平的地方。 - David Rutten
那不是取决于交集测试吗?正确的测试应该处理凹四边形。 - Jay
想象一个有垂直边的碗。如果你从碗的一侧内部画出一个向量,那么它将与碗的另一侧上的四边形相交,即使它在表面上。 - Douglas
啊。如果我可以假设它是一个封闭曲面,那么可以"计算射线与其相交的次数,如果次数为奇数,则说明是内部四边形"。如果内部四边形不是封闭曲面,则这种方法可能行不通。将四边形分解为三角形可能更好。这样会使得数学计算更加简单和快速。 - Jay

2
如果形状是凸的,这可以很容易地完成。当形状是凹的时候,则很难。
对于凸的情况,通过计算所有点的平均值来找到质心。这给出一个在内部的点,具有以下特性:
如果您从重心向四个角落发射射线,定义一个被切成两部分的金字塔,一部分包含形状内部空间,另一部分定义可能是形状外部的空间。
这两个体积为您提供了一个决策过程来检查四边形是否在边界上。如果另一个四边形的任何点出现在外部体积中,则该四边形不在边界上,可以将其丢弃为内部四边形。
编辑:刚才看到您上面的澄清。在形状是凹的更困难的情况下,您需要以下两种之一:
1. 您可以用来选择四边形的形状描述(参数化);或者
2. 其他属性,如所有边界四边形都是连续的。
进一步编辑:刚意识到你所描述的是点集的凹壳。尝试查看此搜索页面中的一些结果。

你的维基链接是关于凸包的。 - Tom Sirgedas

2
考虑所有四边形都在一个大的密封盒子里。选择一个四边形,进行光线追踪;将该四边形视为光源,将所有其他四边形视为反射和模糊的,其中对一个四边形的击中将从表面向所有方向发出光线,但不会绕过角落。
如果所有节点都有机会被击中后没有光线射到外部盒子,则将该四边形视为内部。
如果四边形是凸的,或者内部四边形没有与外部四边形共享边缘,则有更简单的方法。

1
或者反过来:在您飞行时呈现对象,并删除从未显示的多边形。 - Tom Sirgedas
1
@Tom Sirgedas:由于它可能是高度凸形状,因此您无法从盒子外部直接看到所有多边形的视线。话虽如此,如果这些多边形仍然具有漫反射性质,那当然可以。 - Dean J

1

通过减少处理的四边形数量,您可能能够让问题变得更简单。

您知道其中一些四边形形成了一个封闭的壳体。因此,这些四边形在它们的边缘连接。如果一个四边形的三个相邻边(即,边缘形成一个封闭环)与另一个四边形的边重叠,则这些四边形可能是壳体的一部分(这些相邻边构成2D区域的边界;让我们将该区域称为四边形的“连通面”)。制作一个这些“壳体候选者”的列表。现在,浏览此列表并丢弃任何具有边缘不与另一个候选项重叠的候选项(即,该边缘与不在列表中的四边形的边缘重叠)。重复此缩减过程,直到无法删除任何四边形。剩下的应该是您的壳体。创建一个包含所有不在“壳体”列表中的四边形的“非壳体四边形”列表。

在该壳体周围绘制一个边界框(或球体、椭圆等)。现在,浏览您的非壳体四边形列表,并丢弃位于边界区域之外的任何四边形。这些明确不在内部。

取剩下的非壳四边形。这些四边形可能在形状的内部,也可能不在内部。对于每个四边形,从每个面的中心垂直地画线,使其与边界形状的表面相交。沿着每条线追踪,并计算该线穿过壳列表中一个四边形的“连接面”的次数。如果次数为奇数,则该顶点位于形状的内部。如果次数为偶数,则该顶点位于外部。根据四边形的顶点是内部还是外部,可以确定四边形是在内部还是外部。

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