从'三角汤'中找到独特的顶点

时间:2010-03-09 08:01:07

标签: c++ algorithm geometry

我正在两个库(Opencascade和DWF Toolkit)之上构建一个CAD文件转换器。

然而,我的问题是与平台无关:

假设:

我已经生成了一个网格作为三角形面的列表,形成了一个通过我的应用程序构建的模型。每个三角形由三个顶点定义,这三个顶点由三个浮点(x,y和z坐标)组成。由于三角形形成一个网格,因此大多数顶点由多于一个三角形共享。

目标:

我需要找到唯一顶点的列表,并生成一个由这个列表中的三个索引元组组成的面数组。

我想做的是:

//step 1: build a list of unique vertices
for each triangle
   for each vertex in triangle
      if not vertex in listOfVertices
         Add vertex to listOfVertices

//step 2: build a list of faces 
for each triangle
   for each vertex in triangle
      Get Vertex Index From listOfvertices
      AddToMap(vertex Index, triangle)

虽然我有一个执行此操作的实现,但是步骤1(生成唯一顶点列表)在O(n!)的顺序上确实很慢,因为每个顶点都与列表中已有的所有顶点进行比较。我想“嘿,让我们使用std :: map构建我的顶点组件的散列图,这应该加快速度!”,只是发现从三个浮点值生成一个唯一的密钥并不是一项简单的任务。

这里,stackoverflow的专家发挥作用:我需要某种哈希函数,它可以在3个浮点数上运行,或者从3d顶点位置生成唯一值的任何其他函数。

3 个答案:

答案 0 :(得分:3)

三种解决方案。当然还有其他人

  1. 使用哈希映射。这只有在“相同”意味着完全相同的情况下才有效。
  2. 使用二进制空间分区来划分点数
  3. 使用常规网格划分您的积分。
  4. 在情况2和3中,如果要指定一些容差,则需要搜索树或网格的多个部分。在BSP情况下,这意味着检查您是否在分割平面的公差范围内,如果是这样,则递归到两半。在网格情况下,这意味着检查容差范围内的所有相邻单元格。这两者都不是太难,但意味着使用“现成”解决方案会更难。

答案 1 :(得分:2)

转储数组中的所有顶点,然后执行unique(sort(array))。这应该是O(k n log(n)),其中k是共享顶点的三角形的平均数,通常k <7。

我能想到的唯一警告是你的unique函数应该能够获取指向比较函数的指针,因为你可能想要考虑你的顶点是否等于

distance(vertex1, vertex2) < threshold

但似乎是OK

答案 2 :(得分:0)

获取哈希的常见想法是将float的每个bitpattern与prime相乘并将它们相加。这样的事情:

unsigned int hash_point(float x, float y, float z)
{
   unsigned int* px = (unsigned int*)&x;
   unsigned int* py = (unsigned int*)&y;
   unsigned int* pz = (unsigned int*)&z;

   return (*px)*PRIME1 + (*py)*PRIME2 + (*pz)*PRIME3;
}

你应该注意sizeof(unsigned int)在这里被认为等于sizeof(float)。这里的示例仅用于说明主要想法,您应该根据自己的需要进行调整。