确定一个三角形所处的体素。

8

给定一个环境的体素化和一个由顶点 A、B 和 C 组成的三角形,如何确定三角形所“占用”或存在的所有体素?换句话说,如何枚举所有包含三角形任意部分的体素?

2个回答

7
首先,您需要进行体素/三角形相交测试。
为了实现这一点,一种自然的方法是使用六个立方体面的半平面重复应用多边形裁剪算法(例如在3D中的Sutherland-Hodgman),并检查之后剩下的部分。
更好的方法在《图形宝石III》中有描述,三角形-立方体相交,第236-239页(有实现可用)。
然后,您需要枚举所有被三角形相交的体素。
  • 第一种可能的方法:

    1. 计算三角形的3D轴对齐包围盒。
    2. 将此包围盒捕捉到体素网格上(将框的最小/最大顶点向下取整/向上取整),以获得一个3D体素范围 [xmin,xmax]x[ymin,ymax]x[zmin,zmax]
    3. 扫描体素以找出哪些体素与三角形相交:

      • 对于 x[xmin, xmax]

        • 对于 y[ymin, ymax]

          • 对于 z[zmin, zmax]

            检查体素 (x, y, z) 是否与三角形相交

    这可以通过以下至少几种方式进行优化:

    1. 在各种 for 循环中可以逐步计算涉及到的数量。
    2. 通过仅考虑与三角形支撑平面相交的体素,可以减少最后一个 for 循环的范围。
    3. 可以更改循环的顺序,以优先考虑某个轴(以考虑三角形的方向)。
  • 第二种可能的方法:

    1. 选择三角形的一个顶点并找出其中包含的体素。该体素将用作种子。
    2. 从此种子体素开始,对与三角形相交的体素进行广度优先搜索(BFS)或深度优先搜索(DFS),即:
      • 跟踪已经测试了哪些体素与三角形相交,
      • 处理与相交体素相邻但未经测试的所有体素,但
      • 仅将与三角形相交的体素排队(BFS)或推入(DFS)。

谢谢您提供的信息!这可能是一个基本问题:对于第一种可能的方法,三角形的3D轴对齐边界框是否只是一个以三角形极点(min/max(x,y,z))为其边缘的立方体?另外,另一种可能的方法是使用Bresenham算法填充三角形(应用于3D):http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html? - Cenk Baykal
1
是的,三角形的3D轴对齐包围盒是一个盒子,其顶点是三角形的最小/最大x/y/z坐标的8种可能组合。 - user3146587
1
我不确定这是否可以称为三维的Bresenham算法,但你也可以尝试在三角形的两条边上同时进行光线行走,并报告沿着边缘中间点连接的线段上所有相交的体素(搜索关键词为ray walking 3D DDA)。 - user3146587
谢谢您的帮助!我知道这是一个有点老的帖子,但我正在尝试实现“检查体素(x,y,z)是否与三角形相交”的步骤,我对Graphics Gems III中用于体素/三角形相交测试的代码感到有些困惑。该代码似乎是针对与单位立方体的相交而定向的,那么修改它以使其适用于任意立方体/体素的最佳方法是什么?再次感谢。 - Cenk Baykal
3
代码实现了一个以原点为中心的单位立方体与三角形的相交测试。若要将其用于边界框为[xmin,xmax] x [ymin,ymax] x [zmin,zmax]的体素,请对三角形进行平移,使立方体的中心点 ((xmin+xmax)/2,(ymin+ymax)/2,(zmin+zmax)/2) 位于原点,然后对三角形进行非均匀缩放,缩放比例为(xmax-xmin,ymax-ymin,zmax-zmin),最后调用提供的实现代码(即不要更改代码,而是转换您的三角形)。 - user3146587
我认为比例应该是(1/(xmax-xmin), 1/(ymax-ymin), 1/(zmax-zmin)),而不是(xmax-xmin, ymax-ymin, zmax-zmin) - Matheus Gadelha

1
最好的方法是使用DDA进行光栅化,因为它比任何三角形盒测试快几倍。光栅化是一种分散技术,因此它只触及三角形表面上的体素。盒测试是一种聚集技术,因此需要每个体素检查哪些三角形与其接触。前者(分散)是O(n^2),而后者(聚集)是O(n^3)。
有关两者的良好CPU比较,请参见: https://github.com/ramakarl/voxelizer 此代码演示了两种聚集技术Schwarz-Seidel和Akenine-Moller,以及一种分散技术,基于边缘的2D DDA。

你的演示甚至无法编译,能否请您将缺失的函数添加到项目中?https://github.com/ramakarl/voxelizer/issues/1 - Mashpoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接