【问题标题】:3D Voxel Grid Line of Sight Bresenham Algorithm3D 体素网格视线 Bresenham 算法
【发布时间】:2018-11-04 00:54:47
【问题描述】:

给定一个 3D 体素网格,其中每个体素是 SIZE * SIZE * SIZE(宽度 * 高度 * 长度)对于某个整数 SIZE 和一条穿过网格中一些体素的线,是否有一种相当有效的方法来计算视线算法检测线通过的所有体素?

算法约束:

  1. 由于原始 Bresenham 的近似性质,没有遗漏任何体素,如此 2D 示例所示:

  1. 算法需要相当高效,因为它将每帧计算一次;只要算法不采用立方体的面积并计算线是否与每个单独的立方体相交,就可以了。

【问题讨论】:

  • @MBo 我看不到如何将对寻找对象交点感兴趣的光线跟踪算法用作 Bresenham 算法对 3d 的推广
  • @MBo 我同意,但 OP 在 3d 中明确要求 Bresenham。请参阅我的回答中的第一段。
  • @tucuxi 我想他用 Bresenham 作为(唯一的)已知算法的例子

标签: c# algorithm unity3d voxel bresenham


【解决方案1】:

首先,Bresenham 并不擅长视线:正如您的绘图所示,由于所有这些锯齿状边缘,由此产生的细胞/体素选择将不允许源“看到”目标。

但是,如果您愿意认为 Bresenham 在 2d 中对您的问题有好处,那么很容易扩展到 3d:给定一条从 p0 = {x0, y0, z0} 到 p1 = {x1, y1, z1} 的线,您可以从 {x0, y0} 到 {x1, y1} 以及从 {x0, z0} 到 {x1, z1} 运行两次 2d Bresenham。使用第一次运行的 x 和 y 值,以及第二次运行的 z 值。

或者,您可以只进行完整的概括:

 // adapted from https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
 // expects x to be the fastest-changing dimension; replace
 //   with fastest-changing dimension otherwise, and fix plot() accordingly
 function line(float x0, float y0, float x1, float y1, float z1, float y1) {
   float dx = x1 - x0;
   float dy = y1 - y0;
   float dz = z1 - z0;
   float deltaErrorY := abs(dy / dx);
   float deltaErrorZ := abs(dz / dx);
   float errorY = 0;
   float errorZ = 0;
   int y = y0;
   int z = z0;
   for (int x = x0; x<x1; x++) { 
     plot(x,y,z);
     errorY += deltaErrorY;
     while (errorY >= 0.5) {
         y += sign(dy);
         errorY --;
     }
     errorZ += deltaErrorZ;
     while (errorZ >= 0.5) {
         z += sign(dz);
         errorZ --;
     }
   }
}

Brensenham 背后的想法可以推广到任何维度:只需跟踪累积的错误,并在需要时跳转以控制它们

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多