C# 三维体素网格视线Bresenham算法
给定一个三维体素网格,其中每个体素的大小*大小*大小(宽度*高度*长度)为某个整数大小,并且一条线通过网格中的一些体素,是否有一种非常有效的方法来计算视线算法,以检测线通过的所有体素 算法约束:C# 三维体素网格视线Bresenham算法,c#,algorithm,unity3d,voxel,bresenham,C#,Algorithm,Unity3d,Voxel,Bresenham,给定一个三维体素网格,其中每个体素的大小*大小*大小(宽度*高度*长度)为某个整数大小,并且一条线通过网格中的一些体素,是否有一种非常有效的方法来计算视线算法,以检测线通过的所有体素 算法约束: 由于原始Bresenham的近似性质,不会遗漏任何体素,如本2D示例所示: 算法需要合理有效,因为每帧计算一次;只要该算法不计算立方体的面积,并计算直线是否与每个立方体相交,就应该可以了 首先,Bresenham在视线方面不是很好:正如您的图纸所示,由于所有这些锯齿状边缘,最终选择的单元/体素将不允许
首先,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 --;
}
}
}
//改编自https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
//期望x是变化最快的维度;代替
//否则,请使用最快的更改维度,并相应地修复plot()
功能线(浮点数x0、浮点数y0、浮点数x1、浮点数y1、浮点数z1、浮点数y1){
浮点数dx=x1-x0;
浮动dy=y1-y0;
浮子dz=z1-z0;
浮动三角误差:=abs(dy/dx);
浮动三角误差z:=abs(dz/dx);
浮动误差=0;
浮动误差z=0;
int y=y0;
int z=z0;
对于(int x=x0;x=0.5){
y+=符号(dy);
错误--;
}
errorZ+=三角形errorZ;
而(errorZ>=0.5){
z+=符号(dz);
errorZ--;
}
}
}
Brensenham背后的思想可以推广到任何层面:只需跟踪累积的错误,当需要控制它们时,跳转@MBo我不知道如何将对查找对象交点感兴趣的光线跟踪算法用作Bresenham算法的推广,以3d@tucuxiBresenham algo不提供所有接触体素的注册,因此。。如果没有关键的改变,它就不适合这里。@MBo我同意,但OP明确要求在3d中使用Bresenham。见我答案的第一段。@tucuxi我想他用Bresenham作为(唯一)已知算法的例子