Bresenham line drawing algorithm development


Notes:


Here are the assumptions:



Simple Line Equation

/* uses y=mx+b to calculate y from x */

dy = y2-y1;
dx = x2-x1;
m = dy/dx;
b = y1-m*x1;
for (x=x1; x<=x2; x++) {
  y=m*x+b;
  plot(x,round(y));
}

Get Rid of F.P. Multiply Used to Update 'Y'

/* increment y from one x to the next            */
/* instead of calculating from scratch each time */

dy = y2-y1;
dx = x2-x1;
m = dy/dx;
y = y1;                              /* <------------ */
for (x=x1; x<=x2; x++) {
  y=y+m;                             /* <------------ */
  plot(x,round(y));
}

Get Rid of F.P. Round Function

/* split y into integer and fraction parts */

dy = y2-y1;
dx = x2-x1;
m = dy/dx;
y = y1;
f = 0;                             /* <------------ */
for (x=x1; x<=x2; x++) {
  f=f+m;                           /* <------------ */
  plot(x,y);
  if (f>0.5) {                     /* <------------ */
    y = y+1;
    f = f-1;                       /* <------------ */
  }
}

Use f Scaled up by dx

/* use f*dx in place of old f so dy can be used to update f */
/* instead of f.p rational value of 'm'                     */
/* eed to scale up all modifications  and tests of 'f'      */

dy = y2-y1;
dx = x2-x1;
y = y1;
f = 0;
for (x=x1; x<=x2; x++) {
  f=f+dy;                                  /* <------------ */
  plot(x,y);
  if (f>(dx/2)) {                          /* <------------ */
    y = y+1;
    f = f-dx;                              /* <------------ */
  }
}

Use f Scaled up by 2

/* use f*2 instead of old f
/* get rid of divide by 2 at 'if' statement                     */
/* eed to scale up all modifications  and tests of 'f' by 2     */

dy = y2-y1;
dx = x2-x1;
y = y1;
f = 0;
for (x=x1; x<=x2; x++) {
  f=f+2*dy;                          /* <------------ */
  plot(x,y);
  if (f>dx) {                        /* <------------ */
    y = y+1;
    f = f-2*dx;                      /* <------------ */
  }
}

Use f translated down by dx

/* use f-dx instead of old f */
/* get rid of comparison to non-zero value */

dy = y2-y1;
dx = x2-x1;
y = y1;
f = -dx;                                /* <------------ */
for (x=x1; x<=x2; x++){
  f=f+2*dy;
  plot(x,y);
  if (f>0)                             /* <------------ */
    y = y+1;
    f = f-2*dx;
  }
}

Use if-then-else

/*  get rid of twice changing f */

dy = y2-y1;
dx = x2-x1;
y = y1;
f = -dx;
for (x=x1; x<=x2; x++) {
  plot(x,y);
  if (f>0) {                             
    y = y+1;
    f = 2*(dy-dx);                    /* <------------ */
  }
  else
    f = f+2*dy;
}

Use precalculated values to get computation out of loop

dy = y2-y1;
dx = x2-x1;
y = y1;
f = -dx;
incrE = 2*dy;                          /* <------------ */
incrNE = 2*(dy-dx);                    /* <------------ */
for (x=x1; x<=x2; x++) {
  plot(x,y);
  if (f>0) {
    y = y+1;
    f = f + incrNE;                    /* <------------ */
  }
  else
    f = f + incrE;                     /* <------------ */
}

Take endpoint computation out of loop

dy = y2-y1;
dx = x2-x1;
y = y1;
f = 2*dy-dx;
incrE = 2*dy;
incrNE = 2*(dy-dx);

plot(x1,y1);                         /* <------------ */
for (x=x1+1; x< x++) {          /* <------------ */
  plot(x,y);
  if (f>0) {
    y = y+1;
    f = f + incrNE;
  }
  else
    f = f + incrE;
}
plot(x2,y2);                        /* <------------ */

Now look at how efficient the program is!