LCDInfo.com

http://www.lcdinfo.com
It is currently Sat Nov 23, 2024 3:05

All times are UTC + 2 hours




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Line drawing
PostPosted: Sat Nov 12, 2005 16:40 
Offline
User avatar

Joined: Tue Nov 12, 2002 21:15
Posts: 14
Location: Nijmegen, Netherlands
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.

_________________
If it ain't broken, fix it 'till it is!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 2 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group