Represento isosuperficies con cubos de marcha (o tal vez marque los cuadrados ya que esto es 2D) y deseo hacer operaciones de conjunto como establecer diferencia, intersección y unión. Pensé que esto era fácil de implementar, simplemente eligiendo entre dos escalas de vértice de dos superficies implícitas diferentes, pero no es así.Operaciones de CSG en superficies implícitas con cubos de marcha
Para mis pruebas iniciales, he intentado con dos esferas
círculos, y la operación de conjunto diferencia . es decir, A - B. Un círculo se está moviendo y el otro está estacionario. Este es el enfoque que probé al elegir los escalares de los vértices y al clasificar los vértices de las esquinas como interiores o exteriores. El código está escrito en C++. OpenGL se usa para renderizar, pero eso no es importante. La representación normal sin operaciones CSG da el resultado esperado.
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<vec2>& 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<<i); //mark as inside
}
}
else {
scalar[i] = s1; //inside neither circle
}
}
if(squareindex == 0)
return;
/* Usual interpolation between edge points to compute
the new intersection points */
verts[1] = mix(iso, verts[0], verts[2], scalar[0], scalar[1]);
verts[3] = mix(iso, verts[2], verts[4], scalar[1], scalar[2]);
verts[5] = mix(iso, verts[4], verts[6], scalar[2], scalar[3]);
verts[7] = mix(iso, verts[6], verts[0], scalar[3], scalar[0]);
for(int i=0; i<10; ++i){ //10 = maxmimum 3 triangles, + one end token
int index = triTable[squareindex][i]; //look up our indices for triangulation
if(index == -1)
break;
tri.push_back(verts[index]);
}
}
Esto me da el efecto de escalón extraños: here http://www.mechcore.net/images/gfx/csgbug2.png
Parece que la operación se hace CSG sin interpolación. Simplemente "descarta" todo el triángulo. ¿Debo interpolar de alguna otra forma o combinar los valores escalares de los vértices? Me gustaría algo de ayuda con esto. Un caso de prueba completo puede descargarse HERE
EDIT: Básicamente, mi implementación de plazas de marcha funciona bien. Es mi campo escalar que está roto, y me pregunto cómo sería la forma correcta. Preferiblemente Busco un enfoque general para poner en práctica las tres operaciones de conjunto que ha comentado anteriormente, para las primitivas habituales (círculo, rectángulo/cuadrado, plano)
EDIT 2: Estas son algunas imágenes nuevas después de la implementación de la contestadora libro blanco:
1.Difference
2.Intersection
3.Union
EDITAR 3: He implementado esto en 3D también, con el sombreado adecuado/iluminación:
1.Difference between a greater sphere and a smaller sphere
2.Difference between a greater sphere and a smaller sphere in the center, clipped by two planes on both sides, and then union with a sphere in the center.
3.Union between two cylinders.
Hm, raro. Esto realmente funciona, pero el borde se vuelve un poco raro. Voy a investigar si este es un problema de precisión. Sin embargo, no aparece para círculos normales. Aquí hay una captura de pantalla de una grilla de 100x100: http://www.mechcore.net/images/gfx/csgbug3.png –
Correcto, es un problema de precisión. Los círculos más grandes funcionan bien, pero aumentar la teselación de la cuadrícula no (estoy usando flotadores). Gran respuesta y gran papel. Mi más profundo agradecimiento a usted, señor. –
¡De nada! ¡Buena suerte con su proyecto, las superficies implícitas son divertidas! –