Math 具有行进立方体的隐式曲面上的CSG运算

Math 具有行进立方体的隐式曲面上的CSG运算,math,graphics,marching-cubes,implicit-surface,Math,Graphics,Marching Cubes,Implicit Surface,我用移动立方体渲染等值面(或者可能是2D),我想做集合操作,比如集合差分、交集和并集。我认为这很容易实现,只需在两个不同隐式曲面的两个顶点标量之间进行选择,但事实并非如此 对于我的初始测试,我尝试了两个球体和一个圆,并设置了操作差。i、 一个圆圈在移动,另一个静止。这里是我在拾取顶点标量和将角点分类为内部或外部时尝试的方法。代码是用C++编写的。OpenGL用于渲染,但这并不重要。没有任何操作的正常渲染不会给出预期结果。 void march(const vec2& cmi

我用移动立方体渲染等值面(或者可能是2D),我想做集合操作,比如集合差分、交集和并集。我认为这很容易实现,只需在两个不同隐式曲面的两个顶点标量之间进行选择,但事实并非如此

对于我的初始测试,我尝试了两个球体和一个圆,并设置了操作差。i、 一个圆圈在移动,另一个静止。这里是我在拾取顶点标量和将角点分类为内部或外部时尝试的方法。代码是用C++编写的。OpenGL用于渲染,但这并不重要。没有任何操作的正常渲染不会给出预期结果。



       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]);
  }
}
void-march(const-vec2&cmin,//网格单元的最小x和y
const vec2和cmax,//网格单元的最大x和y
标准::矢量和tri,
浮动iso,
浮点(*cmp1)(常量向量2&)//与静止圆的距离
float(*cmp2)(const vec2&)//与移动圆的距离
)
{
无符号整数平方指数=0;
浮点标量[4];
vec2顶点[8];
/*网格单元的初始设置*/
verts[0]=vec2(cmax.x,cmax.y);
顶点[2]=vec2(cmin.x,cmax.y);
顶点[4]=vec2(cmin.x,cmin.y);
顶点[6]=vec2(cmax.x,cmin.y);
浮球s1、s2;
/**********************************
********兴趣圈******
*******区别****
*******两个隐式曲面******
**********************************/

对于(int i=0,j=0;i这不是混合标量字段的方式。标量表示一件事,但标记是否在内部表示另一件事。首先合并字段,然后像处理单个复合对象一样进行渲染:

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;
}

for(int i=0,j=0;iHm,奇怪。这确实有效,但边缘有点奇怪。我将调查这是否是一个精度问题。但普通圆不会出现。这是一个100x100网格的屏幕截图:对,这是一个精度问题。更大的圆效果很好,但增加网格的镶嵌度不会(我用的是浮标)。答案很好,论文也很好。非常感谢你,先生。不客气!祝你的项目好运,很有趣!