// Gets sin of specified radians. // Input and output format is fixed point sign.19.12 int F32SinHP(int radians) //int32 f32sin(int32 radians) { const int PI2_PRECISION_BITS = 20; const int PI2_RECIPROCAL = (int)((1.0f / (2.0 * Math.PI)) * (1 << PI2_PRECISION_BITS)); // Divide incoming radians by 2*PI, so it is a "normalized" // angle between -1 and +1, where 1 equals 2*PI (360 degree). int normalized = (radians * PI2_RECIPROCAL) >> PI2_PRECISION_BITS; // Now that we have our normalized angle, // we just discard all numbers which are not in the range -1..+1. // Since this is fixed point, a simple AND operation can be used. int ranged = normalized & 0x000007ff; // floattof32(1) - 1; // Angle is left as normalized and 2 * PI removed in the calculation of value described below // Approximate sin value // const B replaced with << 3 which is a << 15 then >> 12 (one multiplication and shift), coming from // (int)(8.0f * (1 << 12)); 8.0f = (4 / PI) * (2 * PI) from the skipped step above // 4 / PI = 1.2732395447351f from original calculation // const C replaced with >> 8 which is a << 16 then >> 12 and >> 12 (two multiplications and shifts), coming from // (int)(-16.0f * (1 << 12)); 16.0f = (4 / PI^2) * (2 * PI)^2 from the skipped step above as value is ^ 2 // 4/PI^2 = 0.405284734569f // These are the constants for high precision const int p0_225 = (int)(0.225 * (1 << 12)); const int p0_775 = (int)(0.775 * (1 << 12)); if (normalized < 0) { int value = (normalized << 3) + ((normalized * normalized) >> 8); // return value; // if low precision return ((p0_775 * value) >> 12) - ((((p0_225 * value) >> 12) * value) >> 12); } else { int value = (normalized << 3) - ((normalized * normalized) >> 8); // return value; // if low precision return ((p0_775 * value) >> 12) + ((((p0_225 * value) >> 12) * value) >> 12); } }