예제 #1
0
        public static Vector3 Parse(string text)
        {
            if (text[0] != '(' || text[text.Length - 1] != ')')
            {
                throw new System.FormatException("The input text must starts with '(', and ends with ')'.");
            }
            string[] tokens = text.Substring(1, text.Length - 2).Split(',');
            if (tokens.Length != 3)
            {
                throw new System.FormatException("The input text must contains 3 elements.");
            }
            int x, y, z;

            x = y = z = 0;
            if (!int.TryParse(tokens[0], out x))
            {
                throw new System.FormatException("The element 1 is not a integer.");
            }
            if (!int.TryParse(tokens[1], out y))
            {
                throw new System.FormatException("The element 2 is not a integer.");
            }
            if (!int.TryParse(tokens[2], out z))
            {
                throw new System.FormatException("The element 3 is not a integer.");
            }
            return(new Vector3(Number.Raw(x), Number.Raw(y), Number.Raw(z)));
        }
예제 #2
0
        public static Number Atan2(Number y, Number x)
        {
            CheckRange(y, Number.Raw(int.MinValue), Number.Raw(int.MaxValue), "Atan2(y)");

            if (y == Number.zero)
            {
                return(Number.zero);
            }
            if (x == Number.zero)
            {
                CheckNotEqual(y, Number.zero, "Atan2(y) when x == 0");
                return(HALF_PI * Sign(y));
            }
            Number sign   = Sign(y) * Sign(x);
            Number result = Abs(Atan(y / x)) * sign;

            if (y < Number.zero && x < Number.zero)
            {
                result -= PI;
            }
            else if (y >= Number.zero && x < Number.zero)
            {
                result += PI;
            }
            CheckRange(result, -Math.PI, Math.PI, "Atan2(result)");
            return(result);
        }
예제 #3
0
        public static Number Rad2Deg(Number radians)
        {
            const long X = (long)(57.295779513082320876798154814105 * SQR_FACTOR * SQR_FACTOR);

            return(Number.Raw((int)(radians.raw * X / SQR_FACTOR / SQR_FACTOR)));
            //const long X = (long)(57.296 * FACTOR);
            //return Number.Raw((int)(Math.RndDiv(radians.raw * X, FACTOR)));
        }
예제 #4
0
        static Number fastAsin(Number x)
        {
            Number sign = Sign(x);

            x = Clamp(Abs(x), Number.zero, Number.one);
            Number result = Number.Raw(asinTable[x.raw]);

            return(sign * result);
        }
예제 #5
0
        public static Number Sqrt(Number n)
        {
            long x = (long)n.raw * Math.FACTOR;

            if (x > int.MaxValue)
            {
                x = RndDiv(x, Math.SQR_FACTOR);
            }
            return(Number.Raw(Math.Sqrt((int)x)));
        }
예제 #6
0
        public static Number AngleRad(Vector2 lhs, Vector2 rhs)
        {
            Math.CheckRange(lhs);
            Math.CheckRange(rhs);

            lhs.Normalize();
            rhs.Normalize();
            Number radians = Math.Acos(Number.Raw(Math.Clamp(_Dot(lhs, rhs) / Math.FACTOR, -Math.FACTOR, Math.FACTOR)));

            return(radians);
        }
예제 #7
0
        public static Quaternion operator *(Quaternion lhs, Quaternion rhs)
        {
            long w = lhs.w.raw * rhs.w.raw - lhs.x.raw * rhs.x.raw - lhs.y.raw * rhs.y.raw - lhs.z.raw * rhs.z.raw;
            long x = lhs.w.raw * rhs.x.raw + lhs.x.raw * rhs.w.raw + lhs.y.raw * rhs.z.raw - lhs.z.raw * rhs.y.raw;
            long y = lhs.w.raw * rhs.y.raw + lhs.y.raw * rhs.w.raw + lhs.z.raw * rhs.x.raw - lhs.x.raw * rhs.z.raw;
            long z = lhs.w.raw * rhs.z.raw + lhs.z.raw * rhs.w.raw + lhs.x.raw * rhs.y.raw - lhs.y.raw * rhs.x.raw;

            w = Math.RndDiv(w, Math.FACTOR);
            x = Math.RndDiv(x, Math.FACTOR);
            y = Math.RndDiv(y, Math.FACTOR);
            z = Math.RndDiv(z, Math.FACTOR);
            return(new Quaternion(Number.Raw((int)x), Number.Raw((int)y), Number.Raw((int)z), Number.Raw((int)w)));
        }
예제 #8
0
        public static Vector3 Cross(Vector3 lhs, Vector3 rhs)
        {
            Math.CheckRange(lhs);
            Math.CheckRange(rhs);

            int x = lhs.y.raw * rhs.z.raw - rhs.y.raw * lhs.z.raw;
            int y = lhs.z.raw * rhs.x.raw - rhs.z.raw * lhs.x.raw;
            int z = lhs.x.raw * rhs.y.raw - rhs.x.raw * lhs.y.raw;          //2 power of factor

            return(new Vector3(
                       Number.Raw(Math.RndDiv(x, Math.FACTOR)),
                       Number.Raw(Math.RndDiv(y, Math.FACTOR)),
                       Number.Raw(Math.RndDiv(z, Math.FACTOR))));
        }
예제 #9
0
        public static Quaternion Euler(Number x, Number y, Number z)
        {
            Number  eulerX = Math.Deg2Rad(x) / new Number(2);
            Number  eulerY = Math.Deg2Rad(y) / new Number(2);
            Number  eulerZ = Math.Deg2Rad(z) / new Number(2);
            Vector3 c      = new Vector3(Math.Cos(eulerX), Math.Cos(eulerY), Math.Cos(eulerZ));
            Vector3 s      = new Vector3(Math.Sin(eulerX), Math.Sin(eulerY), Math.Sin(eulerZ));

            int ww = (int)Math.RndDiv((long)c.x.raw * c.y.raw * c.z.raw + (long)s.x.raw * s.y.raw * s.z.raw, Math.SQR_FACTOR);
            int xx = (int)Math.RndDiv((long)s.x.raw * c.y.raw * c.z.raw + (long)c.x.raw * s.y.raw * s.z.raw, Math.SQR_FACTOR);
            int yy = (int)Math.RndDiv((long)c.x.raw * s.y.raw * c.z.raw - (long)s.x.raw * c.y.raw * s.z.raw, Math.SQR_FACTOR);
            int zz = (int)Math.RndDiv((long)c.x.raw * c.y.raw * s.z.raw - (long)s.x.raw * s.y.raw * c.z.raw, Math.SQR_FACTOR);

            return(new Quaternion(Number.Raw(xx), Number.Raw(yy), Number.Raw(zz), Number.Raw(ww)));
        }
예제 #10
0
        public static Quaternion Euler(Vector3 euler)
        {
            Math.CheckRange(euler);

            Number  eulerX = Math.Deg2Rad(euler.x) / new Number(2);
            Number  eulerY = Math.Deg2Rad(euler.y) / new Number(2);
            Number  eulerZ = Math.Deg2Rad(euler.z) / new Number(2);
            Vector3 c      = new Vector3(Math.Cos(eulerX), Math.Cos(eulerY), Math.Cos(eulerZ));
            Vector3 s      = new Vector3(Math.Sin(eulerX), Math.Sin(eulerY), Math.Sin(eulerZ));

            int w = (int)Math.RndDiv((long)c.x.raw * c.y.raw * c.z.raw + (long)s.x.raw * s.y.raw * s.z.raw, Math.SQR_FACTOR);
            int x = (int)Math.RndDiv((long)s.x.raw * c.y.raw * c.z.raw + (long)c.x.raw * s.y.raw * s.z.raw, Math.SQR_FACTOR);
            int y = (int)Math.RndDiv((long)c.x.raw * s.y.raw * c.z.raw - (long)s.x.raw * c.y.raw * s.z.raw, Math.SQR_FACTOR);
            int z = (int)Math.RndDiv((long)c.x.raw * c.y.raw * s.z.raw - (long)s.x.raw * s.y.raw * c.z.raw, Math.SQR_FACTOR);

            return(new Quaternion(Number.Raw(x), Number.Raw(y), Number.Raw(z), Number.Raw(w)));
        }
예제 #11
0
        static Number cos_52s(Number x)
        {
            long xx = (long)x.raw * x.raw;

            Utils.Trace(string.Format("x:{0} xx:{1}", x, xx));

            const long A = (long)(0.9999932946f * SQR_FACTOR);
            const long B = (long)(-0.4999124376f * SQR_FACTOR);
            const long C = (long)(0.0414877472f * SQR_FACTOR);
            const long D = (long)(-0.0012712095f * SQR_FACTOR);

            Utils.Trace(string.Format("A:{0} B:{1} C:{2} D:{3}", A, B, C, D));

            long r1 = C + Math.RndDiv(xx * D, SQR_FACTOR);
            long r2 = B + Math.RndDiv(xx * r1, SQR_FACTOR);
            long r3 = A + Math.RndDiv(xx * r2, SQR_FACTOR);

            Utils.Trace(string.Format("r1:{0} r2:{1} r3:{2}", r1, r2, r3));

            return(Number.Raw((int)Math.RndDiv(r3, FACTOR)));
        }
예제 #12
0
        public static Vector3 CrossAndNormalize(Vector3 lhs, Vector3 rhs)
        {
            Math.CheckRange(lhs);
            Math.CheckRange(rhs);

            int  x      = lhs.y.raw * rhs.z.raw - rhs.y.raw * lhs.z.raw;
            int  y      = lhs.z.raw * rhs.x.raw - rhs.z.raw * lhs.x.raw;
            int  z      = lhs.x.raw * rhs.y.raw - rhs.x.raw * lhs.y.raw;    //2 power of factor
            long sqrMag = (long)(x) * x + (long)(y) * y + (long)(z) * z;    //4 power of factor

            if (sqrMag > (long)int.MaxValue)
            {
                long sqrMag1 = Math.RndDiv(sqrMag, Math.SQR_FACTOR); //2 power of factor
                if (sqrMag1 > (long)int.MaxValue)
                {
                    int sqrMag2 = (int)Math.RndDiv(sqrMag1, Math.SQR_FACTOR); // 0 power of factor
                    int mag     = Math.Sqrt(sqrMag2);                         //0 power of factor
                    x = (int)Math.RndDiv(x, mag * Math.FACTOR);
                    y = (int)Math.RndDiv(y, mag * Math.FACTOR);
                    z = (int)Math.RndDiv(z, mag * Math.FACTOR);
                }
                else
                {
                    int mag = Math.Sqrt((int)sqrMag1);       //1 power of factor
                    x = (int)Math.RndDiv(x, mag);
                    y = (int)Math.RndDiv(y, mag);
                    z = (int)Math.RndDiv(z, mag);
                }
            }
            else
            {
                int mag = Math.Sqrt((int)sqrMag);                   //2 power of factor
                x = (int)(Math.RndDiv((long)x * Math.FACTOR, mag)); //1 power of factor
                y = (int)(Math.RndDiv((long)y * Math.FACTOR, mag)); //1 power of factor
                z = (int)(Math.RndDiv((long)z * Math.FACTOR, mag)); //1 power of factor
            }
            return(new Vector3(Number.Raw(x), Number.Raw(y), Number.Raw(z)));
        }
예제 #13
0
        public static Number Atan(Number x)
        {
            Number rad = Number.zero;

            if (x > new Number(3037))
            {
                rad = HALF_PI;
            }
            else if (x < new Number(-3037))
            {
                rad = -HALF_PI;
            }
            else
            {
                long A       = (long)x.raw * x.raw * Math.SQR_FACTOR; //4 POF
                long B       = (long)x.raw * x.raw + Math.SQR_FACTOR; //2 POF
                long C       = Math.RndDiv(A, B);                     //2 POF
                int  sqrSinA = (int)C;
                int  sinA    = Sqrt(sqrSinA);                         //1 POF
                rad = Asin(Number.Raw(sinA)) * Sign(x);
            }
            return(rad);
        }
예제 #14
0
 public static Number Dot(Vector2 lhs, Vector2 rhs)
 {
     return(Number.Raw(_Dot(lhs, rhs) / Math.FACTOR));
 }
예제 #15
0
        public static Number Deg2Rad(Number degrees)
        {
            const long X = (long)(0.01745329251994329576923690768489 * FACTOR * FACTOR);

            return(Number.Raw((int)Math.RndDiv(Math.RndDiv(degrees.raw * X, FACTOR), FACTOR)));
        }
예제 #16
0
 public static Number Acos(Number x)
 {
     CheckRange(x, -Number.one, Number.one, "Acos(x)");
     return(Number.Raw(1571) - fastAsin(x));
 }
예제 #17
0
 public static Number Abs(Number x)
 {
     return(Number.Raw(System.Math.Abs(x.raw)));
 }