1 |
|
/***************************************************************************/ |
2 |
|
/* */ |
3 |
|
/* afangles.c */ |
4 |
|
/* */ |
5 |
|
/* Routines used to compute vector angles with limited accuracy */ |
6 |
|
/* and very high speed. It also contains sorting routines (body). */ |
7 |
|
/* */ |
8 |
|
/* Copyright 2003, 2004, 2005 by */ |
9 |
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
10 |
|
/* */ |
11 |
|
/* This file is part of the FreeType project, and may only be used, */ |
12 |
|
/* modified, and distributed under the terms of the FreeType project */ |
13 |
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
14 |
|
/* this file you indicate that you have read the license and */ |
15 |
|
/* understand and accept it fully. */ |
16 |
|
/* */ |
17 |
|
/***************************************************************************/ |
18 |
|
|
19 |
|
|
20 |
#include "aftypes.h" |
#include "aftypes.h" |
21 |
|
|
22 |
|
|
23 |
/* |
/* |
24 |
* a python script used to generate the following table |
* a python script used to generate the following table |
25 |
* |
* |
26 |
|
|
27 |
import sys, math |
import sys, math |
28 |
|
|
29 |
units = 256 |
units = 256 |
30 |
scale = units/math.pi |
scale = units/math.pi |
31 |
comma = "" |
comma = "" |
32 |
|
|
33 |
print "" |
print "" |
34 |
print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units" |
print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units" |
35 |
|
|
36 |
r = [-1] + range(32) |
r = [-1] + range( 32 ) |
37 |
|
|
38 |
for n in r: |
for n in r: |
|
|
|
39 |
if n >= 0: |
if n >= 0: |
40 |
x = 1.0/(2.0**n) # tangent value |
x = 1.0 / ( 2.0 ** n ) # tangent value |
41 |
else: |
else: |
42 |
x = 2.0**(-n) |
x = 2.0 ** ( -n ) |
43 |
|
|
44 |
angle = math.atan(x) # arctangent |
angle = math.atan( x ) # arctangent |
45 |
angle2 = angle*scale # arctangent in FT_Angle units |
angle2 = angle * scale # arctangent in FT_Angle units |
46 |
|
|
47 |
# determine which integer value for angle gives the best tangent |
# determine which integer value for angle gives the best tangent |
48 |
lo = int(angle2) |
lo = int( angle2 ) |
49 |
hi = lo + 1 |
hi = lo + 1 |
50 |
tlo = math.tan(lo/scale) |
tlo = math.tan( lo / scale ) |
51 |
thi = math.tan(hi/scale) |
thi = math.tan( hi / scale ) |
52 |
|
|
53 |
errlo = abs( tlo - x ) |
errlo = abs( tlo - x ) |
54 |
errhi = abs( thi - x ) |
errhi = abs( thi - x ) |
60 |
if angle2 <= 0: |
if angle2 <= 0: |
61 |
break |
break |
62 |
|
|
63 |
sys.stdout.write( comma + repr( int(angle2) ) ) |
sys.stdout.write( comma + repr( int( angle2 ) ) ) |
64 |
comma = ", " |
comma = ", " |
65 |
|
|
66 |
* |
* |
141 |
} |
} |
142 |
|
|
143 |
if ( y > 0 ) |
if ( y > 0 ) |
144 |
theta = - theta; |
theta = -theta; |
145 |
|
|
146 |
arctanptr = af_angle_arctan_table; |
arctanptr = af_angle_arctan_table; |
147 |
|
|
186 |
#if 0 |
#if 0 |
187 |
/* round theta */ |
/* round theta */ |
188 |
if ( theta >= 0 ) |
if ( theta >= 0 ) |
189 |
theta = FT_PAD_ROUND( theta, 2 ); |
theta = FT_PAD_ROUND( theta, 2 ); |
190 |
else |
else |
191 |
theta = - FT_PAD_ROUND( -theta, 2 ); |
theta = -FT_PAD_ROUND( -theta, 2 ); |
192 |
#endif |
#endif |
193 |
|
|
194 |
vec->x = x; |
vec->x = x; |
196 |
} |
} |
197 |
|
|
198 |
|
|
199 |
/* documentation is in fttrigon.h */ |
/* cf. documentation in fttrigon.h */ |
200 |
|
|
201 |
FT_LOCAL_DEF( AF_Angle ) |
FT_LOCAL_DEF( AF_Angle ) |
202 |
af_angle_atan( FT_Fixed dx, |
af_angle_atan( FT_Fixed dx, |
217 |
} |
} |
218 |
|
|
219 |
|
|
|
|
|
220 |
FT_LOCAL_DEF( AF_Angle ) |
FT_LOCAL_DEF( AF_Angle ) |
221 |
af_angle_diff( AF_Angle angle1, |
af_angle_diff( AF_Angle angle1, |
222 |
AF_Angle angle2 ) |
AF_Angle angle2 ) |
223 |
{ |
{ |
224 |
AF_Angle delta = angle2 - angle1; |
AF_Angle delta = angle2 - angle1; |
225 |
|
|
226 |
|
|
227 |
delta %= AF_ANGLE_2PI; |
delta %= AF_ANGLE_2PI; |
228 |
if ( delta < 0 ) |
if ( delta < 0 ) |
229 |
delta += AF_ANGLE_2PI; |
delta += AF_ANGLE_2PI; |
235 |
} |
} |
236 |
|
|
237 |
|
|
|
/* well, this needs to be somewhere, right :-) |
|
|
*/ |
|
|
|
|
238 |
FT_LOCAL_DEF( void ) |
FT_LOCAL_DEF( void ) |
239 |
af_sort_pos( FT_UInt count, |
af_sort_pos( FT_UInt count, |
240 |
FT_Pos* table ) |
FT_Pos* table ) |
241 |
{ |
{ |
242 |
FT_UInt i, j; |
FT_UInt i, j; |
243 |
FT_Pos swap; |
FT_Pos swap; |
282 |
|
|
283 |
|
|
284 |
#ifdef TEST |
#ifdef TEST |
285 |
|
|
286 |
#include <stdio.h> |
#include <stdio.h> |
287 |
#include <math.h> |
#include <math.h> |
288 |
|
|
291 |
int angle; |
int angle; |
292 |
int dist; |
int dist; |
293 |
|
|
294 |
|
|
295 |
for ( dist = 100; dist < 1000; dist++ ) |
for ( dist = 100; dist < 1000; dist++ ) |
296 |
{ |
{ |
297 |
for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI*4; angle++ ) |
for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ ) |
298 |
{ |
{ |
299 |
double a = (angle*3.1415926535)/(1.0*AF_ANGLE_PI); |
double a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI ); |
300 |
int dx, dy, angle1, angle2, delta; |
int dx, dy, angle1, angle2, delta; |
301 |
|
|
|
dx = dist * cos(a); |
|
|
dy = dist * sin(a); |
|
302 |
|
|
303 |
angle1 = ((atan2(dy,dx)*AF_ANGLE_PI)/3.1415926535); |
dx = dist * cos( a ); |
304 |
angle2 = af_angle_atan( dx, dy ); |
dy = dist * sin( a ); |
305 |
delta = (angle2 - angle1) % AF_ANGLE_2PI; |
|
306 |
|
angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 ); |
307 |
|
angle2 = af_angle_atan( dx, dy ); |
308 |
|
delta = ( angle2 - angle1 ) % AF_ANGLE_2PI; |
309 |
if ( delta < 0 ) |
if ( delta < 0 ) |
310 |
delta = -delta; |
delta = -delta; |
311 |
|
|
318 |
} |
} |
319 |
return 0; |
return 0; |
320 |
} |
} |
321 |
#endif |
|
322 |
|
#endif /* TEST */ |
323 |
|
|
324 |
|
|
325 |
|
/* END */ |