Найдите уникальные вершины от 'треугольного супа'

Я создаю преобразователь файла CAD сверху двух библиотек (Opencascade и DWF Toolkit).

Однако моим вопросом является агностик платформы:

Данный:

Я генерировал сетку, поскольку список треугольных поверхностей формирует модель, созданную через мое приложение. Каждый Треугольник определяется через три вершины, которые состоят из трех плаваний (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)

В то время как у меня действительно есть реализация, которая делает это, step1 (поколение списка уникальных вершин) действительно медленно в порядке O (n!), так как каждая вершина уже сравнивается со всеми вершинами в списке. Я думал "Эй, позволяет, создают hashmap компонентов моих вершин с помощью станд.:: карта, которая должна ускорить вещи!", только, чтобы найти, что генерация уникального ключа от трех значений с плавающей точкой не является тривиальной задачей.

Здесь, эксперты stackoverflow играют роль: Мне нужна некоторая хеш-функция, которая работает над 3 плаваниями или любой другой функцией, генерирующей уникальное значение от положения 3-й вершины.

6
задан Jon Seigel 24 March 2010 в 18:50
поделиться

3 ответа

Выгрузите все вершины в массив, затем выполните unique (sort (array)) . Это должно быть O (k n log (n)), где k - среднее количество треугольников, имеющих общую вершину, обычно k <7.

Единственное предостережение, о котором я могу думать, это то, что ваша уникальная функция должна иметь возможность принимать указатель на функцию сравнения, поскольку вы, вероятно, захотите считать свои вершины равными if

distance(vertex1, vertex2) < threshold

, но это кажется быть ОК .

3
ответ дан 17 December 2019 в 02:27
поделиться

Обычная идея для получения хеша состоит в том, чтобы умножить каждый битовый шаблон поплавка на простое число и сложить их вместе. Примерно так:

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). Образец приведен только для иллюстрации основной идеи, вы должны настроить его под свои нужды.

0
ответ дан 17 December 2019 в 02:27
поделиться

Три решения. Конечно, есть и другие

  1. Используйте хэш-карту. Это будет работать только в том случае, если «одинаковый» означает в точности то же самое.
  2. Используйте двоичное пространство, чтобы разделить точки
  3. Используйте обычную сетку, чтобы разделить ваши точки.

В случаях 2 и 3, если вы хотите указать некоторый допуск, вам нужно будет выполнить поиск более чем в одной части дерева или сетки. В случае BSP это означает проверку того, что вы находитесь в пределах допуска разделяющей плоскости, и если да, то повторение на обе половины. В случае сетки это означает проверку всех соседних ячеек, которые находятся в пределах допуска. Ни то, ни другое не является слишком твердым, но означает, что будет сложнее использовать готовое решение.

3
ответ дан 17 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: