Line rasterisation: Cover all pixels, regardless of line gradient?

前端 未结 6 2101
南笙
南笙 2020-12-25 13:30

Basically, I want to use a line algo to determine which cells to check for collisions for my raycaster.

Bresenham isn\'t great for this as it uses a unified-thicknes

6条回答
  •  清酒与你
    2020-12-25 14:17

    I had exactly the same problem as you and found an very simple solution. Usually, Bresenham has two consecutive if's to determine whether it should increase the coordinate for the two dimensions:

    public void drawLine(int x0, int y0, int x1, int y1, char ch) {
        int dx =  Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
        int dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
        int err = dx + dy, e2; // error value e_xy
    
        for (;;) {
            put(x0, y0, ch);
    
            if (x0 == x1 && y0 == y1) break;
    
            e2 = 2 * err;
    
            // horizontal step?
            if (e2 > dy) {
                err += dy;
                x0 += sx;
            }
    
            // vertical step?
            if (e2 < dx) {
                err += dx;
                y0 += sy;
            }
        }
    }
    

    Now all you have to do is to insert an else before the second if:

    public void drawLineNoDiagonalSteps(int x0, int y0, int x1, int y1, char ch) {
        int dx =  Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
        int dy = -Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
        int err = dx + dy, e2;
    
        for (;;) {
            put(x0, y0, ch);
    
            if (x0 == x1 && y0 == y1) break;
    
            e2 = 2 * err;
    
            // EITHER horizontal OR vertical step (but not both!)
            if (e2 > dy) { 
                err += dy;
                x0 += sx;
            } else if (e2 < dx) { // <--- this "else" makes the difference
                err += dx;
                y0 += sy;
            }
        }
    }
    

    Now the algorithm doesn't change both coordinates at once anymore. I haven't thoroughly tested this but it seems to work pretty well.

提交回复
热议问题