public Transform2D InterpolateWith(Transform2D m, real_t c) { real_t r1 = Rotation; real_t r2 = m.Rotation; Vector2 s1 = Scale; Vector2 s2 = m.Scale; // Slerp rotation var v1 = new Vector2(Mathf.Cos(r1), Mathf.Sin(r1)); var v2 = new Vector2(Mathf.Cos(r2), Mathf.Sin(r2)); real_t dot = v1.Dot(v2); // Clamp dot to [-1, 1] dot = dot < -1.0f ? -1.0f : (dot > 1.0f ? 1.0f : dot); Vector2 v; if (dot > 0.9995f) { // Linearly interpolate to avoid numerical precision issues v = v1.LinearInterpolate(v2, c).Normalized(); } else { real_t angle = c * Mathf.Acos(dot); Vector2 v3 = (v2 - v1 * dot).Normalized(); v = v1 * Mathf.Cos(angle) + v3 * Mathf.Sin(angle); } // Extract parameters Vector2 p1 = origin; Vector2 p2 = m.origin; // Construct matrix var res = new Transform2D(Mathf.Atan2(v.y, v.x), p1.LinearInterpolate(p2, c)); Vector2 scale = s1.LinearInterpolate(s2, c); res.x *= scale; res.y *= scale; return(res); }
/// <summary> /// Interpolates this transform to the other <paramref name="transform"/> by <paramref name="weight"/>. /// </summary> /// <param name="transform">The other transform.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The interpolated transform.</returns> public Transform2D InterpolateWith(Transform2D transform, real_t weight) { real_t r1 = Rotation; real_t r2 = transform.Rotation; Vector2 s1 = Scale; Vector2 s2 = transform.Scale; // Slerp rotation var v1 = new Vector2(Mathf.Cos(r1), Mathf.Sin(r1)); var v2 = new Vector2(Mathf.Cos(r2), Mathf.Sin(r2)); real_t dot = v1.Dot(v2); dot = Mathf.Clamp(dot, -1.0f, 1.0f); Vector2 v; if (dot > 0.9995f) { // Linearly interpolate to avoid numerical precision issues v = v1.LinearInterpolate(v2, weight).Normalized(); } else { real_t angle = weight * Mathf.Acos(dot); Vector2 v3 = (v2 - (v1 * dot)).Normalized(); v = (v1 * Mathf.Cos(angle)) + (v3 * Mathf.Sin(angle)); } // Extract parameters Vector2 p1 = origin; Vector2 p2 = transform.origin; // Construct matrix var res = new Transform2D(Mathf.Atan2(v.y, v.x), p1.LinearInterpolate(p2, weight)); Vector2 scale = s1.LinearInterpolate(s2, weight); res.x *= scale; res.y *= scale; return(res); }