Bresenham lines w/o diagonal movement

后端 未结 3 995
遥遥无期
遥遥无期 2020-12-22 01:41

Is there a modified Bresenham algorithm, where the step from one pixel to the next one isn\'t allowed to be diagonally, just horizontally or vertically? Or any other algorit

3条回答
  •  醉梦人生
    2020-12-22 02:19

    James' answer is pretty cool, but as he commented, it skews the line a bit. Another simple modification of the original Bresenham draws a line without diagonal steps that is closer to the "real" line.

    This is an implementation of the original Bresenham algorithm:

    public void line(int x0, int y0, int x1, int y1, int value) {
        int xDist =  Math.abs(x1 - x0);
        int yDist = -Math.abs(y1 - y0);
        int xStep = (x0 < x1 ? +1 : -1);
        int yStep = (y0 < y1 ? +1 : -1);
        int error = xDist + yDist;
    
        plot(x0, y0, value);
    
        while (x0 != x1 || y0 != y1) {
            if (2*error > yDist) {
                // horizontal step
                error += yDist;
                x0 += xStep;
            }
    
            if (2*error < xDist) {
                // vertical step
                error += xDist;
                y0 += yStep;
            }
    
            plot(x0, y0, value);
        }
    }
    

    The modification is simply to do either a horizontal or vertical step, not both, depending on whether the error indicator is nearer to a horizontal or vertical step:

    public void lineNoDiag(int x0, int y0, int x1, int y1, int value) {
        int xDist =  Math.abs(x1 - x0);
        int yDist = -Math.abs(y1 - y0);
        int xStep = (x0 < x1 ? +1 : -1);
        int yStep = (y0 < y1 ? +1 : -1);
        int error = xDist + yDist;
    
        plot(x0, y0, value);
    
        while (x0 != x1 || y0 != y1) {
            if (2*error - yDist > xDist - 2*error) {
                // horizontal step
                error += yDist;
                x0 += xStep;
            } else {
                // vertical step
                error += xDist;
                y0 += yStep;
            }
    
            plot(x0, y0, value);
        }
    }
    

    This effectively chooses the kind of step that minimizes the error, thus resulting in a line that is closer to the real line.

    The code is in Java, but it should be easily portable to PHP. I haven't thoroughly tested it, but it should work just as well as the original Bresenham. It may even be a tad faster.

提交回复
热议问题