CSG在带有行军立方体的隐式曲面上的操作

我使用行军立方体渲染等值面(或者行军正方形,因为这是2D),并且我想要执行集合操作,如集合差异,交集和联合。 我认为这很容易实现,只需从两个不同的隐式曲面中选择两个顶点标量,但事实并非如此。

对于我最初的测试,我尝试了两个领域的圆圈和设置的操作差异。 即A - 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<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]);
  }
}

这给了我怪异的锯齿:这里http://www.mechcore.net/images/gfx/csgbug2.png
看起来CSG操作是在没有内插的情况下完成的。 它只是“丢弃”整个三角形。 我是否需要以其他方式进行插值,还是结合顶点标量值? 我很乐意为此提供一些帮助。 完整的测试用例可以在这里下载

编辑:基本上,我的执行行军广场工作正常。 这是我的标量场被破坏了,我想知道正确的方式是什么样子。 最好我正在寻找一种通用的方法来实现上面讨论的三组操作,对于通常的基元(圆形,矩形/正方形,平面)

编辑2:这是执行回答者的白皮书后的一些新图像:

1.Difference
2.Intersection
3.Union

编辑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建模与使用基于Lipschitz的隐式曲面进行软混合相结合。

链接地址: http://www.djcxy.com/p/961.html

上一篇: CSG operations on implicit surfaces with marching cubes

下一篇: Curses for PHP on Windows