// ReSharper disable All // using System; using System.Diagnostics; using System.Runtime.CompilerServices; namespace WPFDark.Internals { internal static class NumberHelper { private const float EPSILON_float = 1.192092896e-07F; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float DistanceSq(in this ValueTuple pos) { var w = pos.Item1.X - pos.Item2.X; var h = pos.Item1.Y - pos.Item2.Y; return w * w + h * h; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool AreClose(float value1, float value2) { if (value1 == value2) return true; var eps = (Math.Abs(value1) + Math.Abs(value2) + 10f) * EPSILON_float; var delta = value1 - value2; return (-eps < delta) && (eps > delta); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool AreCloseZero(float value1) { if (value1 == 0f) return true; var eps = (Math.Abs(value1) + 10f) * EPSILON_float; var delta = value1; return (-eps < delta) && (eps > delta); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Clamp01(float value) { if (value <= 0f) return 0f; if (value >= 1f) return 1f; return value; } /// /// value, min, max /// [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Clamp(in this ValueTuple value) { Debug.Assert(value.Item2 <= value.Item3); if (value.Item1 < value.Item2) return value.Item2; if (value.Item1 > value.Item3) return value.Item3; return value.Item1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static (float Min, float Max) MinMax(in this ValueTuple value) => value.Item1 < value.Item2 ? (value.Item1, value.Item2) : (value.Item2, value.Item1); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Max(in this ValueTuple value) => value.Item1 > value.Item2 ? value.Item1 : value.Item2; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Min(in this ValueTuple value) => value.Item1 < value.Item2 ? value.Item1 : value.Item2; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Max(in this ValueTuple value) => ((value.Item1, value.Item2).Max(), value.Item3).Max(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Min(in this ValueTuple value) => ((value.Item1, value.Item2).Min(), value.Item3).Min(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Max(in this ValueTuple value) => (((value.Item1, value.Item2).Max(), value.Item3).Max(), value.Item4).Max(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float Min(in this ValueTuple value) => (((value.Item1, value.Item2).Min(), value.Item3).Min(), value.Item4).Min(); private const double EPSILON_double = 2.2204460492503131e-016; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double DistanceSq(in this ValueTuple pos) { var w = pos.Item1.X - pos.Item2.X; var h = pos.Item1.Y - pos.Item2.Y; return w * w + h * h; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool AreClose(double value1, double value2) { if (value1 == value2) return true; var eps = (Math.Abs(value1) + Math.Abs(value2) + 10d) * EPSILON_double; var delta = value1 - value2; return (-eps < delta) && (eps > delta); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool AreCloseZero(double value1) { if (value1 == 0d) return true; var eps = (Math.Abs(value1) + 10d) * EPSILON_double; var delta = value1; return (-eps < delta) && (eps > delta); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Clamp01(double value) { if (value <= 0d) return 0d; if (value >= 1d) return 1d; return value; } /// /// value, min, max /// [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Clamp(in this ValueTuple value) { Debug.Assert(value.Item2 <= value.Item3); if (value.Item1 < value.Item2) return value.Item2; if (value.Item1 > value.Item3) return value.Item3; return value.Item1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static (double Min, double Max) MinMax(in this ValueTuple value) => value.Item1 < value.Item2 ? (value.Item1, value.Item2) : (value.Item2, value.Item1); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Max(in this ValueTuple value) => value.Item1 > value.Item2 ? value.Item1 : value.Item2; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Min(in this ValueTuple value) => value.Item1 < value.Item2 ? value.Item1 : value.Item2; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Max(in this ValueTuple value) => ((value.Item1, value.Item2).Max(), value.Item3).Max(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Min(in this ValueTuple value) => ((value.Item1, value.Item2).Min(), value.Item3).Min(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Max(in this ValueTuple value) => (((value.Item1, value.Item2).Max(), value.Item3).Max(), value.Item4).Max(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Min(in this ValueTuple value) => (((value.Item1, value.Item2).Min(), value.Item3).Min(), value.Item4).Min(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Clamp01(int value) { if (value <= 0) return 0; if (value >= 1) return 1; return value; } /// /// value, min, max /// [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Clamp(in this ValueTuple value) { Debug.Assert(value.Item2 <= value.Item3); if (value.Item1 < value.Item2) return value.Item2; if (value.Item1 > value.Item3) return value.Item3; return value.Item1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static (int Min, int Max) MinMax(in this ValueTuple value) => value.Item1 < value.Item2 ? (value.Item1, value.Item2) : (value.Item2, value.Item1); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Max(in this ValueTuple value) => value.Item1 > value.Item2 ? value.Item1 : value.Item2; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Min(in this ValueTuple value) => value.Item1 < value.Item2 ? value.Item1 : value.Item2; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Max(in this ValueTuple value) => ((value.Item1, value.Item2).Max(), value.Item3).Max(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Min(in this ValueTuple value) => ((value.Item1, value.Item2).Min(), value.Item3).Min(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Max(in this ValueTuple value) => (((value.Item1, value.Item2).Max(), value.Item3).Max(), value.Item4).Max(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int Min(in this ValueTuple value) => (((value.Item1, value.Item2).Min(), value.Item3).Min(), value.Item4).Min(); } }