Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何检测三角形网格中的孔?_Algorithm_Geometry - Fatal编程技术网

Algorithm 如何检测三角形网格中的孔?

Algorithm 如何检测三角形网格中的孔?,algorithm,geometry,Algorithm,Geometry,实际上,我可以通过检查三角形的哪条边没有邻居来检测凸面三角形网格的边界或边。所以,如果一个网格有一些洞,那么我们可以很容易地高亮显示该部分,因为我们有边顶点 但问题是,如果我们只有边顶点或边界,我们怎么知道网格有一些洞?网格有多少个洞 我对这个问题想得够多了,但没能理解,有什么想法吗?孔检测的条件或检查应该是什么 在发现一个洞后,我想把它填满。但第一件事是检测它 谢谢。假设网格已连接,并且可以高亮显示所有边界。剩下的是所有孔+一个附加边界,即网格本身的边界。您只需丢弃具有最大长度的边界即可获得所

实际上,我可以通过检查三角形的哪条边没有邻居来检测凸面三角形网格的边界或边。所以,如果一个网格有一些洞,那么我们可以很容易地高亮显示该部分,因为我们有边顶点

但问题是,如果我们只有边顶点或边界,我们怎么知道网格有一些洞?网格有多少个洞

我对这个问题想得够多了,但没能理解,有什么想法吗?孔检测的条件或检查应该是什么

在发现一个洞后,我想把它填满。但第一件事是检测它


谢谢。

假设网格已连接,并且可以高亮显示所有边界。剩下的是所有孔+一个附加边界,即网格本身的边界。您只需丢弃具有最大长度的边界即可获得所有孔。

从扫描仪(如Kinect)衍生的三角形网格可以包含小碎片(孤立的面片)和小孔。我建议,通常可以通过计算边界上相邻顶点的顶点数来检测孔。如果相邻顶点比边界顶点少,则它不是孔。

我的答案仅适用于闭合网格,但它将处理凹孔和凸孔的情况

为了便于解释,让我们想象一个二维网格

计算网格的边界框。在我们的示例中,边界框需要存储X轴和Y轴的最小值和最大值,以及每个值对应的顶点索引:

struct BoundingBox
{
  float minX,maxX,minY,maxY;
  int vminX,vmaxX,vminY,vmaxY;
}
迭代网格中的每个顶点,在添加每个点时增加边界框。当顶点负责更改其中一个最小/最大值时,请使用顶点网格索引存储或覆盖相应的vmin/vmax值

例如

BoundingBox边界;
bounds.minX=顶点[0].X;
bounds.maxX=顶点[0].X;
bounds.minY=verts[0].Y;
bounds.maxY=顶点[0].Y;
bounds.vminX=bounds.vmaxX=bounds.vminY=bounds.vmaxY=0;
for(int i=1;ibounds.maxX){bounds.maxX=v.X;bounds.vmaxX=i;}
如果(v.Ybounds.maxY){bounds.maxY=v.Y;bounds.vmaxY=i;}
}

现在在边界上迭代,直到找到一个包含在边界框中收集的所有顶点的边界。这是你的外边界。其余的边界是网格内的孔。

除非孔是凸面的,否则不能保证孔的长度小于封闭网格。实际上,问题是,当我检测边界或边界顶点时,所有孔边界也包括在其中,因为孔边也没有任何邻居。所以,问题是分离孔边和网格边界?如何知道这些边来自孔,其余的边来自网格边界?这需要对边进行扫描,那些共享一个公共顶点的边属于“边界”,我在回答中写道,分类哪个边界是孔。但是这里有很多角点情况,比如孔和边界共享一个顶点。www.google.com/search?q=mesh+hole+filling似乎给出了一些相关的纸张引用。一旦找到了所有属于“边界”边的边,通过扫描循环运行它们,将第一条边的顶点放在一个集合中,当获得下一条边时,检查是否有任何顶点属于现有集(如果没有将它们放入其他集中),或者如果是,则将它们放入同一集中。完成后,您将有一组顶点,其中每组顶点将表示一个边界。现在只需丢弃长度最大的集合,其余集合将是它们所属的每个孔的顶点。
BoundingBox bounds;
bounds.minX = verts[0].X;
bounds.maxX = verts[0].X;
bounds.minY = verts[0].Y;
bounds.maxY = verts[0].Y;
bounds.vminX = bounds.vmaxX = bounds.vminY = bounds.vmaxY = 0;
for (int i = 1; i < numVerts; i++)
{
  Vertex v = verts[i];
  if (v.X < bounds.minX) { bounds.minX = v.X; bounds.vminX = i; }
  if (v.X > bounds.maxX) { bounds.maxX = v.X; bounds.vmaxX = i; }
  if (v.Y < bounds.minY) { bounds.minY = v.Y; bounds.vminY = i; }
  if (v.Y > bounds.maxY) { bounds.maxY = v.Y; bounds.vmaxY = i; }
}