using System;

namespace StarEngine.Ruby
{
    /// <summary>
    /// 4096 度系の、数学関係の関数を集めたモジュールです。
    /// </summary>
    /// <remarks>
    /// System.Math の三角関数の速度で遅すぎるということはめったにないはず。
    /// というわけで、このクラスは
    /// 角度系を扱いやすい物にしたというメリット程度しかない。
    /// </remarks>
    internal static class Math4096
    {
        /// <summary>
        /// 円一周分の角度の値。
        /// </summary>
        /// <remarks>
        /// 角度は 4096 度系です。
        /// </remarks>
        public const int MaxAngle = 4096;

        private static ushort[] SinTable = new ushort[MaxAngle / 4];
        

        static Math4096()
        {
            double factor = Math.PI * 2 / MaxAngle;
            for (int i = 0; i < SinTable.Length; i++)
                SinTable[i] = (ushort)(Math.Sin(i * factor) * 65536);
        }

        /// <summary>
        /// cos 関数。
        /// </summary>
        /// <param name="angle">角度 (4096 度系)。</param>
        /// <returns>-1〜1</returns>
        public static double Cos(int angle)
        {
            return Sin(angle + MaxAngle / 4);
        }

        /// <summary>
        /// sin 関数。
        /// </summary>
        /// <param name="angle">角度 (4096 度系)。</param>
        /// <returns>-1〜1</returns>
        public static double Sin(int angle)
        {
            angle &= MaxAngle - 1; // Mask
            int q = MaxAngle / 4;
            if (angle < q)
                return SinTable[angle] / 65536.0;
            else if (angle == q)
                return 1;
            else if (angle < q * 2)
                return SinTable[q * 2 - angle] / 65536.0;
            else
                return -Sin(angle - q * 2);
        }

        
    }
}

