using System;
using System.Runtime.CompilerServices;
namespace RGB.NET.Core
{
///
/// Offers some extensions and helper-methods for the work with doubles
///
public static class DoubleExtensions
{
#region Constants
///
/// Defines the precision RGB.NET processes floating point comparisons in.
///
public const double TOLERANCE = 1E-10;
#endregion
#region Methods
///
/// Checks if two values are equal respecting the .
///
/// The first value to compare.
/// The first value to compare.
/// true if the difference is smaller than the ; otherwise, false.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool EqualsInTolerance(this double value1, double value2) => Math.Abs(value1 - value2) < TOLERANCE;
///
/// Clamps the provided value to be bigger or equal min and smaller or equal max.
///
/// The value to clamp.
/// The lower value of the range the value is clamped to.
/// The higher value of the range the value is clamped to.
/// The clamped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Clamp(this double value, double min, double max) => Math.Max(min, Math.Min(max, value));
///
/// Clamps the provided value to be bigger or equal min and smaller or equal max.
///
/// The value to clamp.
/// The lower value of the range the value is clamped to.
/// The higher value of the range the value is clamped to.
/// The clamped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Clamp(this int value, int min, int max) => Math.Max(min, Math.Min(max, value));
///
/// Enforces the provided value to be in the specified range by wrapping it around the edges if it exceeds them.
///
/// The value to wrap.
/// The lower value of the range the value is wrapped into.
/// The higher value of the range the value is wrapped into.
/// The wrapped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Wrap(this double value, double min, double max)
{
double range = max - min;
while (value > max)
value -= range;
while (value < min)
value += range;
return value;
}
#region Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static byte GetByteValueFromPercentage(this double percentage)
{
if (double.IsNaN(percentage)) return 0;
percentage = percentage.Clamp(0, 1.0);
return (byte)(percentage.Equals(1.0) ? 255 : percentage * 256.0);
}
#endregion
#endregion
}
}