|
|
using System;
|
|
|
using JM.LinqFaster;
|
|
|
namespace isometricparkfna
|
|
|
{
|
|
|
public class EmptyArrayException : Exception {
|
|
|
public EmptyArrayException() {
|
|
|
}
|
|
|
|
|
|
public EmptyArrayException(string message) : base(message) {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
public class MathUtils
|
|
|
{
|
|
|
public MathUtils()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
|
|
|
public static bool Between(float val, float x, float y)
|
|
|
{
|
|
|
return ((x <= val && val < y) || (y <= val && val < x));
|
|
|
|
|
|
}
|
|
|
|
|
|
public static bool Between(int val, int x, int y)
|
|
|
{
|
|
|
return ((x <= val && val < y) || (y <= val && val < x));
|
|
|
|
|
|
}
|
|
|
public static bool BetweenExclusive(float val, float x, float y)
|
|
|
{
|
|
|
return ((x < val && val < y) || (y < val && val < x));
|
|
|
|
|
|
}
|
|
|
|
|
|
public static bool BetweenExclusive(int val, int x, int y)
|
|
|
{
|
|
|
return ((x < val && val < y) || (y < val && val < x));
|
|
|
|
|
|
}
|
|
|
|
|
|
public static bool BetweenInclusive(float val, float x, float y)
|
|
|
{
|
|
|
return ((x <= val && val <= y) || (y <= val && val <= x));
|
|
|
|
|
|
}
|
|
|
|
|
|
public static bool BetweenInclusive(int val, int x, int y)
|
|
|
{
|
|
|
return ((x <= val && val <= y) || (y <= val && val <= x));
|
|
|
|
|
|
}
|
|
|
|
|
|
public static int Clamp(int val, int min, int max)
|
|
|
{
|
|
|
if (val > max)
|
|
|
{
|
|
|
return max;
|
|
|
}
|
|
|
else if (val < min)
|
|
|
{
|
|
|
return min;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return val;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static float Clamp(float val, float min, float max)
|
|
|
{
|
|
|
if (val > max)
|
|
|
{
|
|
|
return max;
|
|
|
}
|
|
|
else if (val < min)
|
|
|
{
|
|
|
return min;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return val;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
protected float Decrement(float value, float delta)
|
|
|
{
|
|
|
float magnitude = Math.Abs(value);
|
|
|
|
|
|
//If distance from zero is less than our delta,
|
|
|
//go to zero to prevent overshooting:
|
|
|
if (magnitude < delta)
|
|
|
{
|
|
|
return 0.0f;
|
|
|
}
|
|
|
else if (value > 0)
|
|
|
{
|
|
|
return value - delta;
|
|
|
}
|
|
|
else if (value < 0)
|
|
|
{
|
|
|
return value + delta;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return 0.0f;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public static System.Collections.Generic.IEnumerable<Double> NextNormalEnumerator(Random random, float mean, float variation)
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
{
|
|
|
double u1 = random.NextDouble();
|
|
|
double u2 = random.NextDouble();
|
|
|
|
|
|
double z1 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Cos(2 * Math.PI * u2);
|
|
|
double z2 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Sin(2 * Math.PI * u2);
|
|
|
|
|
|
yield return (variation * z1) + mean;
|
|
|
yield return (variation * z2) + mean;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static Double NextNormal(Random random, float mean, float variation)
|
|
|
{
|
|
|
//Uses Box-Muller to scale the default uniform distribution
|
|
|
double u1 = random.NextDouble();
|
|
|
double u2 = random.NextDouble();
|
|
|
|
|
|
double z1 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Cos(2 * Math.PI * u2);
|
|
|
double z2 = Math.Sqrt(-2 * Math.Log(u1)) * Math.Sin(2 * Math.PI * u2);
|
|
|
|
|
|
if (random.NextDouble() > 0.5d)
|
|
|
{
|
|
|
return (variation * z1) + mean;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return (variation * z2) + mean;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public static int NextSample(Random random, int[] integers)
|
|
|
{
|
|
|
int index = random.Next(0, integers.Length);
|
|
|
|
|
|
return integers[index];
|
|
|
}
|
|
|
|
|
|
public static float Percentile(float[] floats, float percentile) {
|
|
|
if (floats.Length > 0) {
|
|
|
// Array.Sort(floats);
|
|
|
var raw_position = (floats.Length-1) * percentile;
|
|
|
|
|
|
var lower_position = (int)raw_position;
|
|
|
var higher_position = Math.Min((int)(raw_position+1), floats.Length-1);
|
|
|
|
|
|
var remainder = (raw_position % 1);
|
|
|
|
|
|
return (floats[lower_position] * (1-remainder)) + (floats[higher_position] * remainder);
|
|
|
}
|
|
|
else {
|
|
|
throw new EmptyArrayException("Array must not be empty");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static double Percentile(double[] doubles, double percentile) {
|
|
|
if (doubles.Length > 0) {
|
|
|
Array.Sort(doubles);
|
|
|
var raw_position = (doubles.Length-1) * percentile;
|
|
|
|
|
|
var lower_position = (int)raw_position;
|
|
|
var higher_position = Math.Min((int)raw_position + 1, doubles.Length -1);
|
|
|
|
|
|
var remainder = (raw_position % 1);
|
|
|
|
|
|
return (doubles[lower_position] * (1-remainder)) + (doubles[higher_position] * remainder);
|
|
|
}
|
|
|
else {
|
|
|
throw new EmptyArrayException("Array must not be empty");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static float SymmetricLog10(float num) {
|
|
|
return num > 0.0f ? (float)Math.Log10(num) : -(float)Math.Log10(-num);
|
|
|
}
|
|
|
|
|
|
public static double SymmetricLog10(double num) {
|
|
|
return num > 0.0f ? Math.Log10(num) : -Math.Log10(-num);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|