1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - FX -
3   File:     fx_atan.c
4 
5   Copyright 2003-2008 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 //worst case
19 //atan(-1.0 -> 1.0) x = -0.085693                                0.007604
20 //atan(1.0 -> 100.0) x = 11.636475                               0.007850
21 //atan(-1.0 -> -100.0) x = -11.636475                            0.007850
22 //atan2(-1.0 -> 1.0, -1.0 -> 1.0) (x = -0.636719, y = -0.054688) 0.007807
23 
24 #include <nitro/fx/fx_trig.h>
25 #include <nitro/fx/fx_cp.h>
26 #include <nitro/fx/fx_const.h>
27 
28 const fx16 FX_AtanTable_[128 + 1] = {
29     (fx16)0x0000,                      // 0.000
30     (fx16)0x0020,                      // 0.008
31     (fx16)0x0040,                      // 0.016
32     (fx16)0x0060,                      // 0.023
33     (fx16)0x0080,                      // 0.031
34     (fx16)0x00a0,                      // 0.039
35     (fx16)0x00c0,                      // 0.047
36     (fx16)0x00e0,                      // 0.055
37     (fx16)0x0100,                      // 0.062
38     (fx16)0x0120,                      // 0.070
39     (fx16)0x013f,                      // 0.078
40     (fx16)0x015f,                      // 0.086
41     (fx16)0x017f,                      // 0.094
42     (fx16)0x019f,                      // 0.101
43     (fx16)0x01be,                      // 0.109
44     (fx16)0x01de,                      // 0.117
45     (fx16)0x01fd,                      // 0.124
46     (fx16)0x021d,                      // 0.132
47     (fx16)0x023c,                      // 0.140
48     (fx16)0x025c,                      // 0.147
49     (fx16)0x027b,                      // 0.155
50     (fx16)0x029a,                      // 0.163
51     (fx16)0x02b9,                      // 0.170
52     (fx16)0x02d8,                      // 0.178
53     (fx16)0x02f7,                      // 0.185
54     (fx16)0x0316,                      // 0.193
55     (fx16)0x0335,                      // 0.200
56     (fx16)0x0354,                      // 0.208
57     (fx16)0x0372,                      // 0.215
58     (fx16)0x0391,                      // 0.223
59     (fx16)0x03af,                      // 0.230
60     (fx16)0x03cd,                      // 0.238
61     (fx16)0x03eb,                      // 0.245
62     (fx16)0x0409,                      // 0.252
63     (fx16)0x0427,                      // 0.260
64     (fx16)0x0445,                      // 0.267
65     (fx16)0x0463,                      // 0.274
66     (fx16)0x0481,                      // 0.281
67     (fx16)0x049e,                      // 0.289
68     (fx16)0x04bb,                      // 0.296
69     (fx16)0x04d9,                      // 0.303
70     (fx16)0x04f6,                      // 0.310
71     (fx16)0x0513,                      // 0.317
72     (fx16)0x052f,                      // 0.324
73     (fx16)0x054c,                      // 0.331
74     (fx16)0x0569,                      // 0.338
75     (fx16)0x0585,                      // 0.345
76     (fx16)0x05a1,                      // 0.352
77     (fx16)0x05be,                      // 0.359
78     (fx16)0x05da,                      // 0.366
79     (fx16)0x05f5,                      // 0.372
80     (fx16)0x0611,                      // 0.379
81     (fx16)0x062d,                      // 0.386
82     (fx16)0x0648,                      // 0.393
83     (fx16)0x0663,                      // 0.399
84     (fx16)0x067e,                      // 0.406
85     (fx16)0x0699,                      // 0.412
86     (fx16)0x06b4,                      // 0.419
87     (fx16)0x06cf,                      // 0.426
88     (fx16)0x06e9,                      // 0.432
89     (fx16)0x0703,                      // 0.438
90     (fx16)0x071e,                      // 0.445
91     (fx16)0x0738,                      // 0.451
92     (fx16)0x0751,                      // 0.457
93     (fx16)0x076b,                      // 0.464
94     (fx16)0x0785,                      // 0.470
95     (fx16)0x079e,                      // 0.476
96     (fx16)0x07b7,                      // 0.482
97     (fx16)0x07d0,                      // 0.488
98     (fx16)0x07e9,                      // 0.494
99     (fx16)0x0802,                      // 0.500
100     (fx16)0x081a,                      // 0.506
101     (fx16)0x0833,                      // 0.512
102     (fx16)0x084b,                      // 0.518
103     (fx16)0x0863,                      // 0.524
104     (fx16)0x087b,                      // 0.530
105     (fx16)0x0893,                      // 0.536
106     (fx16)0x08aa,                      // 0.542
107     (fx16)0x08c2,                      // 0.547
108     (fx16)0x08d9,                      // 0.553
109     (fx16)0x08f0,                      // 0.559
110     (fx16)0x0907,                      // 0.564
111     (fx16)0x091e,                      // 0.570
112     (fx16)0x0934,                      // 0.575
113     (fx16)0x094b,                      // 0.581
114     (fx16)0x0961,                      // 0.586
115     (fx16)0x0977,                      // 0.592
116     (fx16)0x098d,                      // 0.597
117     (fx16)0x09a3,                      // 0.602
118     (fx16)0x09b9,                      // 0.608
119     (fx16)0x09ce,                      // 0.613
120     (fx16)0x09e3,                      // 0.618
121     (fx16)0x09f9,                      // 0.623
122     (fx16)0x0a0e,                      // 0.628
123     (fx16)0x0a23,                      // 0.634
124     (fx16)0x0a37,                      // 0.638
125     (fx16)0x0a4c,                      // 0.644
126     (fx16)0x0a60,                      // 0.648
127     (fx16)0x0a74,                      // 0.653
128     (fx16)0x0a89,                      // 0.658
129     (fx16)0x0a9c,                      // 0.663
130     (fx16)0x0ab0,                      // 0.668
131     (fx16)0x0ac4,                      // 0.673
132     (fx16)0x0ad7,                      // 0.677
133     (fx16)0x0aeb,                      // 0.682
134     (fx16)0x0afe,                      // 0.687
135     (fx16)0x0b11,                      // 0.692
136     (fx16)0x0b24,                      // 0.696
137     (fx16)0x0b37,                      // 0.701
138     (fx16)0x0b49,                      // 0.705
139     (fx16)0x0b5c,                      // 0.710
140     (fx16)0x0b6e,                      // 0.714
141     (fx16)0x0b80,                      // 0.719
142     (fx16)0x0b92,                      // 0.723
143     (fx16)0x0ba4,                      // 0.728
144     (fx16)0x0bb6,                      // 0.732
145     (fx16)0x0bc8,                      // 0.736
146     (fx16)0x0bd9,                      // 0.740
147     (fx16)0x0beb,                      // 0.745
148     (fx16)0x0bfc,                      // 0.749
149     (fx16)0x0c0d,                      // 0.753
150     (fx16)0x0c1e,                      // 0.757
151     (fx16)0x0c2f,                      // 0.761
152     (fx16)0x0c3f,                      // 0.765
153     (fx16)0x0c50,                      // 0.770
154     (fx16)0x0c60,                      // 0.773
155     (fx16)0x0c71,                      // 0.778
156     (fx16)0x0c81,                      // 0.781
157     (fx16)0x0c91                       // 0.785
158 };
159 
160 
161 /*---------------------------------------------------------------------------*
162   Name:         FX_Atan
163 
164   Description:  Computes an arc tangent of the input value, making use of
165                 a table.
166 
167   Arguments:    x            Y/X in fx32 format
168 
169   Returns:      result in fx16 format
170  *---------------------------------------------------------------------------*/
FX_Atan(fx32 x)171 fx16 FX_Atan(fx32 x)
172 {
173     if (x >= 0)
174     {
175         if (x > FX32_ONE)
176         {
177             return (fx16)(6434 - FX_AtanTable_[FX_Inv(x) >> 5]);
178         }
179         else if (x < FX32_ONE)
180         {
181             return FX_AtanTable_[x >> 5];
182         }
183         else
184         {
185             return (fx16)3217;
186         }
187     }
188     else
189     {
190         if (x < -FX32_ONE)
191         {
192             return (fx16)(-6434 + FX_AtanTable_[FX_Inv(-x) >> 5]);
193         }
194         else if (x > -FX32_ONE)
195         {
196             return (fx16)-FX_AtanTable_[-x >> 5];
197         }
198         else
199         {
200             return (fx16)-3217;
201         }
202     }
203 }
204 
205 
206 /*---------------------------------------------------------------------------*
207   Name:         FX_Atan2
208 
209   Description:  Computes an arc tangent of the input value(y/x), making use of
210                 a table. Note that 'y' is the first argument.
211 
212   Arguments:    y            a value in fx32 format
213                 x            a value in fx32 format
214 
215   Returns:      result in fx16 format
216  *---------------------------------------------------------------------------*/
FX_Atan2(fx32 y,fx32 x)217 fx16 FX_Atan2(fx32 y, fx32 x)
218 {
219     fx32    a, b, c;
220     int     sgn;
221 
222     if (y > 0)
223     {
224         if (x > 0)
225         {
226             if (x > y)
227             {
228                 a = y;
229                 b = x;
230                 c = 0;
231                 sgn = 1;
232             }
233             else if (x < y)
234             {
235                 a = x;
236                 b = y;
237                 c = 6434;
238                 sgn = 0;
239             }
240             else
241             {
242                 return (fx16)3217;
243             }
244         }
245         else if (x < 0)
246         {
247             x = -x;
248             if (x < y)
249             {
250                 a = x;
251                 b = y;
252                 c = 6434;
253                 sgn = 1;
254             }
255             else if (x > y)
256             {
257                 a = y;
258                 b = x;
259                 c = 12868;
260                 sgn = 0;
261             }
262             else
263             {
264                 return (fx16)9651;
265             }
266         }
267         else
268         {
269             return (fx16)6434;
270         }
271     }
272     else if (y < 0)
273     {
274         y = -y;
275         if (x < 0)
276         {
277             x = -x;
278             if (x > y)
279             {
280                 a = y;
281                 b = x;
282                 c = -12868;
283                 sgn = 1;
284             }
285             else if (x < y)
286             {
287                 a = x;
288                 b = y;
289                 c = -6434;
290                 sgn = 0;
291             }
292             else
293             {
294                 return (fx16)-9651;
295             }
296         }
297         else if (x > 0)
298         {
299             if (x < y)
300             {
301                 a = x;
302                 b = y;
303                 c = -6434;
304                 sgn = 1;
305             }
306             else if (x > y)
307             {
308                 a = y;
309                 b = x;
310                 c = 0;
311                 sgn = 0;
312             }
313             else
314             {
315                 return (fx16)-3217;
316             }
317         }
318         else
319         {
320             return (fx16)-6434;
321         }
322     }
323     else                               // y = 0
324     {
325         if (x >= 0)
326         {
327             return 0;
328         }
329         else
330         {
331             return (fx16)12868;
332         }
333     }
334 
335     if (b == 0)
336         return 0;
337     if (sgn)
338         return (fx16)(c + FX_AtanTable_[FX_Div(a, b) >> 5]);
339     else
340         return (fx16)(c - FX_AtanTable_[FX_Div(a, b) >> 5]);
341 }
342