You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

600 lines
20 KiB

using System;
namespace UnityEngine
{
public static class Mathf
{
public const float Epsilon = 0.00001F;
/// <summary>
/// <para>Returns the sine of angle f.</para>
/// </summary>
/// <param name="f">The input angle, in radians.</param>
/// <returns>
/// <para>The return value between -1 and +1.</para>
/// </returns>
public static float Sin(float f)
{
return (float) Math.Sin((double) f);
}
/// <summary>
/// <para>Returns the cosine of angle f.</para>
/// </summary>
/// <param name="f">The input angle, in radians.</param>
/// <returns>
/// <para>The return value between -1 and 1.</para>
/// </returns>
public static float Cos(float f)
{
return (float) Math.Cos((double) f);
}
/// <summary>
/// <para>Returns the tangent of angle f in radians.</para>
/// </summary>
/// <param name="f"></param>
public static float Tan(float f)
{
return (float) Math.Tan((double) f);
}
/// <summary>
/// <para>Returns the arc-sine of f - the angle in radians whose sine is f.</para>
/// </summary>
/// <param name="f"></param>
public static float Asin(float f)
{
return (float) Math.Asin((double) f);
}
/// <summary>
/// <para>Returns the arc-cosine of f - the angle in radians whose cosine is f.</para>
/// </summary>
/// <param name="f"></param>
public static float Acos(float f)
{
return (float) Math.Acos((double) f);
}
/// <summary>
/// <para>Returns the arc-tangent of f - the angle in radians whose tangent is f.</para>
/// </summary>
/// <param name="f"></param>
public static float Atan(float f)
{
return (float) Math.Atan((double) f);
}
/// <summary>
/// <para>Returns the angle in radians whose Tan is y/x.</para>
/// </summary>
/// <param name="y"></param>
/// <param name="x"></param>
public static float Atan2(float y, float x)
{
return (float) Math.Atan2((double) y, (double) x);
}
/// <summary>
/// <para>Returns square root of f.</para>
/// </summary>
/// <param name="f"></param>
public static float Sqrt(float f)
{
return (float) Math.Sqrt((double) f);
}
/// <summary>
/// <para>Returns the absolute value of f.</para>
/// </summary>
/// <param name="f"></param>
public static float Abs(float f)
{
return Math.Abs(f);
}
/// <summary>
/// <para>Returns the absolute value of value.</para>
/// </summary>
/// <param name="value"></param>
public static int Abs(int value)
{
return Math.Abs(value);
}
/// <summary>
/// <para>Returns the smallest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static float Min(float a, float b)
{
return (double) a >= (double) b? b : a;
}
/// <summary>
/// <para>Returns the smallest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static float Min(params float[] values)
{
int length = values.Length;
if (length == 0)
return 0.0f;
float num = values[0];
for (int index = 1; index < length; ++index)
{
if ((double) values[index] < (double) num)
num = values[index];
}
return num;
}
/// <summary>
/// <para>Returns the smallest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static int Min(int a, int b)
{
return a >= b? b : a;
}
/// <summary>
/// <para>Returns the smallest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static int Min(params int[] values)
{
int length = values.Length;
if (length == 0)
return 0;
int num = values[0];
for (int index = 1; index < length; ++index)
{
if (values[index] < num)
num = values[index];
}
return num;
}
/// <summary>
/// <para>Returns largest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static float Max(float a, float b)
{
return (double) a <= (double) b? b : a;
}
/// <summary>
/// <para>Returns largest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static float Max(params float[] values)
{
int length = values.Length;
if (length == 0)
return 0.0f;
float num = values[0];
for (int index = 1; index < length; ++index)
{
if ((double) values[index] > (double) num)
num = values[index];
}
return num;
}
/// <summary>
/// <para>Returns the largest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static int Max(int a, int b)
{
return a <= b? b : a;
}
/// <summary>
/// <para>Returns the largest of two or more values.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="values"></param>
public static int Max(params int[] values)
{
int length = values.Length;
if (length == 0)
return 0;
int num = values[0];
for (int index = 1; index < length; ++index)
{
if (values[index] > num)
num = values[index];
}
return num;
}
/// <summary>
/// <para>Returns f raised to power p.</para>
/// </summary>
/// <param name="f"></param>
/// <param name="p"></param>
public static float Pow(float f, float p)
{
return (float) Math.Pow((double) f, (double) p);
}
/// <summary>
/// <para>Returns e raised to the specified power.</para>
/// </summary>
/// <param name="power"></param>
public static float Exp(float power)
{
return (float) Math.Exp((double) power);
}
/// <summary>
/// <para>Returns the logarithm of a specified number in a specified base.</para>
/// </summary>
/// <param name="f"></param>
/// <param name="p"></param>
public static float Log(float f, float p)
{
return (float) Math.Log((double) f, (double) p);
}
/// <summary>
/// <para>Returns the natural (base e) logarithm of a specified number.</para>
/// </summary>
/// <param name="f"></param>
public static float Log(float f)
{
return (float) Math.Log((double) f);
}
/// <summary>
/// <para>Returns the base 10 logarithm of a specified number.</para>
/// </summary>
/// <param name="f"></param>
public static float Log10(float f)
{
return (float) Math.Log10((double) f);
}
/// <summary>
/// <para>Returns the smallest integer greater to or equal to f.</para>
/// </summary>
/// <param name="f"></param>
public static float Ceil(float f)
{
return (float) Math.Ceiling((double) f);
}
/// <summary>
/// <para>Returns the largest integer smaller to or equal to f.</para>
/// </summary>
/// <param name="f"></param>
public static float Floor(float f)
{
return (float) Math.Floor((double) f);
}
/// <summary>
/// <para>Returns f rounded to the nearest integer.</para>
/// </summary>
/// <param name="f"></param>
public static float Round(float f)
{
return (float) Math.Round((double) f);
}
/// <summary>
/// <para>Returns the smallest integer greater to or equal to f.</para>
/// </summary>
/// <param name="f"></param>
public static int CeilToInt(float f)
{
return (int) Math.Ceiling((double) f);
}
/// <summary>
/// <para>Returns the largest integer smaller to or equal to f.</para>
/// </summary>
/// <param name="f"></param>
public static int FloorToInt(float f)
{
return (int) Math.Floor((double) f);
}
/// <summary>
/// <para>Returns f rounded to the nearest integer.</para>
/// </summary>
/// <param name="f"></param>
public static int RoundToInt(float f)
{
return (int) Math.Round((double) f);
}
/// <summary>
/// <para>Returns the sign of f.</para>
/// </summary>
/// <param name="f"></param>
public static float Sign(float f)
{
return (double) f < 0.0? -1f : 1f;
}
/// <summary>
/// <para>Clamps a value between a minimum float and maximum float value.</para>
/// </summary>
/// <param name="value"></param>
/// <param name="min"></param>
/// <param name="max"></param>
public static float Clamp(float value, float min, float max)
{
if ((double) value < (double) min)
value = min;
else if ((double) value > (double) max)
value = max;
return value;
}
/// <summary>
/// <para>Clamps value between min and max and returns value.</para>
/// </summary>
/// <param name="value"></param>
/// <param name="min"></param>
/// <param name="max"></param>
public static int Clamp(int value, int min, int max)
{
if (value < min)
value = min;
else if (value > max)
value = max;
return value;
}
/// <summary>
/// <para>Clamps value between 0 and 1 and returns value.</para>
/// </summary>
/// <param name="value"></param>
public static float Clamp01(float value)
{
if ((double) value < 0.0)
return 0.0f;
if ((double) value > 1.0)
return 1f;
return value;
}
/// <summary>
/// <para>Linearly interpolates between a and b by t.</para>
/// </summary>
/// <param name="a">The start value.</param>
/// <param name="b">The end value.</param>
/// <param name="t">The interpolation value between the two floats.</param>
/// <returns>
/// <para>The interpolated float result between the two float values.</para>
/// </returns>
public static float Lerp(float a, float b, float t)
{
return a + (b - a) * Mathf.Clamp01(t);
}
/// <summary>
/// <para>Linearly interpolates between a and b by t with no limit to t.</para>
/// </summary>
/// <param name="a">The start value.</param>
/// <param name="b">The end value.</param>
/// <param name="t">The interpolation between the two floats.</param>
/// <returns>
/// <para>The float value as a result from the linear interpolation.</para>
/// </returns>
public static float LerpUnclamped(float a, float b, float t)
{
return a + (b - a) * t;
}
/// <summary>
/// <para>Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="t"></param>
public static float LerpAngle(float a, float b, float t)
{
float num = Mathf.Repeat(b - a, 360f);
if ((double) num > 180.0)
num -= 360f;
return a + num * Mathf.Clamp01(t);
}
/// <summary>
/// <para>Moves a value current towards target.</para>
/// </summary>
/// <param name="current">The current value.</param>
/// <param name="target">The value to move towards.</param>
/// <param name="maxDelta">The maximum change that should be applied to the value.</param>
public static float MoveTowards(float current, float target, float maxDelta)
{
if ((double) Mathf.Abs(target - current) <= (double) maxDelta)
return target;
return current + Mathf.Sign(target - current) * maxDelta;
}
/// <summary>
/// <para>Same as MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.</para>
/// </summary>
/// <param name="current"></param>
/// <param name="target"></param>
/// <param name="maxDelta"></param>
public static float MoveTowardsAngle(float current, float target, float maxDelta)
{
float num = Mathf.DeltaAngle(current, target);
if (-(double) maxDelta < (double) num && (double) num < (double) maxDelta)
return target;
target = current + num;
return Mathf.MoveTowards(current, target, maxDelta);
}
/// <summary>
/// <para>Interpolates between min and max with smoothing at the limits.</para>
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <param name="t"></param>
public static float SmoothStep(float from, float to, float t)
{
t = Mathf.Clamp01(t);
t = (float) (-2.0 * (double) t * (double) t * (double) t + 3.0 * (double) t * (double) t);
return (float) ((double) to * (double) t + (double) from * (1.0 - (double) t));
}
public static float Gamma(float value, float absmax, float gamma)
{
bool flag = false;
if ((double) value < 0.0)
flag = true;
float num1 = Mathf.Abs(value);
if ((double) num1 > (double) absmax)
return !flag? num1 : -num1;
float num2 = Mathf.Pow(num1 / absmax, gamma) * absmax;
return !flag? num2 : -num2;
}
/// <summary>
/// <para>Loops the value t, so that it is never larger than length and never smaller than 0.</para>
/// </summary>
/// <param name="t"></param>
/// <param name="length"></param>
public static float Repeat(float t, float length)
{
return Mathf.Clamp(t - Mathf.Floor(t / length) * length, 0.0f, length);
}
/// <summary>
/// <para>PingPongs the value t, so that it is never larger than length and never smaller than 0.</para>
/// </summary>
/// <param name="t"></param>
/// <param name="length"></param>
public static float PingPong(float t, float length)
{
t = Mathf.Repeat(t, length * 2f);
return length - Mathf.Abs(t - length);
}
/// <summary>
/// <para>Calculates the linear parameter t that produces the interpolant value within the range [a, b].</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="value"></param>
public static float InverseLerp(float a, float b, float value)
{
if ((double) a != (double) b)
return Mathf.Clamp01((float) (((double) value - (double) a) / ((double) b - (double) a)));
return 0.0f;
}
/// <summary>
/// <para>Calculates the shortest difference between two given angles given in degrees.</para>
/// </summary>
/// <param name="current"></param>
/// <param name="target"></param>
public static float DeltaAngle(float current, float target)
{
float num = Mathf.Repeat(target - current, 360f);
if ((double) num > 180.0)
num -= 360f;
return num;
}
internal static bool LineIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
{
float num1 = p2.x - p1.x;
float num2 = p2.y - p1.y;
float num3 = p4.x - p3.x;
float num4 = p4.y - p3.y;
float num5 = (float) ((double) num1 * (double) num4 - (double) num2 * (double) num3);
if ((double) num5 == 0.0)
return false;
float num6 = p3.x - p1.x;
float num7 = p3.y - p1.y;
float num8 = (float) ((double) num6 * (double) num4 - (double) num7 * (double) num3) / num5;
result = new Vector2(p1.x + num8 * num1, p1.y + num8 * num2);
return true;
}
internal static bool LineSegmentIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
{
float num1 = p2.x - p1.x;
float num2 = p2.y - p1.y;
float num3 = p4.x - p3.x;
float num4 = p4.y - p3.y;
float num5 = (float) ((double) num1 * (double) num4 - (double) num2 * (double) num3);
if ((double) num5 == 0.0)
return false;
float num6 = p3.x - p1.x;
float num7 = p3.y - p1.y;
float num8 = (float) ((double) num6 * (double) num4 - (double) num7 * (double) num3) / num5;
if ((double) num8 < 0.0 || (double) num8 > 1.0)
return false;
float num9 = (float) ((double) num6 * (double) num2 - (double) num7 * (double) num1) / num5;
if ((double) num9 < 0.0 || (double) num9 > 1.0)
return false;
result = new Vector2(p1.x + num8 * num1, p1.y + num8 * num2);
return true;
}
internal static long RandomToLong(System.Random r)
{
byte[] buffer = new byte[8];
r.NextBytes(buffer);
return (long) BitConverter.ToUInt64(buffer, 0) & long.MaxValue;
}
public static Vector3 Rad2Deg(Vector3 radians)
{
return new Vector3(
(float)(radians.x * 180 / System.Math.PI),
(float)(radians.y * 180 / System.Math.PI),
(float)(radians.z * 180 / System.Math.PI));
}
public static Vector3 Deg2Rad(Vector3 degrees)
{
return new Vector3(
(float)(degrees.x * System.Math.PI / 180),
(float)(degrees.y * System.Math.PI / 180),
(float)(degrees.z * System.Math.PI / 180));
}
public const float CosAngle20 = 0.9396926208f;
public const float CompareEpsilon = 0.000001f;
public static bool CompareApproximate(float f0, float f1, float epsilon = CompareEpsilon)
{
return System.Math.Abs(f0 - f1) < epsilon;
}
public static bool CompareApproximate(double f0, double f1, float epsilon = CompareEpsilon)
{
return System.Math.Abs(f0 - f1) < epsilon;
}
}
}