LCDInfo.com
http://forum.lcdinfo.com/

Line drawing
http://forum.lcdinfo.com/viewtopic.php?f=17&t=1409
Page 1 of 1

Author:  Remboooo [ Sat Nov 12, 2005 16:40 ]
Post subject:  Line drawing

I noticed, when using the TimeInfo plugin with the analog clock bitmap, that the line drawing routine in the SDK is far from ideal; at some slopes, the line is discontinuous. So I browsed around the internet and found a great routine that produces flawless lines (Bresenham's line drawing routine), and it's probably faster than the routine that was implemented in the SDK. I modified it to work in lcdbitmap.h:

Code:
   void line(unsigned int X1, unsigned int Y1, unsigned int X2, unsigned int Y2, PixelStyle style)
   { 
      assert(X1 <= m_width-1);
      assert(Y1 <= m_height-1);
      assert(X2 <= m_width-1);
      assert(Y2 <= m_height-1);

      // these if's make sure we only use the relatively expensive algorithm if we're drawing a sloping line
      if ((Y1 == Y2) && (X1 == X2)) {
         setPixel(X1, Y1, style);
      }
      else if (Y1 == Y2) {
         hLine((X1<X2)?X1:X2, Y1, (X1<X2)?X2-X1:X1-X2, style);
      }
      else if (X1 == X2) {
         vLine(X1, (Y1<Y2)?Y1:Y2, (Y1<Y2)?Y2-Y1:Y1-Y2, style);
      }
      else {

         int dy = Y2 - Y1;
         int dx = X2 - X1;
         int stepx, stepy;

         if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
         if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
         dy <<= 1;                                                  // dy is now 2*dy
         dx <<= 1;                                                  // dx is now 2*dx

         setPixel(X1, Y1, style);
         if (dx > dy) {
            int fraction = dy - (dx >> 1);                         // same as 2*dy - dx
            while (X1 != X2) {
               if (fraction >= 0) {
                  Y1 += stepy;
                  fraction -= dx;                                // same as fraction -= 2*dx
               }
               X1 += stepx;
               fraction += dy;                                    // same as fraction -= 2*dy
               setPixel(X1, Y1, style);
            }
         } else {
            int fraction = dx - (dy >> 1);
            while (Y1 != Y2) {
               if (fraction >= 0) {
                  X1 += stepx;
                  fraction -= dy;
               }
               Y1 += stepy;
               fraction += dx;
               setPixel(X1, Y1, style);
            }
         }
      }
   }


I recompiled the TimeInfo plugin with this new routine and it works brilliantly.
You can download the modified version of lcdbitmap.h here.

The algorithm I use is almost directly copied from this page, step 3

-edit-
I ran into a rounding error which caused degreeLine() to draw sloped lines at angles like 90°. Now that's fixed too in this new lcdbitmap.h.

Page 1 of 1 All times are UTC + 2 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/