示例#1
0
        /// <summary>
        /// Returns the angle between 0 and 2*pi between the two vectors given.
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        public static Radian Angle(VectorF2D v1, VectorF2D v2)
        {
            double size_v1 = v1.Size;
            double size_v2 = v2.Size;

            double dot   = VectorF2D.Dot(v1, v2);
            double cross = VectorF2D.Cross(v1, v2);

            // filter out the vectors that are parallel.
            if (v1[0] == v2[0] &&
                v1[1] == v2[1])
            {
                return(0);
            }
            else if (v1[0] == v2[0] &&
                     v1[1] == -v2[1])
            {
                return(System.Math.PI / 2.0f);
            }
            else if (v1[0] == -v2[0] &&
                     v1[1] == v2[1])
            {
                return(-System.Math.PI / 2.0f);
            }
            else if (v1[0] == -v2[0] &&
                     v1[1] == -v2[1])
            {
                return(System.Math.PI);
            }

            // split per quadrant.
            double angle;

            if (dot > 0)
            {     // dot > 0
                if (cross > 0)
                { // dot > 0 and cross > 0
                    // Quadrant 1
                    angle = (double)System.Math.Asin(cross / (size_v1 * size_v2));
                    if (angle < System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 1.
                }
                else
                { // dot > 0 and cross <= 0
                    // Quadrant 4
                    angle = (double)(System.Math.PI * 2.0f) + (double)System.Math.Asin(cross / (size_v1 * size_v2));
                    if (angle > (double)(System.Math.PI * 2.0f) - System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)(System.Math.PI * 2.0f) - (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 1.
                }
            }
            else
            {     // dot <= 0
                if (cross > 0)
                { // dot > 0 and cross > 0
                    // Quadrant 2
                    angle = (double)System.Math.PI - (double)System.Math.Asin(cross / (size_v1 * size_v2));
                    if (angle > System.Math.PI / 2f + System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 2.
                }
                else
                { // dot > 0 and cross <= 0
                    // Quadrant 3
                    angle = -(-(double)System.Math.PI + (double)System.Math.Asin(cross / (size_v1 * size_v2)));
                    if (angle < System.Math.PI + System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)(System.Math.PI * 2.0f) - (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 3.
                }
            }
            return(angle);
        }
示例#2
0
        public void Vector2DTest()
        {
            // create the test cases.
            VectorF2D a_b = new VectorF2D(1 , 1);
            VectorF2D b_a = new VectorF2D(-1,-1);
            VectorF2D a_c = new VectorF2D(-1, 1);
            VectorF2D a_d = new VectorF2D(0, 1);
            VectorF2D a_e = new VectorF2D(-1, 0);
            VectorF2D a_f = new VectorF2D(0, 1);
            VectorF2D a_g = new VectorF2D(0, -1);

            // calculate the results
            double sqrt_2 = (double)System.Math.Sqrt(2);

            // check the sizes.
            Assert.AreEqual(a_b.Size, sqrt_2, string.Format("Size should be {0}!", sqrt_2));
            Assert.AreEqual(b_a.Size, sqrt_2, string.Format("Size should be {0}!", sqrt_2));

            // check the equality.
            Assert.IsTrue(a_b.Inverse == b_a, "The inverse of ab should be ba!");

            // check the cross product.
            Assert.AreEqual(VectorF2D.Cross(a_b, b_a), 0, "Cross product of two parallel vectors should be 0!");
            Assert.AreEqual(VectorF2D.Cross(a_b, a_c), 2, string.Format("Cross product of two perpendicular vectors should be maximized; in this case {0}!", 2));
            Assert.AreEqual(VectorF2D.Cross(b_a, a_b), 0, "Cross product of two parallel vectors should be 0!");
            Assert.AreEqual(VectorF2D.Cross(a_c, a_b), -2, string.Format("Cross product of two perpendicular vectors should be maximized; in this case {0}!", -2));

            // check the dot product.
            Assert.AreEqual(VectorF2D.Dot(a_b, b_a), -2, string.Format("Cross product of two parallel vectors should be maximized (absolute value); in this case {0}!", -2));
            Assert.AreEqual(VectorF2D.Dot(a_b, a_c), 0, string.Format("Cross product of two perpendicular vectors should be {0}!", 0));
            Assert.AreEqual(VectorF2D.Dot(a_b, a_d), 1);
            Assert.AreEqual(VectorF2D.Dot(a_b, a_e), -1);
            Assert.AreEqual(VectorF2D.Dot(a_b, a_f), 1);
            Assert.AreEqual(VectorF2D.Dot(a_b, a_g), -1);
            Assert.AreEqual(VectorF2D.Dot(b_a, a_b), -2, string.Format("Cross product of two parallel vectors should be maximized; in this case {0}!", -2));
            Assert.AreEqual(VectorF2D.Dot(a_c, a_b), 0, string.Format("Cross product of two perpendicular vectors should be {0}!", 0));
        }
示例#3
0
 /// <summary>
 /// Compares the two vectors just based on their direction.
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public bool CompareNormalized(VectorF2D other)
 { // be a sensitive as possible.
     return(this.CompareNormalized(other, 0));
 }
示例#4
0
 /// <summary>
 /// Calculates the cross product.
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static double Cross(VectorF2D a, VectorF2D b)
 {
     return(a[0] * b[1] - a[1] * b[0]);
 }
示例#5
0
 public bool CompareNormalized(VectorF2D other)
 {
     return(this.CompareNormalized(other, 0.0));
 }
示例#6
0
 /// <summary>
 /// Returns the angle between this vector and the given vector in the range 0-2pi.
 /// </summary>
 /// <param name="v"></param>
 /// <returns></returns>
 public Radian Angle(VectorF2D v)
 {
     return(VectorF2D.Angle(this, v));
 }
示例#7
0
        /// <summary>
        /// Compares the two vectors just based on their direction.
        /// </summary>
        /// <param name="other">The other vector to compare to.</param>
        /// <param name="epsilon">The tolerance on the total difference between the normalized vectors.</param>
        /// <returns></returns>
        public bool CompareNormalized(VectorF2D other, double epsilon)
        {
            VectorF2D normalizedThis = this.Normalize();
            VectorF2D normalizedOther = other.Normalize();

            double difference = System.Math.Abs(normalizedThis[0] - normalizedOther[0]) +
                System.Math.Abs(normalizedThis[1] - normalizedOther[1]);
            return difference < epsilon;
        }
示例#8
0
        public static Radian Angle(VectorF2D v1, VectorF2D v2)
        {
            double size1 = v1.Size;
            double size2 = v2.Size;
            double num1  = VectorF2D.Dot(v1, v2);
            double num2  = VectorF2D.Cross(v1, v2);

            if (v1[0] == v2[0] && v1[1] == v2[1])
            {
                return((Radian)0.0);
            }
            if (v1[0] == v2[0] && v1[1] == -v2[1])
            {
                return((Radian)(System.Math.PI / 2.0));
            }
            if (v1[0] == -v2[0] && v1[1] == v2[1])
            {
                return((Radian)(-1.0 * System.Math.PI / 2.0));
            }
            if (v1[0] == -v2[0] && v1[1] == -v2[1])
            {
                return((Radian)System.Math.PI);
            }
            double num3;

            if (num1 > 0.0)
            {
                if (num2 > 0.0)
                {
                    num3 = System.Math.Asin(num2 / (size1 * size2));
                    if (num3 < System.Math.PI / 4.0)
                    {
                        num3 = System.Math.Acos(num1 / (size1 * size2));
                    }
                }
                else
                {
                    num3 = 2.0 * System.Math.PI + System.Math.Asin(num2 / (size1 * size2));
                    if (num3 > 7.0 * System.Math.PI / 4.0)
                    {
                        num3 = 2.0 * System.Math.PI - System.Math.Acos(num1 / (size1 * size2));
                    }
                }
            }
            else if (num2 > 0.0)
            {
                num3 = System.Math.PI - System.Math.Asin(num2 / (size1 * size2));
                if (num3 > 3.0 * System.Math.PI / 4.0)
                {
                    num3 = System.Math.Acos(num1 / (size1 * size2));
                }
            }
            else
            {
                num3 = -(System.Math.Asin(num2 / (size1 * size2)) - System.Math.PI);
                if (num3 < 5.0 * System.Math.PI / 4.0)
                {
                    num3 = 2.0 * System.Math.PI - System.Math.Acos(num1 / (size1 * size2));
                }
            }
            return((Radian)num3);
        }
示例#9
0
 /// <summary>
 /// Compares the two vectors just based on their direction.
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public bool CompareNormalized(VectorF2D other)
 {
     // be a sensitive as possible.
     return this.CompareNormalized(other, 0);
 }
示例#10
0
 /// <summary>
 /// Returns the angle between this vector and the given vector in the range 0-2pi.
 /// </summary>
 /// <param name="v"></param>
 /// <returns></returns>
 public Radian Angle(VectorF2D v)
 {
     return VectorF2D.Angle(this, v);
 }
示例#11
0
        /// <summary>
        /// Calcuates the dot-product of the two given vectors.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static double Dot(VectorF2D a, VectorF2D b)
        {
            double dot = 0.0f;

            for (int idx = 0; idx < 2; idx++)
            {
                dot = dot + a[idx] * b[idx];
            }

            return dot;
        }
示例#12
0
 /// <summary>
 /// Calculates the cross product.
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static double Cross(VectorF2D a, VectorF2D b)
 {
     return a[0] * b[1] - a[1] * b[0];
 }
示例#13
0
        /// <summary>
        /// Returns the angle between 0 and 2*pi between the two vectors given.
        /// </summary>
        /// <param name="v1"></param>
        /// <param name="v2"></param>
        /// <returns></returns>
        public static Radian Angle(VectorF2D v1, VectorF2D v2)
        {
            double size_v1 = v1.Size;
            double size_v2 = v2.Size;

            double dot = VectorF2D.Dot(v1, v2);
            double cross = VectorF2D.Cross(v1, v2);

            // filter out the vectors that are parallel.
            if (v1[0] == v2[0]
                && v1[1] == v2[1])
            {
                return 0;
            }
            else if (v1[0] == v2[0]
                && v1[1] == -v2[1])
            {
                return System.Math.PI / 2.0f;
            }
            else if (v1[0] == -v2[0]
                && v1[1] == v2[1])
            {
                return -System.Math.PI / 2.0f;
            }
            else if (v1[0] == -v2[0]
                && v1[1] == -v2[1])
            {
                return System.Math.PI;
            }

            // split per quadrant.
            double angle;
            if (dot > 0)
            { // dot > 0
                if (cross > 0)
                { // dot > 0 and cross > 0
                    // Quadrant 1
                    angle = (double)System.Math.Asin(cross / (size_v1 * size_v2));
                    if (angle < System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 1.
                }
                else
                { // dot > 0 and cross <= 0
                    // Quadrant 4
                    angle = (double)(System.Math.PI * 2.0f) + (double)System.Math.Asin(cross / (size_v1 * size_v2));
                    if (angle > (double)(System.Math.PI * 2.0f) - System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)(System.Math.PI * 2.0f) - (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 1.
                }
            }
            else
            { // dot <= 0
                if (cross > 0)
                { // dot > 0 and cross > 0
                    // Quadrant 2
                    angle = (double)System.Math.PI - (double)System.Math.Asin(cross / (size_v1 * size_v2));
                    if (angle > System.Math.PI / 2f + System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 2.
                }
                else
                { // dot > 0 and cross <= 0
                    // Quadrant 3
                    angle = -(-(double)System.Math.PI + (double)System.Math.Asin(cross / (size_v1 * size_v2)));
                    if (angle < System.Math.PI + System.Math.PI / 4f)
                    { // use cosine.
                        angle = (double)(System.Math.PI * 2.0f) - (double)System.Math.Acos(dot / (size_v1 * size_v2));
                    }
                    // angle is ok here for quadrant 3.
                }
            }
            return angle;
        }