#!/usr/bin/ruby

func plot(x, y, c) {
    c && printf("plot %d %d %.1f\n", x, y, c);
}

func fpart(x) {
    x - int(x);
}

func rfpart(x) {
    1 - fpart(x);
}

func drawLine(x0, y0, x1, y1) {

    var p = plot;
    if (abs(y1 - y0) > abs(x1 - x0)) {
        p = {|arg| plot(arg[1, 0, 2]) };
        (x0, y0, x1, y1) = (y0, x0, y1, x1);
    }

    if (x0 > x1) {
        (x0, x1, y0, y1) = (x1, x0, y1, y0);
    }

    var dx = (x1 - x0);
    var dy = (y1 - y0);
    var gradient = (dy / dx);

    var xends = [];
    var intery;

    # handle the endpoints
    [[x0, y0], [x1, y1]].each { |xy|
        var (x, y) = xy...;
        var xend = int(x + 0.5);
        var yend = (y + gradient*(xend-x));
        var xgap = rfpart(x + 0.5);

        var x_pixel = xend;
        var y_pixel = yend.int;
        xends << x_pixel;

        p.call(x_pixel, y_pixel  , rfpart(yend) * xgap);
        p.call(x_pixel, y_pixel+1,  fpart(yend) * xgap);
        defined(intery) && next;

        # first y-intersection for the main loop
        intery = (yend + gradient);
    }

    # main loop
    range(xends[0]+1, xends[1]-1).each { |x|
        p.call(x, intery.int,  rfpart(intery));
        p.call(x, intery.int+1, fpart(intery));
        intery += gradient;
    }
}

drawLine(0, 1, 10, 2);