Skip to content

Instantly share code, notes, and snippets.

@ErisianArchitect
Created September 1, 2012 01:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ErisianArchitect/3562588 to your computer and use it in GitHub Desktop.
Save ErisianArchitect/3562588 to your computer and use it in GitHub Desktop.
Bresenham Line 3D
public static void DoLine(int startX, int startY, int startZ, int endX, int endY, int endZ, Action<int, int, int> callback)
{
int dx, dy, dz;
int sx, sy, sz;
int accum, accum2;//accumilator
dx = endX - startX;//Start X subtracted from End X
dy = endY - startY;
dz = endZ - startZ;
sx = ((dx) < 0 ? -1 : ((dx) > 0 ? 1 : 0));//if dx is less than 0, sx = -1; otherwise if dx is greater than 0, sx = 1; otherwise sx = 0
sy = ((dy) < 0 ? -1 : ((dy) > 0 ? 1 : 0));
sz = ((dz) < 0 ? -1 : ((dz) > 0 ? 1 : 0));
//dx = (dx < 0 ? -dx : dx);//if dx is less than 0, dx = -dx (becomes positive), otherwise nothing changes
dx = Math.Abs(dx);//Absolute value
//dy = (dy < 0 ? -dy : dy);
dy = Math.Abs(dy);
dz = Math.Abs(dz);
endX += sx;//Add sx to End X
endY += sy;
endZ += sz;
if (dx > dy)//if dx is greater than dy
{
if (dx > dz)
{
accum = dx >> 1;
accum2 = accum;
do
{
callback(startX, startY, startZ);
accum -= dy;
accum2 -= dz;
if (accum < 0)
{
accum += dx;
startY += sy;
}
if (accum2 < 0)
{
accum2 += dx;
startZ += sz;
}
startX += sx;
}
while (startX != endX);
}
else
{
accum = dz >> 1;
accum2 = accum;
do
{
callback(startX, startY, startZ);
accum -= dy;
accum2 -= dx;
if (accum < 0)
{
accum += dz;
startY += sy;
}
if (accum2 < 0)
{
accum2 += dz;
startX += sx;
}
startZ += sz;
}
while (startZ != endZ);
}
}
else
{
if (dy > dz)
{
accum = dy >> 1;
accum2 = accum;
do
{
callback(startX, startY, startZ);
accum -= dx;
accum2 -= dz;
if (accum < 0)
{
accum += dx;
startX += sx;
}
if (accum2 < 0)
{
accum2 += dx;
startZ += sz;
}
startY += sy;
}
while (startY != endY);
}
else
{
accum = dz >> 1;
accum2 = accum;
do
{
callback(startX, startY, startZ);
accum -= dx;
accum2 -= dy;
if (accum < 0)
{
accum += dx;
startX += sx;
}
if (accum2 < 0)
{
accum2 += dx;
startY += sy;
}
startZ += sz;
}
while (startZ != endZ);
}
}
}
@XiaofengdiZhu
Copy link

This is not right.
For example: (0, 3, 0) to (60, 123, -35)

@ErisianArchitect
Copy link
Author

Thanks for the feedback. I'll look into it when I get the chance, and fix it accordingly.

@ErisianArchitect
Copy link
Author

Unfortunately I never got around to fixing this. I don't have a project that I could test a fix on. But if I had to guess, it would work if you used unsigned integers instead of signed integers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment