Я представляю изоповерхности с идущими кубами, (или возможно идущие квадраты, поскольку это 2D), и я хочу сделать операции присвоения как разность множеств, пересечение и объединение. Я думал, что это было легко реализовать путем простого выбора между двумя скалярами вершины из двух различных неявных поверхностей, но это не.
Для моего начального тестирования я попробовал двумя кругами сфер и различием в операции присвоения. т.е. - B. Один круг перемещается, и другой является стационарным. Вот подход, который я попробовал при выборе скаляров вершины и при классификации угловых вершин как внутри или снаружи. Код написан в C++. OpenGL используется для рендеринга, но это не важно. Нормальный рендеринг без любых операций CSG действительно дает ожидаемый результат.
void march(const vec2& cmin, //min x and y for the grid cell
const vec2& cmax, //max x and y for the grid cell
std::vector& tri,
float iso,
float (*cmp1)(const vec2&), //distance from stationary circle
float (*cmp2)(const vec2&) //distance from moving circle
)
{
unsigned int squareindex = 0;
float scalar[4];
vec2 verts[8];
/* initial setup of the grid cell */
verts[0] = vec2(cmax.x, cmax.y);
verts[2] = vec2(cmin.x, cmax.y);
verts[4] = vec2(cmin.x, cmin.y);
verts[6] = vec2(cmax.x, cmin.y);
float s1,s2;
/**********************************
********For-loop of interest******
*******Set difference between ****
*******two implicit surfaces******
**********************************/
for(int i=0,j=0; i<4; ++i, j+=2){
s1 = cmp1(verts[j]);
s2 = cmp2(verts[j]);
if((s1 < iso)){ //if inside circle1
if((s2 < iso)){ //if inside circle2
scalar[i] = s2; //then set the scalar to the moving circle
} else {
scalar[i] = s1; //only inside circle1
squareindex |= (1<
Это дает мне странные неровности:
(источник: mechcore.net)
Похоже, что операция CSG сделана без интерполяции. Это просто "отбрасывает" целый треугольник. Я должен интерполировать некоторым другим способом или объединить скалярные величины вершины? Я любил бы некоторую справку с этим. Полный тестовый сценарий может быть загружен ЗДЕСЬ
Править: В основном моя реализация идущих квадратов хорошо работает. Именно мое скалярное поле повреждается и интересно, на что был бы похож корректный путь. Предпочтительно я ищу общий подход для реализации этих трех операций присвоения, которые я обсудил выше, для обычных примитивов (круг, прямоугольник/квадрат, плоскость)
РЕДАКТИРОВАНИЕ 2: Вот некоторые новые изображения после реализации технического описания отвечающей стороны:
1. Различие
2. Пересечение
3. Объединение
РЕДАКТИРОВАНИЕ 3: Я реализовал это в 3D также с надлежащей штриховкой/освещением:
1. Различие между большей сферой и меньшей сферой
2. Различие между большей сферой и меньшей сферой в центре, отсеченном двумя плоскостями с обеих сторон и затем объединением со сферой в центре.
3. Объединение между двумя цилиндрами.
Это не то, как вы смешиваете скалярные поля. Ваши скаляры говорят одно, а ваши флаги, вне зависимости от того, находитесь вы внутри или нет, говорят другое. Сначала объедините поля, а затем выполните визуализацию, как если бы вы создавали один составной объект:
for(int i=0,j=0; i<4; ++i, j+=2){
s1 = cmp1(verts[j]);
s2 = cmp2(verts[j]);
s = max(s1, iso-s2); // This is the secret sauce
if(s < iso) { // inside circle1, but not inside circle2
squareindex |= (1<<i);
}
scalar[i] = s;
}
Эта статья может быть полезной: Объединение моделирования CSG с мягким смешиванием с использованием Неявные поверхности на основе липшица .