iforce2d Chris / Mbed 2 deprecated ubxDistanceMeter

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers u8g_ellipse.c Source File

u8g_ellipse.c

00001 /*
00002 
00003   u8g_ellipse.c
00004 
00005   Utility to draw empty and filled ellipses.
00006   
00007   Universal 8bit Graphics Library
00008   
00009   Copyright (c) 2011, bjthom@gmail.com
00010   All rights reserved.
00011 
00012   Redistribution and use in source and binary forms, with or without modification, 
00013   are permitted provided that the following conditions are met:
00014 
00015   * Redistributions of source code must retain the above copyright notice, this list 
00016     of conditions and the following disclaimer.
00017     
00018   * Redistributions in binary form must reproduce the above copyright notice, this 
00019     list of conditions and the following disclaimer in the documentation and/or other 
00020     materials provided with the distribution.
00021 
00022   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
00023   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
00024   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00025   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
00027   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00028   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
00029   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
00030   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00031   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
00032   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00033   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00034   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00035   
00036   Addition to the U8G Library as of 02/29/12
00037   Adapted from Bresenham's Algorithm and the following websites:
00038     http://free.pages.at/easyfilter/bresenham.html
00039     http://homepage.smc.edu/kennedy_john/belipse.pdf
00040   
00041 */
00042 
00043 #include "u8g.h"
00044 
00045 
00046 #ifdef WORK_IN_PROGRESS
00047 
00048 void u8g_DrawEllipseRect(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t x1, u8g_uint_t y1)
00049 {
00050     int a = abs(x1 - x0);
00051     int b = abs(y1 - y0);   //get diameters
00052     int b1 = b&1;
00053     long dx = 4*(1-a)*b*b;
00054     long dy = 4*(b1+1)*a*a;
00055     long err = dx+dy+b1*a*a;
00056     long e2;
00057     
00058     if (x0 > x1) { x0 = x1; x1 += a; }
00059     if (y0 > y1) { y0 = y1; } 
00060     y0 += (b+1)/2;
00061     y1 = y0-b1;
00062     a *= 8*a;
00063     b1 = 8*b*b;
00064     
00065     do {
00066         u8g_DrawPixel(u8g, x1, y0);
00067         u8g_DrawPixel(u8g, x0, y0);
00068         u8g_DrawPixel(u8g, x0, y1);
00069         u8g_DrawPixel(u8g, x1, y1);
00070         e2 = 2*err;
00071         if (e2 >= dx) {
00072             x0++;
00073             x1--;
00074             err += dx += b1;
00075         }
00076         if (e2 <= dy) {
00077             y0++;
00078             y1--;
00079             err += dy += a;
00080         }
00081     } while (x0 <= x1);
00082     
00083     while (y0-y1 < b) {
00084         u8g_DrawPixel(u8g, x0-1, y0);
00085         u8g_DrawPixel(u8g, x1+1, y0++);
00086         u8g_DrawPixel(u8g, x0-1, y1);
00087         u8g_DrawPixel(u8g, x1+1, y1--);
00088     }
00089 }
00090 
00091 void u8g_DrawEllipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t xr, u8g_uint_t yr)
00092 {
00093     u8g_DrawPixel(u8g, x0, y0+yr);
00094     u8g_DrawPixel(u8g, x0, y0-yr);
00095     u8g_DrawPixel(u8g, x0+xr, y0);
00096     u8g_DrawPixel(u8g, x0-xr, y0);
00097 }
00098 
00099 #endif
00100 
00101 #if defined(U8G_16BIT)
00102 typedef  int32_t u8g_long_t;
00103 #else
00104 typedef  int16_t u8g_long_t;
00105 #endif
00106 
00107 
00108 /*
00109   Source: 
00110     ftp://pc.fk0.name/pub/books/programming/bezier-ellipse.pdf
00111     Foley, Computer Graphics, p 90
00112 */
00113 static void u8g_draw_ellipse_section(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t x0, u8g_uint_t y0, uint8_t option) U8G_NOINLINE;
00114 static void u8g_draw_ellipse_section(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t x0, u8g_uint_t y0, uint8_t option)
00115 {
00116     /* upper right */
00117     if ( option & U8G_DRAW_UPPER_RIGHT )
00118     {
00119       u8g_DrawPixel(u8g, x0 + x, y0 - y);
00120     }
00121     
00122     /* upper left */
00123     if ( option & U8G_DRAW_UPPER_LEFT )
00124     {
00125       u8g_DrawPixel(u8g, x0 - x, y0 - y);
00126     }
00127     
00128     /* lower right */
00129     if ( option & U8G_DRAW_LOWER_RIGHT )
00130     {
00131       u8g_DrawPixel(u8g, x0 + x, y0 + y);
00132     }
00133     
00134     /* lower left */
00135     if ( option & U8G_DRAW_LOWER_LEFT )
00136     {
00137       u8g_DrawPixel(u8g, x0 - x, y0 + y);
00138     }
00139 }
00140 
00141 void u8g_draw_ellipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rx, u8g_uint_t ry, uint8_t option)
00142 {
00143   u8g_uint_t x, y;
00144   u8g_long_t xchg, ychg;
00145   u8g_long_t err;
00146   u8g_long_t rxrx2;
00147   u8g_long_t ryry2;
00148   u8g_long_t stopx, stopy;
00149   
00150   rxrx2 = rx;
00151   rxrx2 *= rx;
00152   rxrx2 *= 2;
00153   
00154   ryry2 = ry;
00155   ryry2 *= ry;
00156   ryry2 *= 2;
00157   
00158   x = rx;
00159   y = 0;
00160   
00161   xchg = 1;
00162   xchg -= rx;
00163   xchg -= rx;
00164   xchg *= ry;
00165   xchg *= ry;
00166   
00167   ychg = rx;
00168   ychg *= rx;
00169   
00170   err = 0;
00171   
00172   stopx = ryry2;
00173   stopx *= rx;
00174   stopy = 0;
00175   
00176   while( stopx >= stopy )
00177   {
00178     u8g_draw_ellipse_section(u8g, x, y, x0, y0, option);
00179     y++;
00180     stopy += rxrx2;
00181     err += ychg;
00182     ychg += rxrx2;
00183     if ( 2*err+xchg > 0 )
00184     {
00185       x--;
00186       stopx -= ryry2;
00187       err += xchg;
00188       xchg += ryry2;      
00189     }
00190   }
00191 
00192   x = 0;
00193   y = ry;
00194   
00195   xchg = ry;
00196   xchg *= ry;
00197   
00198   ychg = 1;
00199   ychg -= ry;
00200   ychg -= ry;
00201   ychg *= rx;
00202   ychg *= rx;
00203   
00204   err = 0;
00205   
00206   stopx = 0;
00207 
00208   stopy = rxrx2;
00209   stopy *= ry;
00210   
00211 
00212   while( stopx <= stopy )
00213   {
00214     u8g_draw_ellipse_section(u8g, x, y, x0, y0, option);
00215     x++;
00216     stopx += ryry2;
00217     err += xchg;
00218     xchg += ryry2;
00219     if ( 2*err+ychg > 0 )
00220     {
00221       y--;
00222       stopy -= rxrx2;
00223       err += ychg;
00224       ychg += rxrx2;
00225     }
00226   }
00227   
00228 }
00229 
00230 void u8g_DrawEllipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rx, u8g_uint_t ry, uint8_t option)
00231 {
00232   /* check for bounding box */
00233   {
00234     u8g_uint_t rxp, rxp2;
00235     u8g_uint_t ryp, ryp2;
00236     
00237     rxp = rx;
00238     rxp++;
00239     rxp2 = rxp;
00240     rxp2 *= 2;
00241 
00242     ryp = ry;
00243     ryp++;
00244     ryp2 = ryp;
00245     ryp2 *= 2;
00246     
00247     if ( u8g_IsBBXIntersection(u8g, x0-rxp, y0-ryp, rxp2, ryp2) == 0)
00248       return;    
00249   }
00250   
00251   u8g_draw_ellipse(u8g, x0, y0, rx, ry, option);
00252 }
00253 
00254 static void u8g_draw_filled_ellipse_section(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t x0, u8g_uint_t y0, uint8_t option) U8G_NOINLINE;
00255 static void u8g_draw_filled_ellipse_section(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, u8g_uint_t x0, u8g_uint_t y0, uint8_t option)
00256 {
00257     /* upper right */
00258     if ( option & U8G_DRAW_UPPER_RIGHT )
00259     {
00260       u8g_DrawVLine(u8g, x0+x, y0-y, y+1);
00261     }
00262     
00263     /* upper left */
00264     if ( option & U8G_DRAW_UPPER_LEFT )
00265     {
00266       u8g_DrawVLine(u8g, x0-x, y0-y, y+1);
00267     }
00268     
00269     /* lower right */
00270     if ( option & U8G_DRAW_LOWER_RIGHT )
00271     {
00272       u8g_DrawVLine(u8g, x0+x, y0, y+1);
00273     }
00274     
00275     /* lower left */
00276     if ( option & U8G_DRAW_LOWER_LEFT )
00277     {
00278       u8g_DrawVLine(u8g, x0-x, y0, y+1);
00279     }
00280 }
00281 
00282 void u8g_draw_filled_ellipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rx, u8g_uint_t ry, uint8_t option)
00283 {
00284   u8g_uint_t x, y;
00285   u8g_long_t xchg, ychg;
00286   u8g_long_t err;
00287   u8g_long_t rxrx2;
00288   u8g_long_t ryry2;
00289   u8g_long_t stopx, stopy;
00290   
00291   rxrx2 = rx;
00292   rxrx2 *= rx;
00293   rxrx2 *= 2;
00294   
00295   ryry2 = ry;
00296   ryry2 *= ry;
00297   ryry2 *= 2;
00298   
00299   x = rx;
00300   y = 0;
00301   
00302   xchg = 1;
00303   xchg -= rx;
00304   xchg -= rx;
00305   xchg *= ry;
00306   xchg *= ry;
00307   
00308   ychg = rx;
00309   ychg *= rx;
00310   
00311   err = 0;
00312   
00313   stopx = ryry2;
00314   stopx *= rx;
00315   stopy = 0;
00316   
00317   while( stopx >= stopy )
00318   {
00319     u8g_draw_filled_ellipse_section(u8g, x, y, x0, y0, option);
00320     y++;
00321     stopy += rxrx2;
00322     err += ychg;
00323     ychg += rxrx2;
00324     if ( 2*err+xchg > 0 )
00325     {
00326       x--;
00327       stopx -= ryry2;
00328       err += xchg;
00329       xchg += ryry2;      
00330     }
00331   }
00332 
00333   x = 0;
00334   y = ry;
00335   
00336   xchg = ry;
00337   xchg *= ry;
00338   
00339   ychg = 1;
00340   ychg -= ry;
00341   ychg -= ry;
00342   ychg *= rx;
00343   ychg *= rx;
00344   
00345   err = 0;
00346   
00347   stopx = 0;
00348 
00349   stopy = rxrx2;
00350   stopy *= ry;
00351   
00352 
00353   while( stopx <= stopy )
00354   {
00355     u8g_draw_filled_ellipse_section(u8g, x, y, x0, y0, option);
00356     x++;
00357     stopx += ryry2;
00358     err += xchg;
00359     xchg += ryry2;
00360     if ( 2*err+ychg > 0 )
00361     {
00362       y--;
00363       stopy -= rxrx2;
00364       err += ychg;
00365       ychg += rxrx2;
00366     }
00367   }
00368   
00369 }
00370 
00371 void u8g_DrawFilledEllipse(u8g_t *u8g, u8g_uint_t x0, u8g_uint_t y0, u8g_uint_t rx, u8g_uint_t ry, uint8_t option)
00372 {
00373   /* check for bounding box */
00374   {
00375     u8g_uint_t rxp, rxp2;
00376     u8g_uint_t ryp, ryp2;
00377     
00378     rxp = rx;
00379     rxp++;
00380     rxp2 = rxp;
00381     rxp2 *= 2;
00382 
00383     ryp = ry;
00384     ryp++;
00385     ryp2 = ryp;
00386     ryp2 *= 2;
00387     
00388     if ( u8g_IsBBXIntersection(u8g, x0-rxp, y0-ryp, rxp2, ryp2) == 0)
00389       return;    
00390   }
00391   
00392   u8g_draw_filled_ellipse(u8g, x0, y0, rx, ry, option);
00393 }
00394