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

agg_math.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 #ifndef AGG_MATH_INCLUDED
00017 #define AGG_MATH_INCLUDED
00018 
00019 #include <math.h>
00020 #include "agg_basics.h"
00021 
00022 namespace agg
00023 {
00024 
00025     const double intersection_epsilon = 1.0e-8;
00026 
00027     //------------------------------------------------------calc_point_location
00028     inline double calc_point_location(double x1, double y1, 
00029                                       double x2, double y2, 
00030                                       double x,  double y)
00031     {
00032         return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
00033     }
00034 
00035 
00036     //--------------------------------------------------------point_in_triangle
00037     inline bool point_in_triangle(double x1, double y1, 
00038                                   double x2, double y2, 
00039                                   double x3, double y3, 
00040                                   double x,  double y)
00041     {
00042         bool cp1 = calc_point_location(x1, y1, x2, y2, x, y) < 0.0;
00043         bool cp2 = calc_point_location(x2, y2, x3, y3, x, y) < 0.0;
00044         bool cp3 = calc_point_location(x3, y3, x1, y1, x, y) < 0.0;
00045         return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
00046     }
00047 
00048 
00049     //-----------------------------------------------------------calc_distance
00050     inline double calc_distance(double x1, double y1, double x2, double y2)
00051     {
00052         double dx = x2-x1;
00053         double dy = y2-y1;
00054         return sqrt(dx * dx + dy * dy);
00055     }
00056 
00057 
00058     //------------------------------------------------calc_point_line_distance
00059     inline double calc_point_line_distance(double x1, double y1, 
00060                                            double x2, double y2, 
00061                                            double x,  double y)
00062     {
00063         double dx = x2-x1;
00064         double dy = y2-y1;
00065         return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy);
00066     }
00067 
00068 
00069     //-------------------------------------------------------calc_intersection
00070     inline bool calc_intersection(double ax, double ay, double bx, double by,
00071                                   double cx, double cy, double dx, double dy,
00072                                   double* x, double* y)
00073     {
00074         double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
00075         double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
00076         if(fabs(den) < intersection_epsilon) return false;
00077         double r = num / den;
00078         *x = ax + r * (bx-ax);
00079         *y = ay + r * (by-ay);
00080         return true;
00081     }
00082 
00083 
00084     //--------------------------------------------------------calc_orthogonal
00085     inline void calc_orthogonal(double thickness,
00086                                 double x1, double y1,
00087                                 double x2, double y2,
00088                                 double* x, double* y)
00089     {
00090         double dx = x2 - x1;
00091         double dy = y2 - y1;
00092         double d = sqrt(dx*dx + dy*dy); 
00093         *x = thickness * dy / d;
00094         *y = thickness * dx / d;
00095     }
00096 
00097 
00098     //--------------------------------------------------------dilate_triangle
00099     inline void dilate_triangle(double x1, double y1,
00100                                 double x2, double y2,
00101                                 double x3, double y3,
00102                                 double *x, double* y,
00103                                 double d)
00104     {
00105         double dx1=0.0;
00106         double dy1=0.0; 
00107         double dx2=0.0;
00108         double dy2=0.0; 
00109         double dx3=0.0;
00110         double dy3=0.0; 
00111         double loc = calc_point_location(x1, y1, x2, y2, x3, y3);
00112         if(fabs(loc) > intersection_epsilon)
00113         {
00114             if(calc_point_location(x1, y1, x2, y2, x3, y3) > 0.0) 
00115             {
00116                 d = -d;
00117             }
00118             calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
00119             calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
00120             calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
00121         }
00122         *x++ = x1 + dx1;  *y++ = y1 - dy1;
00123         *x++ = x2 + dx1;  *y++ = y2 - dy1;
00124         *x++ = x2 + dx2;  *y++ = y2 - dy2;
00125         *x++ = x3 + dx2;  *y++ = y3 - dy2;
00126         *x++ = x3 + dx3;  *y++ = y3 - dy3;
00127         *x++ = x1 + dx3;  *y++ = y1 - dy3;
00128     }
00129 
00130     //-------------------------------------------------------calc_polygon_area
00131     template<class Storage> double calc_polygon_area(const Storage& st)
00132     {
00133         unsigned i;
00134         double sum = 0.0;
00135         double x  = st[0].x;
00136         double y  = st[0].y;
00137         double xs = x;
00138         double ys = y;
00139 
00140         for(i = 1; i < st.size(); i++)
00141         {
00142             const typename Storage::value_type& v = st[i];
00143             sum += x * v.y - y * v.x;
00144             x = v.x;
00145             y = v.y;
00146         }
00147         return (sum + x * ys - y * xs) * 0.5;
00148     }
00149 
00150     //------------------------------------------------------------------------
00151     // Tables for fast sqrt
00152     extern int16u g_sqrt_table[1024];
00153     extern int8   g_elder_bit_table[256];
00154 
00155 
00156     //---------------------------------------------------------------fast_sqrt
00157     //Fast integer Sqrt - really fast: no cycles, divisions or multiplications
00158     #if defined(_MSC_VER)
00159     #pragma warning(push)
00160     #pragma warning(disable : 4035) //Disable warning "no return value"
00161     #endif
00162     inline unsigned fast_sqrt(unsigned val)
00163     {
00164     #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
00165         //For Ix86 family processors this assembler code is used. 
00166         //The key command here is bsr - determination the number of the most 
00167         //significant bit of the value. For other processors
00168         //(and maybe compilers) the pure C "#else" section is used.
00169         __asm
00170         {
00171             mov ebx, val
00172             mov edx, 11
00173             bsr ecx, ebx
00174             sub ecx, 9
00175             jle less_than_9_bits
00176             shr ecx, 1
00177             adc ecx, 0
00178             sub edx, ecx
00179             shl ecx, 1
00180             shr ebx, cl
00181     less_than_9_bits:
00182             xor eax, eax
00183             mov  ax, g_sqrt_table[ebx*2]
00184             mov ecx, edx
00185             shr eax, cl
00186         }
00187     #else
00188 
00189         //This code is actually pure C and portable to most 
00190         //arcitectures including 64bit ones. 
00191         unsigned t = val;
00192         int bit=0;
00193         unsigned shift = 11;
00194 
00195         //The following piece of code is just an emulation of the
00196         //Ix86 assembler command "bsr" (see above). However on old
00197         //Intels (like Intel MMX 233MHz) this code is about twice 
00198         //faster (sic!) then just one "bsr". On PIII and PIV the
00199         //bsr is optimized quite well.
00200         bit = t >> 24;
00201         if(bit)
00202         {
00203             bit = g_elder_bit_table[bit] + 24;
00204         }
00205         else
00206         {
00207             bit = (t >> 16) & 0xFF;
00208             if(bit)
00209             {
00210                 bit = g_elder_bit_table[bit] + 16;
00211             }
00212             else
00213             {
00214                 bit = (t >> 8) & 0xFF;
00215                 if(bit)
00216                 {
00217                     bit = g_elder_bit_table[bit] + 8;
00218                 }
00219                 else
00220                 {
00221                     bit = g_elder_bit_table[t];
00222                 }
00223             }
00224         }
00225 
00226         //This is calculation sqrt itself.
00227         bit -= 9;
00228         if(bit > 0)
00229         {
00230             bit = (bit >> 1) + (bit & 1);
00231             shift -= bit;
00232             val >>= (bit << 1);
00233         }
00234         return g_sqrt_table[val] >> shift;
00235     #endif
00236     }
00237     #if defined(_MSC_VER)
00238     #pragma warning(pop)
00239     #endif
00240 
00241 
00242 
00243 
00244 }
00245 
00246 
00247 #endif

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