I think 3d Bresenham is the way to go, just tweaked a bit. As a first pass at the problem, proceed as Bresenham, but be suspicious when you're about to take a step, or you've just taken a step, as these are the places where the line could pass through extra cells.
For simplicity, let's assume that z
is dominant, meaning that z
increments every step. The 3d Bresenham question is: "when do we increment/decrement in x
or y
?" The answer is when accumulated error in x
reaches .5, or when the error in y
does, or both.
For your case, I think you need to have a secondary threshold that uses slopeY = deltaY/deltaZ
to decide if the line is about to cross into a neighboring cell. If stepZ
is the change in z along the line for each pixel, then a test like error > .5 - slopeY/stepZ
should tell you to get cells on both sides of the line in y
. A similar test tells you if you have to get the extra cell in x
. If you have to get the extra cell in both x AND y, then you have to get the cell diagonal to the Bresenham cell as well.
If you've detected that you added a cell in y
before the increment, you won't add a cell after. If you haven't added a y
cell before, you will have to after, unless you happened to pass through a cell corner. How you handle that depends on your use-case.
These are my thoughts on the issue, I haven't tested anything, but something like it should work.