19 #ifndef AGG_MATH_INCLUDED 20 #define AGG_MATH_INCLUDED 23 #include "agg_basics.h" 30 const double vertex_dist_epsilon = 1e-14;
34 const double intersection_epsilon = 1.0e-30;
37 AGG_INLINE
double cross_product(
double x1,
double y1,
41 return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
45 AGG_INLINE
bool point_in_triangle(
double x1,
double y1,
50 bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
51 bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
52 bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
53 return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
57 AGG_INLINE
double calc_distance(
double x1,
double y1,
double x2,
double y2)
61 return std::sqrt(dx * dx + dy * dy);
65 AGG_INLINE
double calc_sq_distance(
double x1,
double y1,
double x2,
double y2)
69 return dx * dx + dy * dy;
73 AGG_INLINE
double calc_line_point_distance(
double x1,
double y1,
79 double d = std::sqrt(dx * dx + dy * dy);
80 if(d < vertex_dist_epsilon)
82 return calc_distance(x1, y1, x, y);
84 return ((x - x2) * dy - (y - y2) * dx) / d;
88 AGG_INLINE
double calc_segment_point_u(
double x1,
double y1,
95 if(dx == 0 && dy == 0)
103 return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
107 AGG_INLINE
double calc_segment_point_sq_distance(
double x1,
double y1,
108 double x2,
double y2,
114 return calc_sq_distance(x, y, x1, y1);
119 return calc_sq_distance(x, y, x2, y2);
121 return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
125 AGG_INLINE
double calc_segment_point_sq_distance(
double x1,
double y1,
126 double x2,
double y2,
130 calc_segment_point_sq_distance(
131 x1, y1, x2, y2, x, y,
132 calc_segment_point_u(x1, y1, x2, y2, x, y));
136 AGG_INLINE
bool calc_intersection(
double ax,
double ay,
double bx,
double by,
137 double cx,
double cy,
double dx,
double dy,
138 double* x,
double* y)
140 double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy);
141 double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx);
142 if(std::fabs(den) < intersection_epsilon)
return false;
143 double r = num / den;
144 *x = ax + r * (bx-ax);
145 *y = ay + r * (by-ay);
150 AGG_INLINE
bool intersection_exists(
double x1,
double y1,
double x2,
double y2,
151 double x3,
double y3,
double x4,
double y4)
155 double dx1 = x2 - x1;
156 double dy1 = y2 - y1;
157 double dx2 = x4 - x3;
158 double dy2 = y4 - y3;
159 return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
160 ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
161 ((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
162 ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
177 AGG_INLINE
void calc_orthogonal(
double thickness,
178 double x1,
double y1,
179 double x2,
double y2,
180 double* x,
double* y)
184 double d = std::sqrt(dx*dx + dy*dy);
185 *x = thickness * dy / d;
186 *y = -thickness * dx / d;
190 AGG_INLINE
void dilate_triangle(
double x1,
double y1,
191 double x2,
double y2,
192 double x3,
double y3,
193 double *x,
double* y,
202 double loc = cross_product(x1, y1, x2, y2, x3, y3);
203 if(std::fabs(loc) > intersection_epsilon)
205 if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
209 calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1);
210 calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
211 calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
213 *x++ = x1 + dx1; *y++ = y1 + dy1;
214 *x++ = x2 + dx1; *y++ = y2 + dy1;
215 *x++ = x2 + dx2; *y++ = y2 + dy2;
216 *x++ = x3 + dx2; *y++ = y3 + dy2;
217 *x++ = x3 + dx3; *y++ = y3 + dy3;
218 *x++ = x1 + dx3; *y++ = y1 + dy3;
222 AGG_INLINE
double calc_triangle_area(
double x1,
double y1,
223 double x2,
double y2,
224 double x3,
double y3)
226 return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
230 template<
class Storage>
double calc_polygon_area(
const Storage& st)
239 for(i = 1; i < st.size(); i++)
241 const typename Storage::value_type& v = st[i];
242 sum += x * v.y - y * v.x;
246 return (sum + x * ys - y * xs) * 0.5;
251 extern int16u g_sqrt_table[1024];
252 extern int8 g_elder_bit_table[256];
257 #if defined(_MSC_VER) 258 #pragma warning(push) 259 #pragma warning(disable : 4035) //Disable warning "no return value" 261 AGG_INLINE
unsigned fast_sqrt(
unsigned val)
263 #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM) 282 mov ax, g_sqrt_table[ebx*2]
302 bit = g_elder_bit_table[bit] + 24;
306 bit = (t >> 16) & 0xFF;
309 bit = g_elder_bit_table[bit] + 16;
313 bit = (t >> 8) & 0xFF;
316 bit = g_elder_bit_table[bit] + 8;
320 bit = g_elder_bit_table[t];
329 bit = (bit >> 1) + (bit & 1);
333 return g_sqrt_table[val] >> shift;
336 #if defined(_MSC_VER) 365 inline double besj(
double x,
int n)
373 if(std::fabs(x) <= d)
380 int m1 = (int)std::fabs(x) + 6;
383 m1 = (int)(std::fabs(1.4 * x + 60 / x));
385 int m2 = (int)(n + 2 + std::fabs(x) / 4);
398 if (m2 / 2 * 2 == m2)
403 for (
int i = 1; i <= imax; i++)
405 double c6 = 2 * (m2 - i) * c2 / x - c3;
418 double c6 = 2 * c2 / x - c3;
425 if(std::fabs(b - b1) < d)