using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using UnityEngine; using UnityEngine.Windows; namespace XericLibrary.Runtime.MacroLibrary { /// /// 数学库 /// public static partial class MacroMath { #region 随机 /// /// 获取一个被特定随机数填充的矩阵,这通常是无意义的 /// /// /// public static Matrix4x4 RandomMatrix4(float range) { return new Matrix4x4( RandomVector4(range), RandomVector4(range), RandomVector4(range), RandomVector4(range)); } /// /// 获取一个在指定坐标范围内的随机矢量(矩形范围) /// /// /// public static Vector4 RandomVector4(float range) { var rand = new System.Random(); range *= 100; Func GetNextRand = () => { return rand.Next((int)-range, (int)range) * 0.01f; }; return new Vector4(GetNextRand(), GetNextRand(), GetNextRand(), GetNextRand()); } /// /// 获取一个在指定坐标范围内的随机矢量(矩形范围) /// /// /// public static Vector3 RandomVector3(float range) { var rand = new System.Random(); range *= 100; Func GetNextRand = () => { return rand.Next((int)-range, (int)range) * 0.01f; }; return new Vector3(GetNextRand(), GetNextRand(), GetNextRand()); } /// /// 获取一个在指定坐标范围内的随机矢量(矩形范围) /// /// /// public static Vector2 RandomVector2(float range) { var rand = new System.Random(); range *= 100; Func GetNextRand = () => { return rand.Next((int)-range, (int)range) * 0.01f; }; return new Vector2(GetNextRand(), GetNextRand()); } /// /// 哈希后处理 /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong MurmurFinalize(ulong index) { index ^= index >> 33; index *= 0xff51afd7ed558ccd; index ^= index >> 33; index *= 0xc4ceb9fe1a85ec53; index ^= index >> 33; return index; } /// /// 大范围随机 /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong RandomNumber(ulong index) { index *= 1103515245; index += 12345; index *= 6364136223846793005UL; index += 1442695040888963407UL; index %= 18446744073709551615UL; return index; } #endregion #region 数学 /// /// pmod /// /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int PMod(int a, int b) { if(b <= 0) return 0; var mod = a % b; return a < 0 ? (b + mod) % b : mod; } /// /// pmod /// /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double PMod(double a, double b) { double z = a % b; double w = (z < 0) ? -1 : 1; z = (z < 0) ? -z : z; if(w < 0) return b - z; else return z; } /// /// 获取两者的最小值,但不包括负数; /// /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float MinPositive(float a, float b) => Math.Min(Math.Max(0, a), Math.Max(0, b)); /// /// 获取两者的最小值,但不包括负数; /// /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int MinPositive(int a, int b) => Math.Min(Math.Max(0, a), Math.Max(0, b)); /// /// Interpolates t between a and b to a value between 0 and 1 using a Hermite polynomial. /// /// The first value /// The second value /// The position value /// A smoothed value between 0 and 1 public static float SmoothStep(float a, float b, float t) { t = Mathf.Clamp01((t - a) / (b - a)); return t * t * (3f - 2f * t); } /// /// Interpolates t between a and b to a value between 0 and 1. /// /// The first value /// The second value /// The position value /// Linear value between 0 and 1 public static float LinearStep(float a, float b, float t) { return Mathf.Clamp01((t - a) / (b - a)); } /// /// Wraps a value between min and max. /// /// The value to wrap /// The minimum value /// The maximum value /// public static double Wrap(double value, double min, double max) { double num = max - min; num = ((num < 0.0) ? (0.0 - num) : num); if(value < min) { return value + num * Math.Ceiling(Math.Abs(value / num)); } if(value >= max) { return value - num * Math.Floor(Math.Abs(value / num)); } return value; } /// /// Wraps a value between min and max. /// /// The value to wrap /// The minimum value /// The maximum value /// public static float Wrap(float value, float min, float max) { float num = max - min; num = (((double)num < 0.0) ? (0f - num) : num); if(value < min) { return value + num * (float)Math.Ceiling(Math.Abs(value / num)); } if(value >= max) { return value - num * (float)Math.Floor(Math.Abs(value / num)); } return value; } /// /// Wraps a value between min and max. /// /// The value to wrap /// The minimum value /// The maximum value /// public static int Wrap(int value, int min, int max) { int num = max - min; num = ((num < 0) ? (-num) : num); if(value < min) { return value + num * (Math.Abs(value / num) + 1); } if(value >= max) { return value - num * Math.Abs(value / num); } return value; } /// /// Rounds a number based on a mininum difference. /// /// The value to round /// The min difference /// The rounded value. public static double RoundBasedOnMinimumDifference(double valueToRound, double minDifference) { if(minDifference == 0.0) { return DiscardLeastSignificantDecimal(valueToRound); } return (float)Math.Round(valueToRound, MacroMath.GetNumberOfDecimalsForMinimumDifference(minDifference), MidpointRounding.AwayFromZero); } /// /// Discards the least significant demicals. /// /// The value of insignificant decimals /// Value with significant decimals public static double DiscardLeastSignificantDecimal(double v) { int digits = Math.Max(0, (int)(5.0 - Math.Log10(Math.Abs(v)))); try { return Math.Round(v, digits); } catch(ArgumentOutOfRangeException) { return 0.0; } } /// /// Clamps and wraps an angle between two values. /// /// /// /// /// public static float ClampWrapAngle(float angle, float min, float max) { float num = 360f; float num2 = min; float num3 = max; float num4 = angle; if(num2 < 0f) { num2 = num2 % num + num; } if(num3 < 0f) { num3 = num3 % num + num; } if(num4 < 0f) { num4 = num4 % num + num; } float num5 = (float)(int)(Math.Abs(min - max) / num) * num; num3 += num5; num4 += num5; if(min > max) { num3 += num; } if(num4 < num2) { num4 = num2; } if(num4 > num3) { num4 = num3; } return num4; } /// /// 获取最小差值的小数个数 /// /// /// public static int GetNumberOfDecimalsForMinimumDifference(double minDifference) { return Mathf.Clamp(-Mathf.FloorToInt(Mathf.Log10(Mathf.Abs((float)minDifference))), 0, 15); } #endregion #region 字节控制 /// /// 设置字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetByteState(ref int target, int site, bool state) { if(state) target |= 1 << site; else target &= 0xff - (1 << site); } /// /// 设置字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SetByteState(ref int target, Enum site, bool state) { SetByteState(ref target, Convert.ToInt32(site), state); } /// /// 检查字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GetByteState(int target, int site) { return (target >> site & 0x01) > 0; } /// /// 检查字 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GetByteState(int target, Enum site) { return GetByteState(target, Convert.ToInt32(site)); } #endregion #region 填充 /// /// 获取被从A到B的值填充的列表 /// /// /// /// public static List GetListFormAToB(int a, int b) { var list = new List(); bool way = a > b; var step = way ? -1 : 1; for(int i = a; (!way && i <= b) || (way && i >= b); i += step) list.Add(i); return list; } #endregion } }