namespace UnityHelpers.Core.Helper { using System; using UnityEngine; public static class WallMath { /** http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/concurrent/ThreadLocalRandom.java#356 BoundedDouble borrowed from Java's ThreadLocalRandom */ public static double BoundedDouble(double max, double value) { return value < max ? value : BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(value) - 1); } public static float BoundedFloat(float max, float value) { return value < max ? value : BitConverter.ToSingle( BitConverter.GetBytes( BitConverter.ToInt32(BitConverter.GetBytes(value), 0) - 1 ), 0 ); } public static float PositiveMod(this float value, float max) { value %= max; value += max; return value % max; } public static double PositiveMod(this double value, double max) { value %= max; value += max; return value % max; } public static int PositiveMod(this int value, int max) { value %= max; value += max; return value % max; } public static long PositiveMod(this long value, long max) { value %= max; value += max; return value % max; } public static int WrappedAdd(this int value, int increment, int max) { WrappedAdd(ref value, increment, max); return value; } public static int WrappedAdd(ref int value, int increment, int max) { value += increment; if (value < max) { return value; } return value %= max; } public static int WrappedIncrement(this int value, int max) { return WrappedAdd(value, 1, max); } public static int WrappedIncrement(ref int value, int max) { return WrappedAdd(ref value, 1, max); } public static T Clamp(this T value, T min, T max) where T : IComparable { if (value.CompareTo(min) < 0) { return min; } return max.CompareTo(value) < 0 ? max : value; } public static Vector2 Clamp(this Rect bounds, Vector2 point) { return Clamp(bounds, ref point); } public static Vector2 Clamp(this Rect bounds, ref Vector2 point) { if (bounds.Contains(point)) { return point; } Vector2 center = bounds.center; Vector2 direction = point - center; if (direction == Vector2.zero) { return center; } float tMax = float.MaxValue; Vector2 min = bounds.min; Vector2 max = bounds.max; if (direction.x != 0) { if (0 < direction.x) { float t2 = (max.x - center.x) / direction.x; tMax = Mathf.Min(tMax, t2); } else { float t1 = (min.x - center.x) / direction.x; tMax = Mathf.Min(tMax, t1); } } if (direction.y != 0) { if (direction.y > 0) { float t2 = (max.y - center.y) / direction.y; tMax = Mathf.Min(tMax, t2); } else { float t1 = (min.y - center.y) / direction.y; tMax = Mathf.Min(tMax, t1); } } tMax = Mathf.Clamp01(tMax); point = center + direction * tMax; point = new Vector2( Mathf.Clamp(point.x, min.x, max.x), Mathf.Clamp(point.y, min.y, max.y) ); return point; } public static bool Approximately(this float lhs, float rhs, float tolerance = 0.045f) { return Mathf.Abs(lhs - rhs) <= tolerance; } } }