using System; using UnityEngine; namespace Assets.AR { public static class PFMath { public const double Deg2Rad = 0.017453292519943295; public const double Rad2Deg = 57.295779513082323; public static int Clamp(int value, int min, int max) { if (value < min) return min; return value <= max ? value : max; } public static double Clamp(double value, double min, double max) { if (value < min) return min; return value <= max ? value : max; } public static float Clamp(float value, float min, float max) { if ((double)value < (double)min) return min; return (double)value <= (double)max ? value : max; } public static float Clamp01(float value) => PFMath.Clamp(value, 0.0f, 1f); public static double Clamp01(double value) => PFMath.Clamp(value, 0.0, 1.0); public static bool InBounds(double value, double min, double max) => min <= value && value <= max; public static bool InBounds(int value, int min, int max) => min <= value && value <= max; public static double Lerp(double x1, double y1, double x2, double y2, double x) { var t = x1 != x2 ? PFMath.InverseLerp(x1, x2, x) : 0.5; return PFMath.Lerp(y1, y2, t); } public static float Lerp(float x1, float y1, float x2, float y2, float x) { var t = (double)x1 != (double)x2 ? PFMath.InverseLerp(x1, x2, x) : 0.5f; return PFMath.Lerp(y1, y2, t); } public static double Lerp(double a, double b, double t) => (1.0 - t) * a + t * b; public static float Lerp(float a, float b, float t) => (float)((1.0 - (double)t) * (double)a + (double)t * (double)b); public static double InverseLerp(double a, double b, double value) => a != b ? (value - a) / (b - a) : 0.0; public static float InverseLerp(float a, float b, float value) => (double)a != (double)b ? (float)(((double)value - (double)a) / ((double)b - (double)a)) : 0.0f; public static double SmoothStep(double x) => x * x * (3.0 - 2.0 * x); public static float SmoothStep(float x) => (float)((double)x * (double)x * (3.0 - 2.0 * (double)x)); public static double SmoothStep(double a, double b, double t) => PFMath.Lerp(a, b, PFMath.SmoothStep(t)); public static float SmoothStep(float a, float b, float t) => PFMath.Lerp(a, b, PFMath.SmoothStep(t)); public static double SmoothStep(double x1, double y1, double x2, double y2, double x) { var t = x1 != x2 ? PFMath.InverseLerp(x1, x2, x) : 0.5; return PFMath.SmoothStep(y1, y2, t); } public static float SmoothStep(float x1, float y1, float x2, float y2, float x) { var t = (double)x1 != (double)x2 ? PFMath.InverseLerp(x1, x2, x) : 0.5f; return PFMath.SmoothStep(y1, y2, t); } public static double InverseSmoothStep(double a, double b, double value) => PFMath.InverseSmoothStep(PFMath.InverseLerp(a, b, value)); public static double InverseSmoothStep(double x) { x = 1.0 - 2.0 * x; return 0.5 - Math.Sin(Math.Asin(x) / 3.0); } public static double SmoothStepDerivative(double x) => 6.0 * x * (1.0 - x); public static double SmoothStepDerivative(double a, double b, double t) => 6.0 * t * (b - a) * (1.0 - t); public static double Round(double value, double step) => step * Math.Round(value / step); public static float Round(float value, float step) => step * Mathf.Round(value / step); public static double Floor(double value, double step) => step * Math.Floor(value / step); public static float Floor(float value, float step) => step * Mathf.Floor(value / step); public static double Ceil(double value, double step) => step * Math.Ceiling(value / step); public static float Ceil(float value, float step) => step * Mathf.Ceil(value / step); public static double DistancePointToLineSegment( Vector3d point, Vector3d lineStart, Vector3d lineEnd) { return Vector3d.Magnitude(PFMath.ProjectPointToLineSegment(point, lineStart, lineEnd) - point); } public static Vector3d ProjectPointToLineSegment( Vector3d point, Vector3d lineStart, Vector3d lineEnd) { var lineParameter = PFMath.ProjectPointToLineParameter(point, lineStart, lineEnd); return Vector3d.LerpClamped(lineStart, lineEnd, lineParameter); } public static double ProjectPointToLineParameter( Vector3d point, Vector3d lineStart, Vector3d lineEnd) { var rhs = point - lineStart; var vector3d = lineEnd - lineStart; return Vector3d.Dot(vector3d, rhs) / Vector3d.SqrMagnitude(vector3d); } } }