#!/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);