1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Triangular.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd.  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   $Revision: 19123 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_TRIANGULAR_H_
17 #define NN_MATH_TRIANGULAR_H_
18 
19 #include <nn/math/math_Config.h>
20 #include <nn/math/math_Constant.h>
21 #include <nn/math/math_Arithmetic.h>
22 
23 #include <cmath>
24 
25 
26 namespace nn {
27 namespace math {
28 namespace internal {
29 
30     struct SinCosSample
31     {
32         f32 sin_val;
33         f32 cos_val;
34         f32 sin_delta; // Difference from next sin_val
35         f32 cos_delta; // Difference from next cos_val
36     };
37 
38     extern const SinCosSample gSinCosTbl[256 + 1];
39 
40 } // namespace internal
41 } // namespace math
42 } // namespace nn
43 
44 
45 namespace nn {
46 namespace math {
47 
48 
49 /* =======================================================================
50         sin/cos/tan
51    ======================================================================== */
52 /* Please see man pages for details
53 
54 
55 */
56 
57 #define NN_MATH_RAD_TO_FIDX(rad)  ((rad)  * (256.f / (2.0f * ::nn::math::F_PI)))
58 #define NN_MATH_DEG_TO_FIDX(deg)  ((deg)  * (256.f / 360.f)   )
59 #define NN_MATH_DEG_TO_RAD(deg)   ((deg)  * (::nn::math::F_PI / 180.0f)   )
60 #define NN_MATH_RAD_TO_DEG(rad)   ((rad)  * (180.0f / ::nn::math::F_PI)   )
61 #define NN_MATH_FIDX_TO_RAD(fidx) ((fidx) * ((2.0f * ::nn::math::F_PI) / 256.f))
62 #define NN_MATH_FIDX_TO_DEG(fidx) ((fidx) * (360.f / 256.f)   )
63 
64 
65 /*
66 
67 
68 
69 
70 
71  */
72 f32 SinFIdx(f32 fidx);
73 
74 /*
75 
76 
77 
78 
79 
80  */
81 f32 CosFIdx(f32 fidx);
82 
83 /*
84 
85 
86 
87 
88 
89 
90 
91  */
92 void SinCosFIdx(f32* pSin, f32* pCos, f32 fidx);
93 
94 /*
95 
96 
97 
98 
99 
100  */
101 inline f32
TanFIdx(f32 fidx)102 TanFIdx(f32 fidx)
103 {
104     return ::std::tanf(NN_MATH_FIDX_TO_RAD(fidx));
105 }
106 
107 
108 /*
109 
110 
111 
112 
113 
114  */
SinRad(f32 rad)115 inline f32 SinRad(f32 rad)  { return SinFIdx(NN_MATH_RAD_TO_FIDX(rad)); }
116 
117 /*
118 
119 
120 
121 
122 
123  */
CosRad(f32 rad)124 inline f32 CosRad(f32 rad)  { return CosFIdx(NN_MATH_RAD_TO_FIDX(rad)); }
125 
126 /*
127 
128 
129 
130 
131 
132 
133 
134  */
SinCosRad(f32 * s,f32 * c,f32 rad)135 inline void SinCosRad(f32* s, f32* c, f32 rad) { SinCosFIdx(s, c, NN_MATH_RAD_TO_FIDX(rad)); }
136 
137 /*
138 
139 
140 
141 
142 
143  */
TanRad(f32 rad)144 inline f32 TanRad(f32 rad)  { return TanFIdx(NN_MATH_RAD_TO_FIDX(rad)); }
145 
146 
147 
148 
149 /*
150 
151 
152 
153 
154 
155  */
SinDeg(f32 deg)156 inline f32 SinDeg(f32 deg)  { return SinFIdx(NN_MATH_DEG_TO_FIDX(deg)); }
157 
158 /*
159 
160 
161 
162 
163 
164  */
CosDeg(f32 deg)165 inline f32 CosDeg(f32 deg)  { return CosFIdx(NN_MATH_DEG_TO_FIDX(deg)); }
166 
167 /*
168 
169 
170 
171 
172 
173 
174 
175  */
SinCosDeg(f32 * s,f32 * c,f32 deg)176 inline void SinCosDeg(f32* s, f32* c, f32 deg) { SinCosFIdx(s, c, NN_MATH_DEG_TO_FIDX(deg)); }
177 
178 /*
179 
180 
181 
182 
183 
184  */
TanDeg(f32 deg)185 inline f32 TanDeg(f32 deg)  { return TanFIdx(NN_MATH_DEG_TO_FIDX(deg)); }
186 
187 #if 1
188 /* Once we start using one with a 16-bit index, the implementation of this function will be replaced. */
189 
190 /*
191 
192 
193 
194 
195 
196  */
197 f32 SinIdx(u16 idx);
198 
199 /*
200 
201 
202 
203 
204 
205  */
206 f32 CosIdx(u16 idx);
207 
208 /*
209 
210 
211 
212 
213 
214 
215 
216  */
217 void SinCosIdx(f32* s, f32* c, u16 idx);
218 
219 /*
220 
221 
222 
223 
224 
225  */
TanIdx(u16 idx)226 inline f32 TanIdx(u16 idx)  { return TanFIdx(U16ToF32(idx) * (1.f / 256.f)); }
227 #endif
228 
NN_fAcos(f32 x)229 inline f32 NN_fAcos(f32 x) { return ::std::acosf(x); }
NN_fAsin(f32 x)230 inline f32 NN_fAsin(f32 x) { return ::std::asinf(x); }
NN_fAtan(f32 x)231 inline f32 NN_fAtan(f32 x) { return ::std::atanf(x); }
NN_fAtan2(f32 y,f32 x)232 inline f32 NN_fAtan2(f32 y, f32 x) { return ::std::atan2f(y, x); }
233 
234 
235 /*
236 
237 
238 
239 
240 
241  */
242 inline f32
AsinFIdx(f32 x)243 AsinFIdx(f32 x)
244 {
245     NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AsinFIdx: Input is out of the domain.");
246     return NN_MATH_RAD_TO_FIDX(::std::asin(x));
247 }
248 
249 /*
250 
251 
252 
253 
254 
255  */
256 inline f32
AcosFIdx(f32 x)257 AcosFIdx(f32 x)
258 {
259     NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AcosFIdx: Input is out of the domain.");
260     return NN_MATH_RAD_TO_FIDX(::std::acosf(x));
261 }
262 
263 
264 f32 AtanFIdx(f32 x);
265 f32 Atan2FIdx(f32 y, f32 x);
266 
267 
268 /*
269 
270 
271 
272 
273 
274  */
AsinRad(f32 x)275 inline f32 AsinRad(f32 x)
276 {
277     NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AsinRad: Input is out of the domain.");
278     return ::std::asin(x);
279 }
280 
281 /*
282 
283 
284 
285 
286 
287  */
AcosRad(f32 x)288 inline f32 AcosRad(f32 x)
289 {
290     NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AcosRad: Input is out of the domain.");
291     return ::std::acos(x);
292 }
293 
294 /*
295 
296 
297 
298 
299 
300  */
AtanRad(f32 x)301 inline f32 AtanRad(f32 x)  { return NN_MATH_FIDX_TO_RAD(AtanFIdx(x)); }
302 
303 /*
304 
305 
306 
307 
308 
309 
310  */
Atan2Rad(f32 y,f32 x)311 inline f32 Atan2Rad(f32 y, f32 x)  { return NN_MATH_FIDX_TO_RAD(Atan2FIdx(y, x)); }
312 
313 
314 
315 
316 
317 
318 /*
319 
320 
321 
322 
323 
324  */
AsinDeg(f32 x)325 inline f32 AsinDeg(f32 x)
326 {
327     NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AsinDeg: Input is out of the domain.");
328     return NN_MATH_RAD_TO_DEG(::std::asin(x));
329 }
330 
331 /*
332 
333 
334 
335 
336 
337  */
AcosDeg(f32 x)338 inline f32 AcosDeg(f32 x)
339 {
340     NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AcosDeg: Input is out of the domain.");
341     return NN_MATH_RAD_TO_DEG(::std::acos(x));
342 }
343 
344 /*
345 
346 
347 
348 
349 
350  */
AtanDeg(f32 x)351 inline f32 AtanDeg(f32 x)  { return NN_MATH_FIDX_TO_DEG(AtanFIdx(x)); }
352 
353 /*
354 
355 
356 
357 
358 
359 
360  */
Atan2Deg(f32 y,f32 x)361 inline f32 Atan2Deg(f32 y, f32 x)  { return NN_MATH_FIDX_TO_DEG(Atan2FIdx(y, x)); }
362 
363 #if 1
364 /* Once we start using one with a 16-bit index, the implementation of this function will be replaced. */
365 
366 
367 /*
368 
369 
370 
371 
372 
373  */
374 //        Returns an index in the range of 0 - 90 degrees and 270 - 360 degrees
AsinIdx(f32 x)375 inline u16 AsinIdx(f32 x)  { f32 fidx = AsinFIdx(x); return F32ToU16((fidx < 0 ? fidx + 256.f : fidx) * 256.f); }
376 
377 /*
378 
379 
380 
381 
382 
383  */
384 //        Returns index in the [0,PI] range
AcosIdx(f32 x)385 inline u16 AcosIdx(f32 x)  { return F32ToU16(AcosFIdx(x) * 256.f); }
386 
387 /*
388 
389 
390 
391 
392 
393  */
394 //        Returns an index in the range of 0 - 90 degrees and 270 - 360 degrees
395 u16 AtanIdx(f32 x);
396 
397 /*
398 
399 
400 
401 
402 
403 
404  */
405 //        Returns an index in the range of 0 - 360 degrees
406 u16 Atan2Idx(f32 y, f32 x);
407 #endif
408 
409 /*
410 
411 */
412 
413 } // namespace math
414 } // namespace nn
415 
416 
417 /* NN_MATH_TRIANGULAR_H_ */
418 #endif
419