Add MathUtility.InverseLerp (#60)

This commit is contained in:
Oliver Booth 2022-05-23 10:33:52 +01:00
parent 683e02cc2a
commit 7ca206721b
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
3 changed files with 95 additions and 0 deletions

View File

@ -2,6 +2,7 @@
## 3.2.0
### Added
- X10D: Added `MathUtility.InverseLerp(float, float, float)` and `MathUtility.InverseLerp(double, double, double)`
- X10D: Added `RoundUpToPowerOf2()` for built-in integer types
- X10D: Added `Vector2.Deconstruct()`
- X10D: Added `Vector3.Deconstruct()`

View File

@ -0,0 +1,46 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using X10D.Core;
using X10D.Math;
namespace X10D.Tests.Math;
[TestClass]
public class MathUtilityTests
{
[TestMethod]
public void InverseLerp_ShouldReturn0_5_Given0_5_0_1()
{
double doubleResult = MathUtility.InverseLerp(0.5, 0.0, 1.0);
float floatResult = MathUtility.InverseLerp(0.5f, 0f, 1f);
Assert.AreEqual(0.5, doubleResult, 1e-6);
Assert.AreEqual(0.5f, floatResult, 1e-6f);
}
[TestMethod]
public void InverseLerp_ShouldReturn0_5_Given5_0_10()
{
double doubleResult = MathUtility.InverseLerp(5.0, 0.0, 10.0);
float floatResult = MathUtility.InverseLerp(5f, 0f, 10f);
Assert.AreEqual(0.5, doubleResult, 1e-6);
Assert.AreEqual(0.5f, floatResult, 1e-6f);
}
[TestMethod]
public void InverseLerp_ShouldReturn0_GivenTwoEqualValues()
{
var random = new Random();
double doubleA = random.NextDouble();
double doubleB = random.NextDouble();
float floatA = random.NextSingle();
float floatB = random.NextSingle();
double doubleResult = MathUtility.InverseLerp(doubleA, doubleB, doubleB);
float floatResult = MathUtility.InverseLerp(floatA, floatB, floatB);
Assert.AreEqual(0.0, doubleResult, 1e-6);
Assert.AreEqual(0.0f, floatResult, 1e-6f);
}
}

View File

@ -8,6 +8,54 @@ namespace X10D.Math;
/// </summary>
public static class MathUtility
{
/// <summary>
/// Returns the linear interpolation inverse of a value, such that it determines where a value lies between two other
/// values.
/// </summary>
/// <param name="alpha">The value whose lerp inverse is to be found.</param>
/// <param name="start">The start of the range.</param>
/// <param name="end">The end of the range.</param>
/// <returns>A value determined by <c>(alpha - start) / (end - start)</c>.</returns>
[Pure]
#if NETSTANDARD2_1
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
#endif
public static float InverseLerp(float alpha, float start, float end)
{
if (MathF.Abs(start - end) < float.Epsilon)
{
return 0f;
}
return (alpha - start) / (end - start);
}
/// <summary>
/// Returns the linear interpolation inverse of a value, such that it determines where a value lies between two other
/// values.
/// </summary>
/// <param name="alpha">The value whose lerp inverse is to be found.</param>
/// <param name="start">The start of the range.</param>
/// <param name="end">The end of the range.</param>
/// <returns>A value determined by <c>(alpha - start) / (end - start)</c>.</returns>
[Pure]
#if NETSTANDARD2_1
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#else
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
#endif
public static double InverseLerp(double alpha, double start, double end)
{
if (System.Math.Abs(start - end) < double.Epsilon)
{
return 0.0;
}
return (alpha - start) / (end - start);
}
/// <summary>
/// Linearly interpolates from one value to a target using a specified alpha.
/// </summary>