【问题标题】:Draw all voxels that pass through a 3D line in 3D voxel space在 3D 体素空间中绘制通过 3D 线的所有体素
【发布时间】:2019-03-20 14:34:34
【问题描述】:

我想画一条 3D 体素化的线,即找出一条线经过的所有体素。 3D bresenham 总是会跳过一些体素。如图所示,3D bresenham 生成的体素不能完全包含起始体素和目标体素之间的连线。

此链接中的算法:Algorithm for drawing a 4-connected line 可以解决我在 2D 平面上的问题,但我未能将其改进为 3D。

【问题讨论】:

  • 前段时间我用这篇论文做了类似你想做的事情:cs.yorku.ca/~amana/research/grid.pdf
  • 非常感谢。我在论文中对这种方法进行了一些更改,并解决了我的问题。
  • 使用 DDA 简单,比 bresenham 更快,并且可以轻松移植到任何维度。也看看这个:DDA + subpixel precision
  • 您的目标是绘制通过 3D 线的所有体素吗?
  • @PeterO。是的。我已经通过以下方法解决了我的问题。如果您有更好的解决方案,我会尝试。

标签: graphics 3d voxel bresenham


【解决方案1】:

Pierre Baret 链接中的方法可以解决我的问题。当直线只经过某个体素的顶点时,是否访问当前体素是一个很模糊的问题,所以我对方法做了一点改动。当tMaxX、tMaxY、tMaxZ中的两个或多个值相等时,论文中的方法生成的体素如图a所示。我做了一些改动以在 b 中生成结果。 c中显示了一个更正常的条件,它分别比较了3D bresenham和这种方法生成的线。

c++实现的代码:

void line3D(int endX, int endY, int endZ, int startX, int startY, int startZ, void draw){
int x1 = endX, y1 = endY, z1 = endZ, x0 = startX, y0 = startY, z0 = startZ;
int dx = abs(x1 - x0);
int dy = abs(y1 - y0);
int dz = abs(z1 - z0);
int stepX = x0 < x1 ? 1 : -1;
int stepY = y0 < y1 ? 1 : -1;
int stepZ = z0 < z1 ? 1 : -1;
double hypotenuse = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2));
double tMaxX = hypotenuse*0.5 / dx;
double tMaxY = hypotenuse*0.5 / dy;
double tMaxZ = hypotenuse*0.5 / dz;
double tDeltaX = hypotenuse / dx;
double tDeltaY = hypotenuse / dy;
double tDeltaZ = hypotenuse / dz;
while (x0 != x1 || y0 != y1 || z0 != z1){
    if (tMaxX < tMaxY) {
        if (tMaxX < tMaxZ) {
            x0 = x0 + stepX;
            tMaxX = tMaxX + tDeltaX;
        }
        else if (tMaxX > tMaxZ){
            z0 = z0 + stepZ;
            tMaxZ = tMaxZ + tDeltaZ;
        }
        else{
            x0 = x0 + stepX;
            tMaxX = tMaxX + tDeltaX;
            z0 = z0 + stepZ;
            tMaxZ = tMaxZ + tDeltaZ;
        }
    }
    else if (tMaxX > tMaxY){
        if (tMaxY < tMaxZ) {
            y0 = y0 + stepY;
            tMaxY = tMaxY + tDeltaY;
        }
        else if (tMaxY > tMaxZ){
            z0 = z0 + stepZ;
            tMaxZ = tMaxZ + tDeltaZ;
        }
        else{
            y0 = y0 + stepY;
            tMaxY = tMaxY + tDeltaY;
            z0 = z0 + stepZ;
            tMaxZ = tMaxZ + tDeltaZ;

        }
    }
    else{
        if (tMaxY < tMaxZ) {
            y0 = y0 + stepY;
            tMaxY = tMaxY + tDeltaY;
            x0 = x0 + stepX;
            tMaxX = tMaxX + tDeltaX;
        }
        else if (tMaxY > tMaxZ){
            z0 = z0 + stepZ;
            tMaxZ = tMaxZ + tDeltaZ;
        }
        else{
            x0 = x0 + stepX;
            tMaxX = tMaxX + tDeltaX;
            y0 = y0 + stepY;
            tMaxY = tMaxY + tDeltaY;
            z0 = z0 + stepZ;
            tMaxZ = tMaxZ + tDeltaZ;

        }
    }
    draw(x0, y0, z0);
}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 2023-04-08
    • 2022-11-10
    • 2013-05-06
    • 2011-04-18
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多