我正在两个库(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顶点位置生成唯一值的任何其他函数。
答案 0 :(得分:3)
三种解决方案。当然还有其他人
在情况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)。这里的示例仅用于说明主要想法,您应该根据自己的需要进行调整。