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); } */ //------------------------------------------------------------------- } }