/*---------------------------------------------------------------------------* 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; // 次のsin_valとの差 f32 cos_delta; // 次のcos_valとの差 }; extern const SinCosSample gSinCosTbl[256 + 1]; } // namespace internal } // namespace math } // namespace nn namespace nn { namespace math { /* ======================================================================= sin/cos/tan ======================================================================== */ /*! @name 三角関数 @{ */ #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) ) /*!--------------------------------------------------------------------------* @brief 正弦の値を求めます @param[in] fidx 1 円周を 256.0 とする角度 @return fidx に対する正弦の値を返します。 *---------------------------------------------------------------------------*/ f32 SinFIdx(f32 fidx); /*!--------------------------------------------------------------------------* @brief 余弦の値を求めます @param[in] fidx 1 円周を 256.0 とする角度 @return fidx に対する余弦の値を返します。 *---------------------------------------------------------------------------*/ f32 CosFIdx(f32 fidx); /*!--------------------------------------------------------------------------* @brief 正弦と余弦の値を求めます @param[out] pSin 正弦の値を格納するバッファへのポインタ @param[out] pCos 余弦の値を格納するバッファへのポインタ @param[in] fidx 1 円周を 256.0 とする角度 @return なし *---------------------------------------------------------------------------*/ void SinCosFIdx(f32* pSin, f32* pCos, f32 fidx); /*!--------------------------------------------------------------------------* @brief 正接の値を求めます @param[in] fidx 1 円周を 256.0 とする角度 @return fidx に対する正接の値を返します。 *---------------------------------------------------------------------------*/ inline f32 TanFIdx(f32 fidx) { return ::std::tanf(NN_MATH_FIDX_TO_RAD(fidx)); } /*!--------------------------------------------------------------------------* @brief 正弦の値を求めます。 @param[in] rad ラジアン単位の角度 @return rad に対する正弦の値を返します。 *---------------------------------------------------------------------------*/ inline f32 SinRad(f32 rad) { return SinFIdx(NN_MATH_RAD_TO_FIDX(rad)); } /*!--------------------------------------------------------------------------* @brief 余弦の値を求めます。 @param[in] rad ラジアン単位の角度 @return rad に対する余弦の値を返します。 *---------------------------------------------------------------------------*/ inline f32 CosRad(f32 rad) { return CosFIdx(NN_MATH_RAD_TO_FIDX(rad)); } /*!--------------------------------------------------------------------------* @brief 正弦と余弦の値を求めます。 @param[out] s 正弦の値を格納するバッファへのポインタ @param[out] c 余弦の値を格納するバッファへのポインタ @param[in] rad ラジアン単位の角度 @return なし *---------------------------------------------------------------------------*/ inline void SinCosRad(f32* s, f32* c, f32 rad) { SinCosFIdx(s, c, NN_MATH_RAD_TO_FIDX(rad)); } /*!--------------------------------------------------------------------------* @brief 正接の値を求めます。 @param[in] rad ラジアン単位の角度 @return rad に対する正接の値を返します。 *---------------------------------------------------------------------------*/ inline f32 TanRad(f32 rad) { return TanFIdx(NN_MATH_RAD_TO_FIDX(rad)); } /*!--------------------------------------------------------------------------* @brief 正弦の値を求めます。 @param[in] deg 1 円周を 360.0 とする角度 @return deg に対する正弦の値を返します。 *---------------------------------------------------------------------------*/ inline f32 SinDeg(f32 deg) { return SinFIdx(NN_MATH_DEG_TO_FIDX(deg)); } /*!--------------------------------------------------------------------------* @brief 余弦の値を求めます。 @param[in] deg 1 円周を 360.0 とする角度 @return deg に対する余弦の値を返します。 *---------------------------------------------------------------------------*/ inline f32 CosDeg(f32 deg) { return CosFIdx(NN_MATH_DEG_TO_FIDX(deg)); } /*!--------------------------------------------------------------------------* @brief 正弦と余弦の値を求めます。 @param[out] s 正弦の値を格納するバッファへのポインタ @param[out] c 余弦の値を格納するバッファへのポインタ @param[in] deg 1 円周を 360.0 とする角度 @return なし *---------------------------------------------------------------------------*/ inline void SinCosDeg(f32* s, f32* c, f32 deg) { SinCosFIdx(s, c, NN_MATH_DEG_TO_FIDX(deg)); } /*!--------------------------------------------------------------------------* @brief 正接の値を求めます。 @param[in] deg 1 円周を 360.0 とする角度 @return deg に対する正接の値を返します。 *---------------------------------------------------------------------------*/ inline f32 TanDeg(f32 deg) { return TanFIdx(NN_MATH_DEG_TO_FIDX(deg)); } #if 1 /* 16bitインデックスのものを使うことになったら、この関数の実装を置き換える */ /*!--------------------------------------------------------------------------* @brief 正弦の値を求めます。 @param[in] idx 1 円周を 65536 とする角度 @return idx に対する正弦の値を返します。 *---------------------------------------------------------------------------*/ f32 SinIdx(u16 idx); /*!--------------------------------------------------------------------------* @brief 余弦の値を求めます。 @param[in] idx 1 円周を 65536 とする角度 @return idx に対する余弦の値を返します。 *---------------------------------------------------------------------------*/ f32 CosIdx(u16 idx); /*!--------------------------------------------------------------------------* @brief 正弦と余弦の値を求めます。 @param[out] s 正弦の値を格納するバッファへのポインタ @param[out] c 余弦の値を格納するバッファへのポインタ @param[in] idx 1 円周を 65536 とする角度 @return なし *---------------------------------------------------------------------------*/ void SinCosIdx(f32* s, f32* c, u16 idx); /*!--------------------------------------------------------------------------* @brief 正接の値を求めます。 @param[in] idx 1 円周を 65536 とする角度 @return 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); } /*!--------------------------------------------------------------------------* @brief 逆正弦の値を求めます。 @param[in] x 逆正弦を求める値 @return 1 円周を 256.0 とする角度で逆正弦の値を返します。 *---------------------------------------------------------------------------*/ 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)); } /*!--------------------------------------------------------------------------* @brief 逆余弦の値を求めます。 @param[in] x 逆余弦を求める値 @return 1 円周を 256.0 とする角度で逆余弦の値を返します。 *---------------------------------------------------------------------------*/ 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); /*!--------------------------------------------------------------------------* @brief 逆正弦の値を求めます。 @param[in] x 逆正弦を求める値 @return 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); } /*!--------------------------------------------------------------------------* @brief 逆余弦の値を求めます。 @param[in] x 逆余弦を求める値 @return 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); } /*!--------------------------------------------------------------------------* @brief 逆正接の値を求めます。 @param[in] x 逆正接を求める値 @return x に対する逆正接の値をラジアン単位で返します *---------------------------------------------------------------------------*/ inline f32 AtanRad(f32 x) { return NN_MATH_FIDX_TO_RAD(AtanFIdx(x)); } /*!--------------------------------------------------------------------------* @brief 逆正接の値を求めます。 @param[in] y 正接の値の分子 @param[in] x 正接の値の分母 @return y/x の逆正接の値をラジアン単位で返します *---------------------------------------------------------------------------*/ inline f32 Atan2Rad(f32 y, f32 x) { return NN_MATH_FIDX_TO_RAD(Atan2FIdx(y, x)); } /*!--------------------------------------------------------------------------* @brief 逆正弦の値を求めます。 @param[in] x 逆正弦を求める値 @return x に対する逆正弦の値を 360.0 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ 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)); } /*!--------------------------------------------------------------------------* @brief 逆余弦の値を求めます。 @param[in] x 逆余弦を求める値 @return x に対する逆余弦の値を 360.0 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ 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)); } /*!--------------------------------------------------------------------------* @brief 逆正接の値を求めます。 @param[in] x 逆正接を求める値 @return x に対する逆正接の値を 360.0 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ inline f32 AtanDeg(f32 x) { return NN_MATH_FIDX_TO_DEG(AtanFIdx(x)); } /*!--------------------------------------------------------------------------* @brief 逆正接の値を求めます。 @param[in] y 正接の値の分子 @param[in] x 正接の値の分母 @return y/x の逆正接の値を 360.0 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ inline f32 Atan2Deg(f32 y, f32 x) { return NN_MATH_FIDX_TO_DEG(Atan2FIdx(y, x)); } #if 1 /* 16bitインデックスのものを使うことになったら、この関数の実装を置き換える */ /*!--------------------------------------------------------------------------* @brief 逆正弦の値を求めます。 @param[in] x 逆正弦を求める値 @return x に対する逆正弦の値を 65536 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ // 0°~ 90°と 270°~ 360°の範囲のインデックスを返します inline u16 AsinIdx(f32 x) { f32 fidx = AsinFIdx(x); return F32ToU16((fidx < 0 ? fidx + 256.f : fidx) * 256.f); } /*!--------------------------------------------------------------------------* @brief 逆余弦の値を求めます。 @param[in] x 逆余弦を求める値 @return x に対する逆余弦の値を 65536 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ // [0,PI] の範囲のインデックスを返します inline u16 AcosIdx(f32 x) { return F32ToU16(AcosFIdx(x) * 256.f); } /*!--------------------------------------------------------------------------* @brief 逆正接の値を求めます。 @param[in] x 逆正接を求める値 @return x に対する逆正接の値を 65536 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ // 0°~ 90°と 270°~ 360°の範囲のインデックスを返します u16 AtanIdx(f32 x); /*!--------------------------------------------------------------------------* @brief 逆正接の値を求めます。 @param[in] y 正接の値の分子 @param[in] x 正接の値の分母 @return y/x の逆正接の値を 65536 を 1 円周とする単位で返します *---------------------------------------------------------------------------*/ // 0°~ 360°の範囲のインデックスを返します u16 Atan2Idx(f32 y, f32 x); #endif /*! @} */ } // namespace math } // namespace nn /* NN_MATH_TRIANGULAR_H_ */ #endif