确定三角形所在的体素

时间:2014-02-07 21:55:53

标签: graphics 3d geometry voxel

给定环境的体素化和具有顶点A,B和C的三角形,确定三角形“占据”或居住的哪些体素的最佳方法是什么?换句话说,我怎样才能枚举三角形的任何部分所在的所有体素?

2 个答案:

答案 0 :(得分:5)

首先,您需要进行体素/三角交叉测试。

  • 为实现这一目标,一种自然的方法是使用立方体六面的半平面在三角形上重复应用多边形裁剪算法(例如3D中的Sutherland-Hodgman)并检查之后还剩下什么。

  • 图形宝石III中描述了一种更好的方法,Triangle-Cube Intersection,第236-239页(implementation可用)。

然后,您需要枚举与三角形相交的所有体素。

  • 第一种可能的方法:

    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)是否与三角形相交

    4. 这可以通过以下几种方式进行优化:

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

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

答案 1 :(得分:0)

最好的方法是使用DDA进行栅格化,因为它将比任何盒中三角测试快几倍。栅格化是一种散射技术,因此它仅接触三角形表面上的体素。盒式测试是一种收集技术,因此它们要求每个体素检查哪些三角形与之接触。前者(散射)为O(n ^ 2),而后者(聚集)为O(n ^ 3)。

要对两者进行良好的CPU比较,请参见: https://github.com/ramakarl/voxelizer

此代码演示了Schwarz-Seidel和Akenine-Moller两种收集技术,以及一种基于边缘的2D DDA分散技术。