149 lines
5.5 KiB
C#
149 lines
5.5 KiB
C#
using System;
|
|
|
|
namespace Sarand.Net.Standard.Base.Utils
|
|
{
|
|
public static class MathUtil
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// C o m p a r i s o n
|
|
//-------------------------------------------------------------------
|
|
/// <summary>Compare double values within tollerance.</summary>
|
|
public static bool Equals (this double value, double compareValue, double tollerance)
|
|
{
|
|
return (Math.Abs(value - compareValue) <= tollerance);
|
|
}
|
|
/// <summary>Compare float values within tollerance.</summary>
|
|
public static bool Equals (this float value, float compareValue, float tollerance)
|
|
{
|
|
return (Math.Abs(value - compareValue) <= tollerance);
|
|
}
|
|
/// <summary>Compare decimal values within tollerance.</summary>
|
|
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
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Constrain integer value by maximum and minimum values.
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="min"></param>
|
|
/// <param name="max"></param>
|
|
/// <returns></returns>
|
|
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));
|
|
}
|
|
/// <summary>
|
|
/// Constrain decimal value by maximum and minimum values.
|
|
/// </summary>
|
|
/// <param name="value"></param>
|
|
/// <param name="min"></param>
|
|
/// <param name="max"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Test for near zero values (<1e-10).
|
|
/// </summary>
|
|
/// <param name="d"></param>
|
|
/// <returns></returns>
|
|
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));
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/*
|
|
/// <summary>
|
|
/// Offset size by specified distance and angle (anti-clockwise from vertical).
|
|
/// angle = 0: straight up; angle = 90: to left; angle = -90: to right, etc.
|
|
/// </summary>
|
|
/// <param name="distance"></param>
|
|
/// <param name="angleDegrees"></param>
|
|
/// <returns></returns>
|
|
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));
|
|
}
|
|
*/
|
|
|
|
//-------------------------------------------------------------------
|
|
/*
|
|
/// <summary>
|
|
/// Rotate a point about the specified center point by the number of degrees.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
*/
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
}
|