1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 #ifndef AGG_MATH_INCLUDED
17 #define AGG_MATH_INCLUDED
20 #include "agg_basics.h"
25 const double intersection_epsilon
= 1.0e-8;
27 //------------------------------------------------------calc_point_location
28 AGG_INLINE
double calc_point_location(double x1
, double y1
,
32 return (x
- x2
) * (y2
- y1
) - (y
- y2
) * (x2
- x1
);
36 //--------------------------------------------------------point_in_triangle
37 AGG_INLINE
bool point_in_triangle(double x1
, double y1
,
42 bool cp1
= calc_point_location(x1
, y1
, x2
, y2
, x
, y
) < 0.0;
43 bool cp2
= calc_point_location(x2
, y2
, x3
, y3
, x
, y
) < 0.0;
44 bool cp3
= calc_point_location(x3
, y3
, x1
, y1
, x
, y
) < 0.0;
45 return cp1
== cp2
&& cp2
== cp3
&& cp3
== cp1
;
49 //-----------------------------------------------------------calc_distance
50 AGG_INLINE
double calc_distance(double x1
, double y1
, double x2
, double y2
)
54 return sqrt(dx
* dx
+ dy
* dy
);
58 //------------------------------------------------calc_point_line_distance
59 AGG_INLINE
double calc_point_line_distance(double x1
, double y1
,
65 return ((x
- x2
) * dy
- (y
- y2
) * dx
) / sqrt(dx
* dx
+ dy
* dy
);
69 //-------------------------------------------------------calc_intersection
70 AGG_INLINE
bool calc_intersection(double ax
, double ay
, double bx
, double by
,
71 double cx
, double cy
, double dx
, double dy
,
74 double num
= (ay
-cy
) * (dx
-cx
) - (ax
-cx
) * (dy
-cy
);
75 double den
= (bx
-ax
) * (dy
-cy
) - (by
-ay
) * (dx
-cx
);
76 if(fabs(den
) < intersection_epsilon
) return false;
78 *x
= ax
+ r
* (bx
-ax
);
79 *y
= ay
+ r
* (by
-ay
);
84 //--------------------------------------------------------calc_orthogonal
85 AGG_INLINE
void calc_orthogonal(double thickness
,
92 double d
= sqrt(dx
*dx
+ dy
*dy
);
93 *x
= thickness
* dy
/ d
;
94 *y
= thickness
* dx
/ d
;
98 //--------------------------------------------------------dilate_triangle
99 AGG_INLINE
void dilate_triangle(double x1
, double y1
,
100 double x2
, double y2
,
101 double x3
, double y3
,
102 double *x
, double* y
,
111 double loc
= calc_point_location(x1
, y1
, x2
, y2
, x3
, y3
);
112 if(fabs(loc
) > intersection_epsilon
)
114 if(calc_point_location(x1
, y1
, x2
, y2
, x3
, y3
) > 0.0)
118 calc_orthogonal(d
, x1
, y1
, x2
, y2
, &dx1
, &dy1
);
119 calc_orthogonal(d
, x2
, y2
, x3
, y3
, &dx2
, &dy2
);
120 calc_orthogonal(d
, x3
, y3
, x1
, y1
, &dx3
, &dy3
);
122 *x
++ = x1
+ dx1
; *y
++ = y1
- dy1
;
123 *x
++ = x2
+ dx1
; *y
++ = y2
- dy1
;
124 *x
++ = x2
+ dx2
; *y
++ = y2
- dy2
;
125 *x
++ = x3
+ dx2
; *y
++ = y3
- dy2
;
126 *x
++ = x3
+ dx3
; *y
++ = y3
- dy3
;
127 *x
++ = x1
+ dx3
; *y
++ = y1
- dy3
;
130 //-------------------------------------------------------calc_polygon_area
131 template<class Storage
> double calc_polygon_area(const Storage
& st
)
140 for(i
= 1; i
< st
.size(); i
++)
142 const typename
Storage::value_type
& v
= st
[i
];
143 sum
+= x
* v
.y
- y
* v
.x
;
147 return (sum
+ x
* ys
- y
* xs
) * 0.5;
150 //------------------------------------------------------------------------
151 // Tables for fast sqrt
152 extern int16u g_sqrt_table
[1024];
153 extern int8 g_elder_bit_table
[256];
156 //---------------------------------------------------------------fast_sqrt
157 //Fast integer Sqrt - really fast: no cycles, divisions or multiplications
158 #if defined(_MSC_VER)
159 #pragma warning(push)
160 #pragma warning(disable : 4035) //Disable warning "no return value"
162 AGG_INLINE
unsigned fast_sqrt(unsigned val
)
164 #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM)
165 //For Ix86 family processors this assembler code is used.
166 //The key command here is bsr - determination the number of the most
167 //significant bit of the value. For other processors
168 //(and maybe compilers) the pure C "#else" section is used.
183 mov ax
, g_sqrt_table
[ebx
*2]
189 //This code is actually pure C and portable to most
190 //arcitectures including 64bit ones.
195 //The following piece of code is just an emulation of the
196 //Ix86 assembler command "bsr" (see above). However on old
197 //Intels (like Intel MMX 233MHz) this code is about twice
198 //faster (sic!) then just one "bsr". On PIII and PIV the
199 //bsr is optimized quite well.
203 bit
= g_elder_bit_table
[bit
] + 24;
207 bit
= (t
>> 16) & 0xFF;
210 bit
= g_elder_bit_table
[bit
] + 16;
214 bit
= (t
>> 8) & 0xFF;
217 bit
= g_elder_bit_table
[bit
] + 8;
221 bit
= g_elder_bit_table
[t
];
226 //This is calculation sqrt itself.
230 bit
= (bit
>> 1) + (bit
& 1);
234 return g_sqrt_table
[val
] >> shift
;
237 #if defined(_MSC_VER)