using System;
namespace Sarand.Net.Standard.Base.Utils
{
public static class MathUtil
{
//-------------------------------------------------------------------
// C o m p a r i s o n
//-------------------------------------------------------------------
/// Compare double values within tollerance.
public static bool Equals (this double value, double compareValue, double tollerance)
{
return (Math.Abs(value - compareValue) <= tollerance);
}
/// Compare float values within tollerance.
public static bool Equals (this float value, float compareValue, float tollerance)
{
return (Math.Abs(value - compareValue) <= tollerance);
}
/// Compare decimal values within tollerance.
public static bool Equals (this decimal value, decimal compareValue, decimal tollerance)
{
return (Math.Abs(value - compareValue) <= tollerance);
}
//-------------------------------------------------------------------
// C o n s t r a i n
//-------------------------------------------------------------------
///
/// Constrain integer value by maximum and minimum values.
///
///
///
///
///
public static int Constrain (this int value, int min, int max)
{
// Ref. Math.Clamp() in .Net Core 2.0.
return Math.Min(max, Math.Max(min, value));
}
///
/// Constrain decimal value by maximum and minimum values.
///
///
///
///
///
public static decimal Constrain (this decimal value, decimal min, decimal max)
{
return Math.Min(max, Math.Max(min, value));
}
//-------------------------------------------------------------------
// S o l v e Q u a d r a t i c
//-------------------------------------------------------------------
// Ref. https://en.wikipedia.org/wiki/Quadratic_formula
// ax² + bx + c = 0
// x = (-b ± Sqrt(b²-4ac)) / 2a
// NB c must be <= b² / 4a
public static double SolveQuadratic (double valueA, double valueB, double valueC, bool maxValue = true)
{
double result = 0;
double result1 = (-valueB + Math.Sqrt(Math.Pow(valueB, 2) - (4 * valueA * valueC))) / (2 * valueA);
double result2 = (-valueB - Math.Sqrt(Math.Pow(valueB, 2) - (4 * valueA * valueC))) / (2 * valueA);
if (maxValue)
result = Math.Max(result1, result2);
else result = Math.Min(result1, result2);
return result;
}
//-------------------------------------------------------------------
///
/// Test for near zero values (<1e-10).
///
///
///
public static bool IsZero (this double d, double zeroEpsilon = 1e-10)
{
return Math.Abs(d) < zeroEpsilon;
}
//-------------------------------------------------------------------
// Convert degress to radians.
public static double DegreesToRadians (double degrees)
{
return (Math.PI / 180) * AdjustDegrees(degrees);
}
// Convert radians to degrees.
public static double RadiansToDegrees (double radians)
{
return AdjustDegrees((180 / Math.PI) * radians);
}
public static double AdjustDegrees (double degrees)
{
while (degrees < 0.0) degrees += 360.0;
while (degrees >= 360.0) degrees -= 360.0;
return degrees;
}
//-------------------------------------------------------------------
// Calculate hypotenuse lenfth from the other two sides.
public static double GetHypotenuseLength (double side1, double side2)
{
return Math.Sqrt(Math.Pow(side1, 2.0) + Math.Pow(side2, 2.0));
}
//-------------------------------------------------------------------
/*
///
/// Offset size by specified distance and angle (anti-clockwise from vertical).
/// angle = 0: straight up; angle = 90: to left; angle = -90: to right, etc.
///
///
///
///
public static SizeF GetSizeOffsetByDegrees (float distance, double angleDegrees)
{
double angleRadians = MathUtil.DegreesToRadians(angleDegrees);
return GetSizeOffsetByRadians(distance, angleRadians);
}
public static SizeF GetSizeOffsetByRadians (float distance, double angleRadians)
{
return new SizeF(-Convert.ToSingle(Math.Sin(angleRadians) * distance), Convert.ToSingle(Math.Cos(angleRadians) * distance));
}
*/
//-------------------------------------------------------------------
/*
///
/// Rotate a point about the specified center point by the number of degrees.
///
public static PointF RotatePointDegrees (PointF point, PointF center, double angleDegrees)
{
return RotatePointRadians(point, center, MathUtil.DegreesToRadians(angleDegrees));
}
public static PointF RotatePointRadians (PointF point, PointF center, double angleRadians)
{
double cosTheta = Math.Cos(angleRadians);
double sinTheta = Math.Sin(angleRadians);
float x = Convert.ToSingle(cosTheta * (point.X - center.X) - sinTheta * (point.Y - center.Y) + center.X);
float y = Convert.ToSingle(sinTheta * (point.X - center.X) + cosTheta * (point.Y - center.Y) + center.Y);
return new PointF(x, y);
}
*/
//-------------------------------------------------------------------
}
}