C#: Add `BezierInterpolate` method

Adds a `BezierInterpolate` method for floats in `Mathf` and for vectors
in `Vector2` and `Vector3`.
This commit is contained in:
Raul Santos 2022-07-06 21:35:37 +02:00
parent 76d0a99707
commit 71f99c6d40
No known key found for this signature in database
GPG Key ID: B532473AE3A803E4
3 changed files with 72 additions and 6 deletions

View File

@ -197,6 +197,28 @@ namespace Godot
(-pre + 3.0f * from - 3.0f * to + post) * (weight * weight * weight)); (-pre + 3.0f * from - 3.0f * to + post) * (weight * weight * weight));
} }
/// <summary>
/// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by
/// the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points.
/// </summary>
/// <param name="start">The start value for the interpolation.</param>
/// <param name="control1">Control point that defines the bezier curve.</param>
/// <param name="control2">Control point that defines the bezier curve.</param>
/// <param name="end">The destination value for the interpolation.</param>
/// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The resulting value of the interpolation.</returns>
public static real_t BezierInterpolate(real_t start, real_t control1, real_t control2, real_t end, real_t t)
{
// Formula from Wikipedia article on Bezier curves
real_t omt = 1 - t;
real_t omt2 = omt * omt;
real_t omt3 = omt2 * omt;
real_t t2 = t * t;
real_t t3 = t2 * t;
return start * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
}
/// <summary> /// <summary>
/// Converts an angle expressed in degrees to radians. /// Converts an angle expressed in degrees to radians.
/// </summary> /// </summary>

View File

@ -220,6 +220,27 @@ namespace Godot
); );
} }
/// <summary>
/// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by this vector
/// and the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points.
/// </summary>
/// <param name="control1">Control point that defines the bezier curve.</param>
/// <param name="control2">Control point that defines the bezier curve.</param>
/// <param name="end">The destination vector.</param>
/// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated vector.</returns>
public Vector2 BezierInterpolate(Vector2 control1, Vector2 control2, Vector2 end, real_t t)
{
// Formula from Wikipedia article on Bezier curves
real_t omt = 1 - t;
real_t omt2 = omt * omt;
real_t omt3 = omt2 * omt;
real_t t2 = t * t;
real_t t3 = t2 * t;
return this * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
}
/// <summary> /// <summary>
/// Returns the normalized vector pointing from this vector to <paramref name="to"/>. /// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary> /// </summary>
@ -522,7 +543,8 @@ namespace Godot
{ {
real_t startLengthSquared = LengthSquared(); real_t startLengthSquared = LengthSquared();
real_t endLengthSquared = to.LengthSquared(); real_t endLengthSquared = to.LengthSquared();
if (startLengthSquared == 0.0 || endLengthSquared == 0.0) { if (startLengthSquared == 0.0 || endLengthSquared == 0.0)
{
// Zero length vectors have no angle, so the best we can do is either lerp or throw an error. // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
return Lerp(to, weight); return Lerp(to, weight);
} }

View File

@ -213,6 +213,27 @@ namespace Godot
); );
} }
/// <summary>
/// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by this vector
/// and the given <paramref name="control1"/>, <paramref name="control2"/> and <paramref name="end"/> points.
/// </summary>
/// <param name="control1">Control point that defines the bezier curve.</param>
/// <param name="control2">Control point that defines the bezier curve.</param>
/// <param name="end">The destination vector.</param>
/// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated vector.</returns>
public Vector3 BezierInterpolate(Vector3 control1, Vector3 control2, Vector3 end, real_t t)
{
// Formula from Wikipedia article on Bezier curves
real_t omt = 1 - t;
real_t omt2 = omt * omt;
real_t omt3 = omt2 * omt;
real_t t2 = t * t;
real_t t3 = t2 * t;
return this * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3;
}
/// <summary> /// <summary>
/// Returns the normalized vector pointing from this vector to <paramref name="to"/>. /// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary> /// </summary>
@ -562,7 +583,8 @@ namespace Godot
{ {
real_t startLengthSquared = LengthSquared(); real_t startLengthSquared = LengthSquared();
real_t endLengthSquared = to.LengthSquared(); real_t endLengthSquared = to.LengthSquared();
if (startLengthSquared == 0.0 || endLengthSquared == 0.0) { if (startLengthSquared == 0.0 || endLengthSquared == 0.0)
{
// Zero length vectors have no angle, so the best we can do is either lerp or throw an error. // Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
return Lerp(to, weight); return Lerp(to, weight);
} }