Марширующие кубики Terrassing / Ridge Effect

Я реализую алгоритм движущихся кубов, как правило, основанный на реализации Пол Бурк с некоторыми основными корректировками:

  • предварительный расчет скалярного поля (значения с плавающей запятой)
  • избегая дублирования вершин в окончательном списке, используя std :: map
  • хранение вершин для визуализации финальной сетки в Ogre3D

В основном я изменил почти 80% его кода. У моего полученного меша есть несколько уродливых террас, и я не уверен, как их избежать. Я предполагал, что использование плавающих точек для скалярного поля сделает эту работу. Это общий эффект? Как вы можете избежать этого?

Проходящие марширующие кубики

вычисление позиций вершин по краям. (cell.val [p1] содержит скалярное значение для данной вершины):

//if there is an intersection on this edge
if (cell.iEdgeFlags & (1 << iEdge))
{
const int* edge = a2iEdgeConnection[iEdge];

int p1 = edge[0];
int p2 = edge[1];

//find the approx intersection point by linear interpolation between the two edges and the density value
float length = cell.val[p1] / (cell.val[p2] + cell.val[p1]);
asEdgeVertex[iEdge] = cell.p[p1] + length  * (cell.p[p2] - cell.p[p1]);
}

Вы можете найти полный исходный код здесь: https://github.com/DieOptimistin/MarchingCubes
Я использую Ogre3D в качестве библиотеки для этого примера.

1

Решение

Как сказал Энди Ньюманн, дьявол был в линейной интерполяции. Правильно это:

float offset;
float delta = cell.val[p2] - cell.val[p1];

if (delta == 0) offset = 0.5;
else offset = (mTargetValue - cell.val[p1]) / delta;

asEdgeVertex[iEdge] = cell.p[p1] + offset* (cell.p[p2] - cell.p[p1]);
0

Другие решения


По вопросам рекламы [email protected]