Эти таблицы используются для выяснения того, как тесселяция поверхности:
Первая таблица дает вам необходимые ребра для интерполяции. Вторая таблица дает вам способ тесселяции, то есть, какие треугольники вы должны сделать внутри куба.
Небольшой пример:
допустим, вершины 1 и 2 находятся ниже уровня изо, индекс куба должен быть равен 3.
Весь перекресток должен выглядеть как клин.
Если подумать, вам придется интерполировать значения на ребрах: 0 и 9, 2 и 10. Если вы введете это в битовое поле, каждый бит, соответствующий «пересечено ли ребро?» вы получите что-то вроде этого:
10 9 8 7 6 5 4 3 2 1 edge
1 1 0 0 0 0 1 0 1 0 intersected?
не так ли?
Это точно значение из edgeTable[3] в двоичном формате ;) 0x30A = 1100001010
Теперь вы можете написать функцию, которая линейно интерполирует точки на этих ребрах в соответствии с вашим изоуровнем. Эти точки станут вашей поверхностью внутри этой ячейки.
Но как разбить эту ячейку/поверхность?
если заглянуть в triTable[3] улыбка должна ползти по лицу :)
Дополнение после утверждения остаточного недоумения в комментарии: ;-)
Что делает Marching Cubes: представьте, что у вас есть темная комната с одним точечным источником света. Это центр объемного поля интенсивности света скалярных значений интенсивности. Вы можете перейти к точке (x, y, z) и измерить интенсивность там, например. 3 канделы.
Теперь вы хотите визуализировать поверхность через все точки с определенной интенсивностью света. Вы можете представить, что эта изоповерхность будет выглядеть как сфера вокруг точечного источника света. Именно это, мы надеемся, нам предоставят Походные кубы.
Теперь пробежаться по всем точкам в комнате и пометить каждую точку как вершину, имеющую примерно значение iso, будет очень сложно алгоритмически и приведет к огромному количеству вершин. Который нам потом нужно было бы как-то тесселировать.
Итак: Первые маршевые кубы рассекают весь объем на кубы одинакового размера. Если базовые данные имеют какую-то базовую дискретность, используются кратные этому. Я не буду вдаваться в другой случай, так как это редкость. Например, мы помещаем сетку с плотностью 1 мм в комнату размером 2 х 5 х 5 м.
Мы используем кубики 5ммx5ммx5мм. Прохождение через них должно быть намного дешевле.
Теперь вы можете представить, что ребра некоторых кубов пересекают изоповерхность. Это самые интересные. Этот код идентифицирует их:
cubeindex = 0;
if (grid.val[0]
если кубический индекс остается равным нулю, этот конкретный куб не пересекается изоповерхностью. Если cubeindex > 0, теперь вы знаете, что изоповерхность проходит через этот куб, и вы хотите визуализировать часть изоповерхности, которая находится внутри него.
Пожалуйста, представьте себе это. См. http://en.wikipedia.org/wiki/Marching_cubes для примеров пересекающихся кубов.
Вершины, которые вы можете легко получить, находятся на ребрах куба. Просто выполните линейную интерполяцию между двумя угловыми точками, чтобы найти положение изозначения, и поместите туда вершину. Но какие ребра пересекаются??? Это информация в edgeTable[cubeindex]. Это большой фрагмент кода со всеми ifs, который хранит интерполированные точки как вершины в массиве точек xyz: vertlist[]. Этот фрагмент звучит следующим образом:
get the bitfield = edgeTable[cubeindex]
if edge 1 is marked in bitfield (bit 1 set to 1 in bitfield)
vertlist[0] = interpolated point, somewhere on edge 1
... and so on.
Теперь у вас есть массив, полный вершин, но как соединить их с треугольниками? Это информация, которую предоставляет Tritable.
Остальное в значительной степени то, что я объяснил выше.
Что ж, если проблемы все еще будут, пожалуйста, укажите конкретный фрагмент кода, который вызывает у вас проблемы.
person
AndreasT
schedule
22.04.2009