/*---------------------------------------------------------------------------* Project: Horizon File: math_Triangular.h Copyright (C)2009-2010 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 19123 $ *---------------------------------------------------------------------------*/ #ifndef NN_MATH_TRIANGULAR_H_ #define NN_MATH_TRIANGULAR_H_ #include #include #include #include namespace nn { namespace math { namespace internal { struct SinCosSample { f32 sin_val; f32 cos_val; f32 sin_delta; // Difference from next sin_val f32 cos_delta; // Difference from next cos_val }; extern const SinCosSample gSinCosTbl[256 + 1]; } // namespace internal } // namespace math } // namespace nn namespace nn { namespace math { /* ======================================================================= sin/cos/tan ======================================================================== */ /* Please see man pages for details */ #define NN_MATH_RAD_TO_FIDX(rad) ((rad) * (256.f / (2.0f * ::nn::math::F_PI))) #define NN_MATH_DEG_TO_FIDX(deg) ((deg) * (256.f / 360.f) ) #define NN_MATH_DEG_TO_RAD(deg) ((deg) * (::nn::math::F_PI / 180.0f) ) #define NN_MATH_RAD_TO_DEG(rad) ((rad) * (180.0f / ::nn::math::F_PI) ) #define NN_MATH_FIDX_TO_RAD(fidx) ((fidx) * ((2.0f * ::nn::math::F_PI) / 256.f)) #define NN_MATH_FIDX_TO_DEG(fidx) ((fidx) * (360.f / 256.f) ) /* */ f32 SinFIdx(f32 fidx); /* */ f32 CosFIdx(f32 fidx); /* */ void SinCosFIdx(f32* pSin, f32* pCos, f32 fidx); /* */ inline f32 TanFIdx(f32 fidx) { return ::std::tanf(NN_MATH_FIDX_TO_RAD(fidx)); } /* */ inline f32 SinRad(f32 rad) { return SinFIdx(NN_MATH_RAD_TO_FIDX(rad)); } /* */ inline f32 CosRad(f32 rad) { return CosFIdx(NN_MATH_RAD_TO_FIDX(rad)); } /* */ inline void SinCosRad(f32* s, f32* c, f32 rad) { SinCosFIdx(s, c, NN_MATH_RAD_TO_FIDX(rad)); } /* */ inline f32 TanRad(f32 rad) { return TanFIdx(NN_MATH_RAD_TO_FIDX(rad)); } /* */ inline f32 SinDeg(f32 deg) { return SinFIdx(NN_MATH_DEG_TO_FIDX(deg)); } /* */ inline f32 CosDeg(f32 deg) { return CosFIdx(NN_MATH_DEG_TO_FIDX(deg)); } /* */ inline void SinCosDeg(f32* s, f32* c, f32 deg) { SinCosFIdx(s, c, NN_MATH_DEG_TO_FIDX(deg)); } /* */ inline f32 TanDeg(f32 deg) { return TanFIdx(NN_MATH_DEG_TO_FIDX(deg)); } #if 1 /* Once we start using one with a 16-bit index, the implementation of this function will be replaced. */ /* */ f32 SinIdx(u16 idx); /* */ f32 CosIdx(u16 idx); /* */ void SinCosIdx(f32* s, f32* c, u16 idx); /* */ inline f32 TanIdx(u16 idx) { return TanFIdx(U16ToF32(idx) * (1.f / 256.f)); } #endif inline f32 NN_fAcos(f32 x) { return ::std::acosf(x); } inline f32 NN_fAsin(f32 x) { return ::std::asinf(x); } inline f32 NN_fAtan(f32 x) { return ::std::atanf(x); } inline f32 NN_fAtan2(f32 y, f32 x) { return ::std::atan2f(y, x); } /* */ inline f32 AsinFIdx(f32 x) { NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AsinFIdx: Input is out of the domain."); return NN_MATH_RAD_TO_FIDX(::std::asin(x)); } /* */ inline f32 AcosFIdx(f32 x) { NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AcosFIdx: Input is out of the domain."); return NN_MATH_RAD_TO_FIDX(::std::acosf(x)); } f32 AtanFIdx(f32 x); f32 Atan2FIdx(f32 y, f32 x); /* */ inline f32 AsinRad(f32 x) { NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AsinRad: Input is out of the domain."); return ::std::asin(x); } /* */ inline f32 AcosRad(f32 x) { NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AcosRad: Input is out of the domain."); return ::std::acos(x); } /* */ inline f32 AtanRad(f32 x) { return NN_MATH_FIDX_TO_RAD(AtanFIdx(x)); } /* */ inline f32 Atan2Rad(f32 y, f32 x) { return NN_MATH_FIDX_TO_RAD(Atan2FIdx(y, x)); } /* */ inline f32 AsinDeg(f32 x) { NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AsinDeg: Input is out of the domain."); return NN_MATH_RAD_TO_DEG(::std::asin(x)); } /* */ inline f32 AcosDeg(f32 x) { NN_MATH_WARNING(x <= 1.f && x >= -1.f, "AcosDeg: Input is out of the domain."); return NN_MATH_RAD_TO_DEG(::std::acos(x)); } /* */ inline f32 AtanDeg(f32 x) { return NN_MATH_FIDX_TO_DEG(AtanFIdx(x)); } /* */ inline f32 Atan2Deg(f32 y, f32 x) { return NN_MATH_FIDX_TO_DEG(Atan2FIdx(y, x)); } #if 1 /* Once we start using one with a 16-bit index, the implementation of this function will be replaced. */ /* */ // Returns an index in the range of 0 - 90 degrees and 270 - 360 degrees inline u16 AsinIdx(f32 x) { f32 fidx = AsinFIdx(x); return F32ToU16((fidx < 0 ? fidx + 256.f : fidx) * 256.f); } /* */ // Returns index in the [0,PI] range inline u16 AcosIdx(f32 x) { return F32ToU16(AcosFIdx(x) * 256.f); } /* */ // Returns an index in the range of 0 - 90 degrees and 270 - 360 degrees u16 AtanIdx(f32 x); /* */ // Returns an index in the range of 0 - 360 degrees u16 Atan2Idx(f32 y, f32 x); #endif /* */ } // namespace math } // namespace nn /* NN_MATH_TRIANGULAR_H_ */ #endif