diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-10-02 13:15:49 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-10-02 13:15:49 +0200 |
commit | 7588e3ff0dd7f5e522009f770f99fe593d1ebdb0 (patch) | |
tree | 10f196c218e21815984cdfcd45e53c016d7285c1 /modules | |
parent | ce236a6d03bfb4ccd81fc60b859b28122edaa20d (diff) | |
parent | 3a39de4e2f18c8b9764166e9f6cb882d8e2c7017 (diff) | |
download | redot-engine-7588e3ff0dd7f5e522009f770f99fe593d1ebdb0.tar.gz |
Merge pull request #80225 from ettiSurreal/rotate-toward
Add `rotate_toward` and `angle_difference` methods.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 81b2ffef34..09269508b7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -134,6 +134,38 @@ namespace Godot } /// <summary> + /// Returns the difference between the two angles, + /// in range of -<see cref="Pi"/>, <see cref="Pi"/>. + /// When <paramref name="from"/> and <paramref name="to"/> are opposite, + /// returns -<see cref="Pi"/> if <paramref name="from"/> is smaller than <paramref name="to"/>, + /// or <see cref="Pi"/> otherwise. + /// </summary> + /// <param name="from">The start angle.</param> + /// <param name="to">The destination angle.</param> + /// <returns>The difference between the two angles.</returns> + public static float AngleDifference(float from, float to) + { + float difference = (to - from) % MathF.Tau; + return ((2.0f * difference) % MathF.Tau) - difference; + } + + /// <summary> + /// Returns the difference between the two angles, + /// in range of -<see cref="Pi"/>, <see cref="Pi"/>. + /// When <paramref name="from"/> and <paramref name="to"/> are opposite, + /// returns -<see cref="Pi"/> if <paramref name="from"/> is smaller than <paramref name="to"/>, + /// or <see cref="Pi"/> otherwise. + /// </summary> + /// <param name="from">The start angle.</param> + /// <param name="to">The destination angle.</param> + /// <returns>The difference between the two angles.</returns> + public static double AngleDifference(double from, double to) + { + double difference = (to - from) % Math.Tau; + return ((2.0 * difference) % Math.Tau) - difference; + } + + /// <summary> /// Returns the arc sine of <paramref name="s"/> in radians. /// Use to get the angle of sine <paramref name="s"/>. /// </summary> @@ -1093,9 +1125,7 @@ namespace Godot /// <returns>The resulting angle of the interpolation.</returns> public static float LerpAngle(float from, float to, float weight) { - float difference = (to - from) % MathF.Tau; - float distance = ((2 * difference) % MathF.Tau) - difference; - return from + (distance * weight); + return from + AngleDifference(from, to) * weight; } /// <summary> @@ -1110,9 +1140,7 @@ namespace Godot /// <returns>The resulting angle of the interpolation.</returns> public static double LerpAngle(double from, double to, double weight) { - double difference = (to - from) % Math.Tau; - double distance = ((2 * difference) % Math.Tau) - difference; - return from + (distance * weight); + return from + AngleDifference(from, to) * weight; } /// <summary> @@ -1429,6 +1457,38 @@ namespace Godot } /// <summary> + /// Rotates <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> amount. Will not go past <paramref name="to"/>. + /// Similar to <see cref="MoveToward(float, float, float)"/> but interpolates correctly when the angles wrap around <see cref="Tau"/>. + /// If <paramref name="delta"/> is negative, this function will rotate away from <paramref name="to"/>, toward the opposite angle, and will not go past the opposite angle. + /// </summary> + /// <param name="from">The start angle.</param> + /// <param name="to">The angle to move towards.</param> + /// <param name="delta">The amount to move by.</param> + /// <returns>The angle after moving.</returns> + public static float RotateToward(float from, float to, float delta) + { + float difference = AngleDifference(from, to); + float absDifference = Math.Abs(difference); + return from + Math.Clamp(delta, absDifference - MathF.PI, absDifference) * (difference >= 0.0f ? 1.0f : -1.0f); + } + + /// <summary> + /// Rotates <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> amount. Will not go past <paramref name="to"/>. + /// Similar to <see cref="MoveToward(double, double, double)"/> but interpolates correctly when the angles wrap around <see cref="Tau"/>. + /// If <paramref name="delta"/> is negative, this function will rotate away from <paramref name="to"/>, toward the opposite angle, and will not go past the opposite angle. + /// </summary> + /// <param name="from">The start angle.</param> + /// <param name="to">The angle to move towards.</param> + /// <param name="delta">The amount to move by.</param> + /// <returns>The angle after moving.</returns> + public static double RotateToward(double from, double to, double delta) + { + double difference = AngleDifference(from, to); + double absDifference = Math.Abs(difference); + return from + Math.Clamp(delta, absDifference - Math.PI, absDifference) * (difference >= 0.0 ? 1.0 : -1.0); + } + + /// <summary> /// Rounds <paramref name="s"/> to the nearest whole number, /// with halfway cases rounded towards the nearest multiple of two. /// </summary> |