/// <summary> /// Returns the signed angle to the given vector, in radians. /// The sign of the angle is positive in a counter-clockwise /// direction and negative in a clockwise direction when viewed /// from the side specified by the `axis`. /// </summary> /// <param name="to">The other vector to compare this vector to.</param> /// <param name="axis">The reference axis to use for the angle sign.</param> /// <returns>The signed angle between the two vectors, in radians.</returns> public double SignedAngleTo(Vector3d to, Vector3d axis) { Vector3d crossTo = Cross(to); double unsignedAngle = Mathd.Atan2(crossTo.Length(), Dot(to)); double sign = crossTo.Dot(axis); return((sign < 0) ? -unsignedAngle : unsignedAngle); }
public Transform2Dd InterpolateWith(Transform2Dd m, double c) { double r1 = Rotation; double r2 = m.Rotation; Vector2d s1 = Scale; Vector2d s2 = m.Scale; // Slerp rotation var v1 = new Vector2d(Mathd.Cos(r1), Mathd.Sin(r1)); var v2 = new Vector2d(Mathd.Cos(r2), Mathd.Sin(r2)); double dot = v1.Dot(v2); // Clamp dot to [-1, 1] dot = dot < -1.0f ? -1.0f : (dot > 1.0f ? 1.0f : dot); Vector2d v; if (dot > 0.9995f) { // Linearly interpolate to avoid numerical precision issues v = v1.LinearInterpolate(v2, c).Normalized(); } else { double angle = c * Mathd.Acos(dot); Vector2d v3 = (v2 - v1 * dot).Normalized(); v = v1 * Mathd.Cos(angle) + v3 * Mathd.Sin(angle); } // Extract parameters Vector2d p1 = origin; Vector2d p2 = m.origin; // Construct matrix var res = new Transform2Dd(Mathd.Atan2(v.y, v.x), p1.LinearInterpolate(p2, c)); Vector2d scale = s1.LinearInterpolate(s2, c); res.x *= scale; res.y *= scale; return(res); }
/// <summary> /// Returns the angle between the line connecting the two points and the X axis, in radians. /// </summary> /// <param name="to">The other vector to compare this vector to.</param> /// <returns>The angle between the two vectors, in radians.</returns> public double AngleToPoint(Vector2d to) { return(Mathd.Atan2(y - to.y, x - to.x)); }
/// <summary> /// Returns the angle to the given vector, in radians. /// </summary> /// <param name="to">The other vector to compare this vector to.</param> /// <returns>The angle between the two vectors, in radians.</returns> public double AngleTo(Vector2d to) { return(Mathd.Atan2(Cross(to), Dot(to))); }
/// <summary> /// Returns this vector's angle with respect to the X axis, or (1, 0) vector, in radians. /// /// Equivalent to the result of <see cref="Mathd.Atan2(double, double)"/> when /// called with the vector's `y` and `x` as parameters: `Mathd.Atan2(v.y, v.x)`. /// </summary> /// <returns>The angle of this vector, in radians.</returns> public double Angle() { return(Mathd.Atan2(y, x)); }
/// <summary> /// Returns the unsigned minimum angle to the given vector, in radians. /// </summary> /// <param name="to">The other vector to compare this vector to.</param> /// <returns>The unsigned angle between the two vectors, in radians.</returns> public double AngleTo(Vector3d to) { return(Mathd.Atan2(Cross(to).Length(), Dot(to))); }