00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
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
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
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
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
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
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
00152 extern int16u g_sqrt_table[1024];
00153 extern int8 g_elder_bit_table[256];
00154
00155
00156
00157
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
00166
00167
00168
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
00190
00191 unsigned t = val;
00192 int bit=0;
00193 unsigned shift = 11;
00194
00195
00196
00197
00198
00199
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
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