Bitmap/Bresenham's line algorithm

Revision as of 12:22, 6 December 2008 by rosettacode>Blue Prawn (added C)

Using the data storage type defined on this page for raster graphics images, draw a line given 2 points with the Bresenham's algorithm (definition on Wikipedia).

Task
Bitmap/Bresenham's line algorithm
You are encouraged to solve this task according to the task description, using any language you may know.

C

<C>#define plot(x, y) put_pixel_clip(img, x, y, r, g, b)

  1. define swap_uint(a, b) do{ unsigned int tmp; tmp = a; a = b; b = tmp; }while(0)

void draw_line(

       image img,
       unsigned int x0, unsigned int y0,
       unsigned int x1, unsigned int y1,
       color_component r,
       color_component g,
       color_component b )

{

   unsigned short steep;
   steep = abs(y1 - y0) > abs(x1 - x0);
   if (steep) {
       swap_uint(x0, y0);
       swap_uint(x1, y1);
   }
   if (x0 > x1) {
       swap_uint(x0, x1);
       swap_uint(y0, y1);
   }
   {
       int deltax = x1 - x0;
       int deltay = abs(y1 - y0);
       int error = deltax / 2;
       int ystep;
       int y = y0;
       int x;
       if (y0 < y1) ystep = 1; else ystep = -1;
       for (x = x0; x <= x1; ++x) {
           if (steep) plot(y,x); else plot(x,y);
           error = error - deltay;
           if (error < 0) {
               y = y + ystep;
               error = error + deltax;
           }
       }
   }

}

  1. undef swap_uint
  2. undef plot</C>


MAXScript

fn plot img coord steep col =
(
    if steep then
    (
        swap coord[1] coord[2]
    )
    setPixels img coord col
)

fn drawLine img start end col =
(
    local steep = (abs (end.y - start.y)) > (abs (end.x - start.x))
	
    if steep then
    (
        swap start.x start.y
        swap end.x end.y
    )
	
    if start.x > end.x then
    (
        swap start.x end.x
        swap start.y end.y
    )
	
    local deltaX = end.x - start.x
    local deltaY = abs (end.y - start.y)
    local error = deltaX / 2.0
    local yStep = -1
    local y = start.y
	
    if start.y < end.y then
    (
        yStep = 1
    )
	
    for x in start.x to end.x do
    (
        plot img [x, y] steep col
        error -= deltaY
        if error < 0 then
        (
            y += yStep
            error += deltaX
        )
    )
    img
)

myBitmap = bitmap 512 512 color:(color 0 0 0)
myBitmap = drawLine myBitmap [0, 511] [511, 0] #((color 255 255 255))
display myBitmap

OCaml

<ocaml>let draw_line ~img ~color ~p0:(x0,y0) ~p1:(x1,y1) =

 let steep = abs(y1 - y0) > abs(x1 - x0) in
 let plot =
   if steep
   then (fun x y -> put_pixel img color y x)
   else (fun x y -> put_pixel img color x y)
 in
 let x0, y0, x1, y1 =
   if steep
   then y0, x0, y1, x1
   else x0, y0, x1, y1
 in
 let x0, x1, y0, y1 =
   if x0 > x1
   then x1, x0, y1, y0
   else x0, x1, y0, y1
 in
 let delta_x = x1 - x0
 and delta_y = abs(y1 - y0) in
 let error = -delta_x / 2
 and y_step =
   if y0 < y1 then 1 else -1
 in
 let rec loop x y error =
   plot x y;
   if x <= x1 then
     let error = error + delta_y in
     let y, error =
       if error > 0
       then (y + y_step), (error - delta_x)
       else y, error
     in
     loop (succ x) y error
 in
 loop x0 y0 error
</ocaml>