Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages | Examples

agg_clip_liang_barsky.h

00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry - Version 2.2
00003 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
00004 //
00005 // Permission to copy, use, modify, sell and distribute this software 
00006 // is granted provided this copyright notice appears in all copies. 
00007 // This software is provided "as is" without express or implied
00008 // warranty, and with no claim as to its suitability for any purpose.
00009 //
00010 //----------------------------------------------------------------------------
00011 // Contact: mcseem@antigrain.com
00012 //          mcseemagg@yahoo.com
00013 //          http://www.antigrain.com
00014 //----------------------------------------------------------------------------
00015 //
00016 // Liang-Barsky clipping 
00017 //
00018 //----------------------------------------------------------------------------
00019 #ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED
00020 #define AGG_CLIP_LIANG_BARSKY_INCLUDED
00021 
00022 #include "agg_basics.h"
00023 
00024 namespace agg
00025 {
00026 
00027     //----------------------------------------------------------clipping_flags
00028     // Determine the clipping code of the vertex according to the 
00029     // Cyrus-Beck line clipping algorithm
00030     //
00031     //        |        |
00032     //  0110  |  0010  | 0011
00033     //        |        |
00034     // -------+--------+-------- clip_box.y2
00035     //        |        |
00036     //  0100  |  0000  | 0001
00037     //        |        |
00038     // -------+--------+-------- clip_box.y1
00039     //        |        |
00040     //  1100  |  1000  | 1001
00041     //        |        |
00042     //  clip_box.x1  clip_box.x2
00043     //
00044     // 
00045     template<class T>
00046     inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
00047     {
00048         return  (x > clip_box.x2) |
00049                ((y > clip_box.y2) << 1) |
00050                ((x < clip_box.x1) << 2) |
00051                ((y < clip_box.y1) << 3);
00052     }
00053 
00054 
00055 
00056     //-------------------------------------------------------clip_liang_barsky
00057     template<class T>
00058     inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
00059                                       const rect_base<T>& clip_box,
00060                                       T* x, T* y)
00061     {
00062         const double nearzero = 1e-30;
00063 
00064         double deltax = x2 - x1;
00065         double deltay = y2 - y1; 
00066         double xin;
00067         double xout;
00068         double yin;
00069         double yout;
00070         double tinx;
00071         double tiny;
00072         double toutx;
00073         double touty;  
00074         double tin1;
00075         double tin2;
00076         double tout1;
00077         unsigned np = 0;
00078 
00079         if(deltax == 0.0) 
00080         {   
00081             // bump off of the vertical
00082             deltax = (x1 > clip_box.x1) ? -nearzero : nearzero;
00083         }
00084 
00085         if(deltay == 0.0) 
00086         { 
00087             // bump off of the horizontal 
00088             deltay = (y1 > clip_box.y1) ? -nearzero : nearzero;
00089         }
00090         
00091         if(deltax > 0.0) 
00092         {                
00093             // points to right
00094             xin  = clip_box.x1;
00095             xout = clip_box.x2;
00096         }
00097         else 
00098         {
00099             xin  = clip_box.x2;
00100             xout = clip_box.x1;
00101         }
00102 
00103         if(deltay > 0.0) 
00104         {
00105             // points up
00106             yin  = clip_box.y1;
00107             yout = clip_box.y2;
00108         }
00109         else 
00110         {
00111             yin  = clip_box.y2;
00112             yout = clip_box.y1;
00113         }
00114         
00115         tinx = (xin - x1) / deltax;
00116         tiny = (yin - y1) / deltay;
00117         
00118         if (tinx < tiny) 
00119         {
00120             // hits x first
00121             tin1 = tinx;
00122             tin2 = tiny;
00123         }
00124         else
00125         {
00126             // hits y first
00127             tin1 = tiny;
00128             tin2 = tinx;
00129         }
00130         
00131         if(tin1 <= 1.0) 
00132         {
00133             if(0.0 < tin1) 
00134             {
00135                 *x++ = (T)xin;
00136                 *y++ = (T)yin;
00137                 ++np;
00138             }
00139 
00140             if(tin2 <= 1.0)
00141             {
00142                 toutx = (xout - x1) / deltax;
00143                 touty = (yout - y1) / deltay;
00144                 
00145                 tout1 = (toutx < touty) ? toutx : touty;
00146                 
00147                 if(tin2 > 0.0 || tout1 > 0.0) 
00148                 {
00149                     if(tin2 <= tout1) 
00150                     {
00151                         if(tin2 > 0.0) 
00152                         {
00153                             if(tinx > tiny) 
00154                             {
00155                                 *x++ = (T)xin;
00156                                 *y++ = (T)(y1 + tinx * deltay);
00157                             }
00158                             else 
00159                             {
00160                                 *x++ = (T)(x1 + tiny * deltax);
00161                                 *y++ = (T)yin;
00162                             }
00163                             ++np;
00164                         }
00165 
00166                         if(tout1 < 1.0) 
00167                         {
00168                             if(toutx < touty) 
00169                             {
00170                                 *x++ = (T)xout;
00171                                 *y++ = (T)(y1 + toutx * deltay);
00172                             }
00173                             else 
00174                             {
00175                                 *x++ = (T)(x1 + touty * deltax);
00176                                 *y++ = (T)yout;
00177                             }
00178                         }
00179                         else 
00180                         {
00181                             *x++ = x2;
00182                             *y++ = y2;
00183                         }
00184                         ++np;
00185                     }
00186                     else 
00187                     {
00188                         if(tinx > tiny) 
00189                         {
00190                             *x++ = (T)xin;
00191                             *y++ = (T)yout;
00192                         }
00193                         else 
00194                         {
00195                             *x++ = (T)xout;
00196                             *y++ = (T)yin;
00197                         }
00198                         ++np;
00199                     }
00200                 }
00201             }
00202         }
00203         return np;
00204     }
00205     
00206 
00207 }
00208 
00209 #endif

Generated on Wed Feb 9 11:31:34 2005 for OpenGUI by  doxygen 1.4.0