/// <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); }
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); }