Merge pull request #11 from That-One-Nerd/main

Moving
This commit is contained in:
That_One_Nerd 2022-05-02 13:20:23 -04:00 committed by GitHub
commit c388df3d3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 948 additions and 943 deletions

View File

@ -1,12 +1,14 @@
# Nerd_STF v2.1.1
# Nerd_STF v2.1.2
This update doesn't add any new features, simply a code simplification, using some of the .net 6 tools, such as global usings and file-scoped namespace declarations.
This update just replaces instances of `double` with `float` instead.
I know, this isn't the update you wanted. More stuff coming soon.
```
* Nerd_STF
= Removed unused or unrequired usings in all files.
= Replaced all namespace declarations with file-scoped declarations.
* Miscellaneous
* GlobalUsings
+ global using System.Diagnostics.CodeAnalysis
= Replace all instances of `double` with `float`
* Mathematics
= Renamed `Double2` to `Float2`
= Renamed `Double3` to `Float3`
= Renamed `Double4` to `Float4`
```

View File

@ -24,5 +24,6 @@ public class DifferingVertCountException : Nerd_STFException
ParamName = paramName;
Polygons = polys;
}
protected DifferingVertCountException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}

View File

@ -24,5 +24,6 @@ public class DisconnectedLinesException : Nerd_STFException
ParamName = paramName;
Lines = lines;
}
protected DisconnectedLinesException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}

View File

@ -8,17 +8,17 @@ public struct Angle : ICloneable, IComparable<Angle>, IEquatable<Angle>
public static Angle Quarter => new(90);
public static Angle Zero => new(0);
public double Degrees
public float Degrees
{
get => p_deg;
set => p_deg = value;
}
public double Gradians
public float Gradians
{
get => p_deg * 1.11111111111; // Reciprocal of 9/10 as a constant (10/9)
set => p_deg = value * 0.9;
get => p_deg * 1.11111111111f; // Reciprocal of 9/10 as a constant (10/9)
set => p_deg = value * 0.9f;
}
public double Radians
public float Radians
{
get => p_deg * Mathf.DegToRad;
set => p_deg = value * Mathf.RadToDeg;
@ -26,14 +26,14 @@ public struct Angle : ICloneable, IComparable<Angle>, IEquatable<Angle>
public Angle Bounded => new(p_deg % 360);
private double p_deg;
private float p_deg;
public Angle(double value, Type valueType = Type.Degrees)
public Angle(float value, Type valueType = Type.Degrees)
{
p_deg = valueType switch
{
Type.Degrees => value,
Type.Gradians => value * 0.9,
Type.Gradians => value * 0.9f,
Type.Radians => value * Mathf.RadToDeg,
_ => throw new ArgumentException("Unknown type.", nameof(valueType)),
};
@ -44,15 +44,15 @@ public struct Angle : ICloneable, IComparable<Angle>, IEquatable<Angle>
public static Angle Ceiling(Angle val) => new(Mathf.Ceiling(val.p_deg));
public static Angle Clamp(Angle val, Angle min, Angle max) => new(Mathf.Clamp(val.p_deg, min.p_deg, max.p_deg));
public static Angle Floor(Angle val) => new(Mathf.Ceiling(val.p_deg));
public static Angle Lerp(Angle a, Angle b, double t, bool clamp = true) =>
public static Angle Lerp(Angle a, Angle b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.p_deg, b.p_deg, t, clamp));
public static Angle Max(params Angle[] vals) => new(Mathf.Max(ToDoubles(Type.Degrees, vals)));
public static Angle Median(params Angle[] vals) => new(Mathf.Median(ToDoubles(Type.Degrees, vals)));
public static Angle Min(params Angle[] vals) => new(Mathf.Min(ToDoubles(Type.Degrees, vals)));
public static double[] ToDoubles(Type outputType, params Angle[] vals)
public static float[] ToDoubles(Type outputType, params Angle[] vals)
{
double[] res = new double[vals.Length];
float[] res = new float[vals.Length];
for (int i = 0; i < vals.Length; i++)
{
res[i] = outputType switch
@ -97,9 +97,9 @@ public struct Angle : ICloneable, IComparable<Angle>, IEquatable<Angle>
public static Angle operator -(Angle a) => new(-a.p_deg);
public static Angle operator -(Angle a, Angle b) => new(a.p_deg - b.p_deg);
public static Angle operator *(Angle a, Angle b) => new(a.p_deg * b.p_deg);
public static Angle operator *(Angle a, double b) => new(a.p_deg * b);
public static Angle operator *(Angle a, float b) => new(a.p_deg * b);
public static Angle operator /(Angle a, Angle b) => new(a.p_deg / b.p_deg);
public static Angle operator /(Angle a, double b) => new(a.p_deg / b);
public static Angle operator /(Angle a, float b) => new(a.p_deg / b);
public static bool operator ==(Angle a, Angle b) => a.Equals(b);
public static bool operator !=(Angle a, Angle b) => !a.Equals(b);
public static bool operator >(Angle a, Angle b) => a.CompareTo(b) > 0;

View File

@ -2,32 +2,32 @@
public static class Calculus
{
public const double DefaultStep = 0.001;
public const float DefaultStep = 0.001f;
public static Equation GetDerivative(Equation equ, double min, double max, double step = DefaultStep)
public static Equation GetDerivative(Equation equ, float min, float max, float step = DefaultStep)
{
Dictionary<double, double> vals = new();
for (double x = min; x <= max; x += step)
Dictionary<float, float> vals = new();
for (float x = min; x <= max; x += step)
{
double val1 = equ(x), val2 = equ(x + step), change = (val2 - val1) / step;
float val1 = equ(x), val2 = equ(x + step), change = (val2 - val1) / step;
vals.Add(x, change);
}
return Mathf.MakeEquation(vals);
}
public static double GetDerivativeAtPoint(Equation equ, double x, double step = DefaultStep) =>
public static float GetDerivativeAtPoint(Equation equ, float x, float step = DefaultStep) =>
(equ(x + DefaultStep) - equ(x)) / step;
public static double GetIntegral(Equation equ, double lowerBound, double upperBound, double step = DefaultStep)
public static float GetIntegral(Equation equ, float lowerBound, float upperBound, float step = DefaultStep)
{
double val = 0;
for (double x = lowerBound; x <= upperBound; x += step) val += equ(x) * step;
float val = 0;
for (float x = lowerBound; x <= upperBound; x += step) val += equ(x) * step;
return val;
}
public static double GradientDescent(Equation equ, double initial, double rate, double stepCount = 1000,
double step = DefaultStep)
public static float GradientDescent(Equation equ, float initial, float rate, float stepCount = 1000,
float step = DefaultStep)
{
double val = initial;
float val = initial;
for (int i = 0; i < stepCount; i++) val -= GetDerivativeAtPoint(equ, val, step) * rate;
return val;
}

View File

@ -1,181 +0,0 @@
namespace Nerd_STF.Mathematics;
public struct Double2 : ICloneable, IComparable<Double2>, IEquatable<Double2>, IGroup<double>
{
public static Double2 Down => new(0, -1);
public static Double2 Left => new(-1, 0);
public static Double2 Right => new(1, 0);
public static Double2 Up => new(0, 1);
public static Double2 One => new(1, 1);
public static Double2 Zero => new(0, 0);
public double Magnitude => Mathf.Sqrt(x * x + y * y);
public Double2 Normalized => this / Magnitude;
public double x, y;
public Double2(double all) : this(all, all) { }
public Double2(double x, double y)
{
this.x = x;
this.y = y;
}
public Double2(Fill<double> fill) : this(fill(0), fill(1)) { }
public Double2(Fill<int> fill) : this(fill(0), fill(1)) { }
public double this[int index]
{
get => index switch
{
0 => x,
1 => y,
_ => throw new IndexOutOfRangeException(nameof(index)),
};
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
default: throw new IndexOutOfRangeException(nameof(index));
}
}
}
public static Double2 Absolute(Double2 val) =>
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y));
public static Double2 Average(params Double2[] vals) => Sum(vals) / vals.Length;
public static Double2 Ceiling(Double2 val) =>
new(Mathf.Ceiling(val.x), Mathf.Ceiling(val.y));
public static Double2 Clamp(Double2 val, Double2 min, Double2 max) =>
new(Mathf.Clamp(val.x, min.x, max.x),
Mathf.Clamp(val.y, min.y, max.y));
public static Double2 ClampMagnitude(Double2 val, double minMag, double maxMag)
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
double mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
else if (mag > maxMag) val *= maxMag;
return val;
}
public static Double3 Cross(Double2 a, Double2 b, bool normalized = false) =>
Double3.Cross(a, b, normalized);
public static Double2 Divide(Double2 num, params Double2[] vals)
{
foreach (Double2 d in vals) num /= d;
return num;
}
public static double Dot(Double2 a, Double2 b) => a.x * b.x + a.y * b.y;
public static double Dot(params Double2[] vals)
{
if (vals.Length < 1) return 0;
double x = 1, y = 1;
foreach (Double2 d in vals)
{
x *= d.x;
y *= d.y;
}
return x + y;
}
public static Double2 Floor(Double2 val) =>
new(Mathf.Floor(val.x), Mathf.Floor(val.y));
public static Double2 Lerp(Double2 a, Double2 b, double t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp));
public static Double2 Median(params Double2[] vals)
{
double index = Mathf.Average(0, vals.Length - 1);
Double2 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
return Average(valA, valB);
}
public static Double2 Max(params Double2[] vals)
{
if (vals.Length < 1) return Zero;
Double2 val = vals[0];
foreach (Double2 d in vals) val = d > val ? d : val;
return val;
}
public static Double2 Min(params Double2[] vals)
{
if (vals.Length < 1) return Zero;
Double2 val = vals[0];
foreach (Double2 d in vals) val = d < val ? d : val;
return val;
}
public static Double2 Multiply(params Double2[] vals)
{
if (vals.Length < 1) return Zero;
Double2 val = One;
foreach (Double2 d in vals) val *= d;
return val;
}
public static Double2 Subtract(Double2 num, params Double2[] vals)
{
foreach (Double2 d in vals) num -= d;
return num;
}
public static Double2 Sum(params Double2[] vals)
{
Double2 val = Zero;
foreach (Double2 d in vals) val += d;
return val;
}
public int CompareTo(Double2 other) => Magnitude.CompareTo(other.Magnitude);
public override bool Equals([NotNullWhen(true)] object? obj)
{
if (obj == null || obj.GetType() != typeof(Double2)) return false;
return Equals((Double2)obj);
}
public bool Equals(Double2 other) => x == other.x && y == other.y;
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode();
public override string ToString() => ToString((string?)null);
public string ToString(string? provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider);
public string ToString(IFormatProvider provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider);
public object Clone() => new Double2(x, y);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<double> GetEnumerator()
{
yield return x;
yield return y;
}
public double[] ToArray() => new[] { x, y };
public List<double> ToList() => new() { x, y };
public static Double2 operator +(Double2 a, Double2 b) => new(a.x + b.x, a.y + b.y);
public static Double2 operator -(Double2 d) => new(-d.x, -d.y);
public static Double2 operator -(Double2 a, Double2 b) => new(a.x - b.x, a.y - b.y);
public static Double2 operator *(Double2 a, Double2 b) => new(a.x * b.x, a.y * b.y);
public static Double2 operator *(Double2 a, double b) => new(a.x * b, a.y * b);
public static Double2 operator /(Double2 a, Double2 b) => new(a.x / b.x, a.y / b.y);
public static Double2 operator /(Double2 a, double b) => new(a.x / b, a.y / b);
public static bool operator ==(Double2 a, Double2 b) => a.Equals(b);
public static bool operator !=(Double2 a, Double2 b) => !a.Equals(b);
public static bool operator >(Double2 a, Double2 b) => a.CompareTo(b) > 0;
public static bool operator <(Double2 a, Double2 b) => a.CompareTo(b) < 0;
public static bool operator >=(Double2 a, Double2 b) => a == b || a > b;
public static bool operator <=(Double2 a, Double2 b) => a == b || a < b;
public static explicit operator Double2(Double3 val) => new(val.x, val.y);
public static explicit operator Double2(Double4 val) => new(val.x, val.y);
public static implicit operator Double2(Int2 val) => new(val.x, val.y);
public static explicit operator Double2(Int3 val) => new(val.x, val.y);
public static explicit operator Double2(Int4 val) => new(val.x, val.y);
public static explicit operator Double2(Vert val) => new(val.position.x, val.position.y);
public static implicit operator Double2(Fill<double> fill) => new(fill);
public static implicit operator Double2(Fill<int> fill) => new(fill);
}

View File

@ -1,202 +0,0 @@
namespace Nerd_STF.Mathematics;
public struct Double3 : ICloneable, IComparable<Double3>, IEquatable<Double3>, IGroup<double>
{
public static Double3 Back => new(0, 0, -1);
public static Double3 Down => new(0, -1, 0);
public static Double3 Forward => new(0, 0, 1);
public static Double3 Left => new(-1, 0, 0);
public static Double3 Right => new(1, 0, 0);
public static Double3 Up => new(0, 1, 0);
public static Double3 One => new(1, 1, 1);
public static Double3 Zero => new(0, 0, 0);
public double Magnitude => Mathf.Sqrt(x * x + y * y + z * z);
public Double3 Normalized => this / Magnitude;
public Double2 XY => new(x, y);
public Double2 XZ => new(x, z);
public Double2 YZ => new(y, z);
public double x, y, z;
public Double3(double all) : this(all, all, all) { }
public Double3(double x, double y) : this(x, y, 0) { }
public Double3(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Double3(Fill<double> fill) : this(fill(0), fill(1), fill(2)) { }
public Double3(Fill<int> fill) : this(fill(0), fill(1), fill(2)) { }
public double this[int index]
{
get => index switch
{
0 => x,
1 => y,
2 => z,
_ => throw new IndexOutOfRangeException(nameof(index)),
};
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default: throw new IndexOutOfRangeException(nameof(index));
}
}
}
public static Double3 Absolute(Double3 val) =>
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y), Mathf.Absolute(val.z));
public static Double3 Average(params Double3[] vals) => Sum(vals) / vals.Length;
public static Double3 Ceiling(Double3 val) =>
new(Mathf.Ceiling(val.x), Mathf.Ceiling(val.y), Mathf.Ceiling(val.z));
public static Double3 Clamp(Double3 val, Double3 min, Double3 max) =>
new(Mathf.Clamp(val.x, min.x, max.x),
Mathf.Clamp(val.y, min.y, max.y),
Mathf.Clamp(val.z, min.z, max.z));
public static Double3 ClampMagnitude(Double3 val, double minMag, double maxMag)
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
double mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
else if (mag > maxMag) val *= maxMag;
return val;
}
public static Double3 Cross(Double3 a, Double3 b, bool normalized = false)
{
Double3 val = new(a.y * b.z - b.y * a.z,
b.x * a.z - a.x * b.z,
a.x * b.y - b.x * a.y);
return normalized ? val.Normalized : val;
}
public static Double3 Divide(Double3 num, params Double3[] vals)
{
foreach (Double3 d in vals) num /= d;
return num;
}
public static double Dot(Double3 a, Double3 b) => a.x * b.x + a.y * b.y + a.z * b.z;
public static double Dot(params Double3[] vals)
{
if (vals.Length < 1) return 0;
double x = 1, y = 1, z = 1;
foreach (Double3 d in vals)
{
x *= d.x;
y *= d.y;
z *= d.z;
}
return x + y + z;
}
public static Double3 Floor(Double3 val) =>
new(Mathf.Floor(val.x), Mathf.Floor(val.y), Mathf.Floor(val.z));
public static Double3 Lerp(Double3 a, Double3 b, double t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp));
public static Double3 Median(params Double3[] vals)
{
double index = Mathf.Average(0, vals.Length - 1);
Double3 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
return Average(valA, valB);
}
public static Double3 Max(params Double3[] vals)
{
if (vals.Length < 1) return Zero;
Double3 val = vals[0];
foreach (Double3 d in vals) val = d > val ? d : val;
return val;
}
public static Double3 Min(params Double3[] vals)
{
if (vals.Length < 1) return Zero;
Double3 val = vals[0];
foreach (Double3 d in vals) val = d < val ? d : val;
return val;
}
public static Double3 Multiply(params Double3[] vals)
{
if (vals.Length < 1) return Zero;
Double3 val = One;
foreach (Double3 d in vals) val *= d;
return val;
}
public static Double3 Subtract(Double3 num, params Double3[] vals)
{
foreach (Double3 d in vals) num -= d;
return num;
}
public static Double3 Sum(params Double3[] vals)
{
Double3 val = Zero;
foreach (Double3 d in vals) val += d;
return val;
}
public int CompareTo(Double3 other) => Magnitude.CompareTo(other.Magnitude);
public override bool Equals([NotNullWhen(true)] object? obj)
{
if (obj == null || obj.GetType() != typeof(Double3)) return false;
return Equals((Double3)obj);
}
public bool Equals(Double3 other) => x == other.x && y == other.y && z == other.z;
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
public override string ToString() => ToString((string?)null);
public string ToString(string? provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider);
public string ToString(IFormatProvider provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider);
public object Clone() => new Double3(x, y, z);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<double> GetEnumerator()
{
yield return x;
yield return y;
yield return z;
}
public double[] ToArray() => new[] { x, y, z };
public List<double> ToList() => new() { x, y, z };
public static Double3 operator +(Double3 a, Double3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z);
public static Double3 operator -(Double3 d) => new(-d.x, -d.y, -d.z);
public static Double3 operator -(Double3 a, Double3 b) => new(a.x - b.x, a.y - b.y, a.z - b.z);
public static Double3 operator *(Double3 a, Double3 b) => new(a.x * b.x, a.y * b.y, a.z * b.z);
public static Double3 operator *(Double3 a, double b) => new(a.x * b, a.y * b, a.z * b);
public static Double3 operator /(Double3 a, Double3 b) => new(a.x / b.x, a.y / b.y, a.z / b.z);
public static Double3 operator /(Double3 a, double b) => new(a.x / b, a.y / b, a.z / b);
public static bool operator ==(Double3 a, Double3 b) => a.Equals(b);
public static bool operator !=(Double3 a, Double3 b) => !a.Equals(b);
public static bool operator >(Double3 a, Double3 b) => a.CompareTo(b) > 0;
public static bool operator <(Double3 a, Double3 b) => a.CompareTo(b) < 0;
public static bool operator >=(Double3 a, Double3 b) => a == b || a > b;
public static bool operator <=(Double3 a, Double3 b) => a == b || a < b;
public static implicit operator Double3(Double2 val) => new(val.x, val.y, 0);
public static explicit operator Double3(Double4 val) => new(val.x, val.y, val.z);
public static implicit operator Double3(Int2 val) => new(val.x, val.y, 0);
public static implicit operator Double3(Int3 val) => new(val.x, val.y, val.z);
public static explicit operator Double3(Int4 val) => new(val.x, val.y, val.z);
public static implicit operator Double3(Vert val) => new(val.position.x, val.position.y, val.position.z);
public static implicit operator Double3(Fill<double> fill) => new(fill);
public static implicit operator Double3(Fill<int> fill) => new(fill);
}

View File

@ -1,218 +0,0 @@
namespace Nerd_STF.Mathematics;
public struct Double4 : ICloneable, IComparable<Double4>, IEquatable<Double4>, IGroup<double>
{
public static Double4 Back => new(0, 0, -1, 0);
public static Double4 Deep => new(0, 0, 0, -1);
public static Double4 Down => new(0, -1, 0, 0);
public static Double4 Far => new(0, 0, 0, 1);
public static Double4 Forward => new(0, 0, 1, 0);
public static Double4 Left => new(-1, 0, 0, 0);
public static Double4 Right => new(1, 0, 0, 0);
public static Double4 Up => new(0, 1, 0, 0);
public static Double4 One => new(1, 1, 1, 1);
public static Double4 Zero => new(0, 0, 0, 0);
public double Magnitude => Mathf.Sqrt(x * x + y * y + z * z + w * w);
public Double4 Normalized => this / Magnitude;
public Double2 XY => new(x, y);
public Double2 XZ => new(x, z);
public Double2 XW => new(x, w);
public Double2 YW => new(y, w);
public Double2 YZ => new(y, z);
public Double2 ZW => new(z, w);
public Double3 XYW => new(x, y, w);
public Double3 XYZ => new(x, y, z);
public Double3 YZW => new(y, z, w);
public Double3 XZW => new(x, z, w);
public double x, y, z, w;
public Double4(double all) : this(all, all, all, all) { }
public Double4(double x, double y) : this(x, y, 0, 0) { }
public Double4(double x, double y, double z) : this(x, y, z, 0) { }
public Double4(double x, double y, double z, double w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Double4(Fill<double> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Double4(Fill<int> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public double this[int index]
{
get => index switch
{
0 => x,
1 => y,
2 => z,
3 => w,
_ => throw new IndexOutOfRangeException(nameof(index)),
};
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
case 3:
w = value;
break;
default: throw new IndexOutOfRangeException(nameof(index));
}
}
}
public static Double4 Absolute(Double4 val) =>
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y), Mathf.Absolute(val.z), Mathf.Absolute(val.w));
public static Double4 Average(params Double4[] vals) => Sum(vals) / vals.Length;
public static Double4 Ceiling(Double4 val) =>
new(Mathf.Ceiling(val.x), Mathf.Ceiling(val.y), Mathf.Ceiling(val.z), Mathf.Ceiling(val.w));
public static Double4 Clamp(Double4 val, Double4 min, Double4 max) =>
new(Mathf.Clamp(val.x, min.x, max.x),
Mathf.Clamp(val.y, min.y, max.y),
Mathf.Clamp(val.z, min.z, max.z),
Mathf.Clamp(val.w, min.w, max.w));
public static Double4 ClampMagnitude(Double4 val, double minMag, double maxMag)
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
double mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
else if (mag > maxMag) val *= maxMag;
return val;
}
public static Double4 Divide(Double4 num, params Double4[] vals)
{
foreach (Double4 d in vals) num /= d;
return num;
}
public static double Dot(Double4 a, Double4 b) => a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
public static double Dot(params Double4[] vals)
{
if (vals.Length < 1) return 0;
double x = 1, y = 1, z = 1, w = 1;
foreach (Double4 d in vals)
{
x *= d.x;
y *= d.y;
z *= d.z;
w *= d.w;
}
return x + y + z;
}
public static Double4 Floor(Double4 val) =>
new(Mathf.Floor(val.x), Mathf.Floor(val.y), Mathf.Floor(val.z), Mathf.Floor(val.w));
public static Double4 Lerp(Double4 a, Double4 b, double t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp),
Mathf.Lerp(a.w, b.w, t, clamp));
public static Double4 Median(params Double4[] vals)
{
double index = Mathf.Average(0, vals.Length - 1);
Double4 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
return Average(valA, valB);
}
public static Double4 Max(params Double4[] vals)
{
if (vals.Length < 1) return Zero;
Double4 val = vals[0];
foreach (Double4 d in vals) val = d > val ? d : val;
return val;
}
public static Double4 Min(params Double4[] vals)
{
if (vals.Length < 1) return Zero;
Double4 val = vals[0];
foreach (Double4 d in vals) val = d < val ? d : val;
return val;
}
public static Double4 Multiply(params Double4[] vals)
{
if (vals.Length < 1) return Zero;
Double4 val = One;
foreach (Double4 d in vals) val *= d;
return val;
}
public static Double4 Subtract(Double4 num, params Double4[] vals)
{
foreach (Double4 d in vals) num -= d;
return num;
}
public static Double4 Sum(params Double4[] vals)
{
Double4 val = Zero;
foreach (Double4 d in vals) val += d;
return val;
}
public int CompareTo(Double4 other) => Magnitude.CompareTo(other.Magnitude);
public override bool Equals([NotNullWhen(true)] object? obj)
{
if (obj == null || obj.GetType() != typeof(Double4)) return false;
return Equals((Double4)obj);
}
public bool Equals(Double4 other) => x == other.x && y == other.y && z == other.z && w == other.w;
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
public override string ToString() => ToString((string?)null);
public string ToString(string? provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider)
+ " W: " + w.ToString(provider);
public string ToString(IFormatProvider provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider)
+ " W: " + w.ToString(provider);
public object Clone() => new Double4(x, y, z, w);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<double> GetEnumerator()
{
yield return x;
yield return y;
yield return z;
yield return w;
}
public double[] ToArray() => new[] { x, y, z, w };
public List<double> ToList() => new() { x, y, z, w };
public static Double4 operator +(Double4 a, Double4 b) => new(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
public static Double4 operator -(Double4 d) => new(-d.x, -d.y, -d.z, -d.w);
public static Double4 operator -(Double4 a, Double4 b) => new(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
public static Double4 operator *(Double4 a, Double4 b) => new(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
public static Double4 operator *(Double4 a, double b) => new(a.x * b, a.y * b, a.z * b, a.w * b);
public static Double4 operator /(Double4 a, Double4 b) => new(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
public static Double4 operator /(Double4 a, double b) => new(a.x / b, a.y / b, a.z / b, a.w / b);
public static bool operator ==(Double4 a, Double4 b) => a.Equals(b);
public static bool operator !=(Double4 a, Double4 b) => !a.Equals(b);
public static bool operator >(Double4 a, Double4 b) => a.CompareTo(b) > 0;
public static bool operator <(Double4 a, Double4 b) => a.CompareTo(b) < 0;
public static bool operator >=(Double4 a, Double4 b) => a == b || a > b;
public static bool operator <=(Double4 a, Double4 b) => a == b || a < b;
public static implicit operator Double4(Double2 val) => new(val.x, val.y, 0, 0);
public static implicit operator Double4(Double3 val) => new(val.x, val.y, val.z, 0);
public static implicit operator Double4(Int2 val) => new(val.x, val.y, 0, 0);
public static implicit operator Double4(Int3 val) => new(val.x, val.y, val.z, 0);
public static implicit operator Double4(Int4 val) => new(val.x, val.y, val.z, val.w);
public static implicit operator Double4(Vert val) => new(val.position.x, val.position.y, val.position.z, 0);
public static implicit operator Double4(Fill<double> fill) => new(fill);
public static implicit operator Double4(Fill<int> fill) => new(fill);
}

View File

@ -1,3 +1,3 @@
namespace Nerd_STF.Mathematics;
public delegate double Equation(double x);
public delegate float Equation(float x);

View File

@ -0,0 +1,181 @@
namespace Nerd_STF.Mathematics;
public struct Float2 : ICloneable, IComparable<Float2>, IEquatable<Float2>, IGroup<float>
{
public static Float2 Down => new(0, -1);
public static Float2 Left => new(-1, 0);
public static Float2 Right => new(1, 0);
public static Float2 Up => new(0, 1);
public static Float2 One => new(1, 1);
public static Float2 Zero => new(0, 0);
public float Magnitude => Mathf.Sqrt(x * x + y * y);
public Float2 Normalized => this / Magnitude;
public float x, y;
public Float2(float all) : this(all, all) { }
public Float2(float x, float y)
{
this.x = x;
this.y = y;
}
public Float2(Fill<float> fill) : this(fill(0), fill(1)) { }
public Float2(Fill<int> fill) : this(fill(0), fill(1)) { }
public float this[int index]
{
get => index switch
{
0 => x,
1 => y,
_ => throw new IndexOutOfRangeException(nameof(index)),
};
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
default: throw new IndexOutOfRangeException(nameof(index));
}
}
}
public static Float2 Absolute(Float2 val) =>
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y));
public static Float2 Average(params Float2[] vals) => Sum(vals) / vals.Length;
public static Float2 Ceiling(Float2 val) =>
new(Mathf.Ceiling(val.x), Mathf.Ceiling(val.y));
public static Float2 Clamp(Float2 val, Float2 min, Float2 max) =>
new(Mathf.Clamp(val.x, min.x, max.x),
Mathf.Clamp(val.y, min.y, max.y));
public static Float2 ClampMagnitude(Float2 val, float minMag, float maxMag)
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
float mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
else if (mag > maxMag) val *= maxMag;
return val;
}
public static Float3 Cross(Float2 a, Float2 b, bool normalized = false) =>
Float3.Cross(a, b, normalized);
public static Float2 Divide(Float2 num, params Float2[] vals)
{
foreach (Float2 d in vals) num /= d;
return num;
}
public static float Dot(Float2 a, Float2 b) => a.x * b.x + a.y * b.y;
public static float Dot(params Float2[] vals)
{
if (vals.Length < 1) return 0;
float x = 1, y = 1;
foreach (Float2 d in vals)
{
x *= d.x;
y *= d.y;
}
return x + y;
}
public static Float2 Floor(Float2 val) =>
new(Mathf.Floor(val.x), Mathf.Floor(val.y));
public static Float2 Lerp(Float2 a, Float2 b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp));
public static Float2 Median(params Float2[] vals)
{
float index = Mathf.Average(0, vals.Length - 1);
Float2 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
return Average(valA, valB);
}
public static Float2 Max(params Float2[] vals)
{
if (vals.Length < 1) return Zero;
Float2 val = vals[0];
foreach (Float2 d in vals) val = d > val ? d : val;
return val;
}
public static Float2 Min(params Float2[] vals)
{
if (vals.Length < 1) return Zero;
Float2 val = vals[0];
foreach (Float2 d in vals) val = d < val ? d : val;
return val;
}
public static Float2 Multiply(params Float2[] vals)
{
if (vals.Length < 1) return Zero;
Float2 val = One;
foreach (Float2 d in vals) val *= d;
return val;
}
public static Float2 Subtract(Float2 num, params Float2[] vals)
{
foreach (Float2 d in vals) num -= d;
return num;
}
public static Float2 Sum(params Float2[] vals)
{
Float2 val = Zero;
foreach (Float2 d in vals) val += d;
return val;
}
public int CompareTo(Float2 other) => Magnitude.CompareTo(other.Magnitude);
public override bool Equals([NotNullWhen(true)] object? obj)
{
if (obj == null || obj.GetType() != typeof(Float2)) return false;
return Equals((Float2)obj);
}
public bool Equals(Float2 other) => x == other.x && y == other.y;
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode();
public override string ToString() => ToString((string?)null);
public string ToString(string? provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider);
public string ToString(IFormatProvider provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider);
public object Clone() => new Float2(x, y);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<float> GetEnumerator()
{
yield return x;
yield return y;
}
public float[] ToArray() => new[] { x, y };
public List<float> ToList() => new() { x, y };
public static Float2 operator +(Float2 a, Float2 b) => new(a.x + b.x, a.y + b.y);
public static Float2 operator -(Float2 d) => new(-d.x, -d.y);
public static Float2 operator -(Float2 a, Float2 b) => new(a.x - b.x, a.y - b.y);
public static Float2 operator *(Float2 a, Float2 b) => new(a.x * b.x, a.y * b.y);
public static Float2 operator *(Float2 a, float b) => new(a.x * b, a.y * b);
public static Float2 operator /(Float2 a, Float2 b) => new(a.x / b.x, a.y / b.y);
public static Float2 operator /(Float2 a, float b) => new(a.x / b, a.y / b);
public static bool operator ==(Float2 a, Float2 b) => a.Equals(b);
public static bool operator !=(Float2 a, Float2 b) => !a.Equals(b);
public static bool operator >(Float2 a, Float2 b) => a.CompareTo(b) > 0;
public static bool operator <(Float2 a, Float2 b) => a.CompareTo(b) < 0;
public static bool operator >=(Float2 a, Float2 b) => a == b || a > b;
public static bool operator <=(Float2 a, Float2 b) => a == b || a < b;
public static explicit operator Float2(Float3 val) => new(val.x, val.y);
public static explicit operator Float2(Float4 val) => new(val.x, val.y);
public static implicit operator Float2(Int2 val) => new(val.x, val.y);
public static explicit operator Float2(Int3 val) => new(val.x, val.y);
public static explicit operator Float2(Int4 val) => new(val.x, val.y);
public static explicit operator Float2(Vert val) => new(val.position.x, val.position.y);
public static implicit operator Float2(Fill<float> fill) => new(fill);
public static implicit operator Float2(Fill<int> fill) => new(fill);
}

View File

@ -0,0 +1,202 @@
namespace Nerd_STF.Mathematics;
public struct Float3 : ICloneable, IComparable<Float3>, IEquatable<Float3>, IGroup<float>
{
public static Float3 Back => new(0, 0, -1);
public static Float3 Down => new(0, -1, 0);
public static Float3 Forward => new(0, 0, 1);
public static Float3 Left => new(-1, 0, 0);
public static Float3 Right => new(1, 0, 0);
public static Float3 Up => new(0, 1, 0);
public static Float3 One => new(1, 1, 1);
public static Float3 Zero => new(0, 0, 0);
public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z);
public Float3 Normalized => this / Magnitude;
public Float2 XY => new(x, y);
public Float2 XZ => new(x, z);
public Float2 YZ => new(y, z);
public float x, y, z;
public Float3(float all) : this(all, all, all) { }
public Float3(float x, float y) : this(x, y, 0) { }
public Float3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Float3(Fill<float> fill) : this(fill(0), fill(1), fill(2)) { }
public Float3(Fill<int> fill) : this(fill(0), fill(1), fill(2)) { }
public float this[int index]
{
get => index switch
{
0 => x,
1 => y,
2 => z,
_ => throw new IndexOutOfRangeException(nameof(index)),
};
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default: throw new IndexOutOfRangeException(nameof(index));
}
}
}
public static Float3 Absolute(Float3 val) =>
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y), Mathf.Absolute(val.z));
public static Float3 Average(params Float3[] vals) => Sum(vals) / vals.Length;
public static Float3 Ceiling(Float3 val) =>
new(Mathf.Ceiling(val.x), Mathf.Ceiling(val.y), Mathf.Ceiling(val.z));
public static Float3 Clamp(Float3 val, Float3 min, Float3 max) =>
new(Mathf.Clamp(val.x, min.x, max.x),
Mathf.Clamp(val.y, min.y, max.y),
Mathf.Clamp(val.z, min.z, max.z));
public static Float3 ClampMagnitude(Float3 val, float minMag, float maxMag)
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
float mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
else if (mag > maxMag) val *= maxMag;
return val;
}
public static Float3 Cross(Float3 a, Float3 b, bool normalized = false)
{
Float3 val = new(a.y * b.z - b.y * a.z,
b.x * a.z - a.x * b.z,
a.x * b.y - b.x * a.y);
return normalized ? val.Normalized : val;
}
public static Float3 Divide(Float3 num, params Float3[] vals)
{
foreach (Float3 d in vals) num /= d;
return num;
}
public static float Dot(Float3 a, Float3 b) => a.x * b.x + a.y * b.y + a.z * b.z;
public static float Dot(params Float3[] vals)
{
if (vals.Length < 1) return 0;
float x = 1, y = 1, z = 1;
foreach (Float3 d in vals)
{
x *= d.x;
y *= d.y;
z *= d.z;
}
return x + y + z;
}
public static Float3 Floor(Float3 val) =>
new(Mathf.Floor(val.x), Mathf.Floor(val.y), Mathf.Floor(val.z));
public static Float3 Lerp(Float3 a, Float3 b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp));
public static Float3 Median(params Float3[] vals)
{
float index = Mathf.Average(0, vals.Length - 1);
Float3 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
return Average(valA, valB);
}
public static Float3 Max(params Float3[] vals)
{
if (vals.Length < 1) return Zero;
Float3 val = vals[0];
foreach (Float3 d in vals) val = d > val ? d : val;
return val;
}
public static Float3 Min(params Float3[] vals)
{
if (vals.Length < 1) return Zero;
Float3 val = vals[0];
foreach (Float3 d in vals) val = d < val ? d : val;
return val;
}
public static Float3 Multiply(params Float3[] vals)
{
if (vals.Length < 1) return Zero;
Float3 val = One;
foreach (Float3 d in vals) val *= d;
return val;
}
public static Float3 Subtract(Float3 num, params Float3[] vals)
{
foreach (Float3 d in vals) num -= d;
return num;
}
public static Float3 Sum(params Float3[] vals)
{
Float3 val = Zero;
foreach (Float3 d in vals) val += d;
return val;
}
public int CompareTo(Float3 other) => Magnitude.CompareTo(other.Magnitude);
public override bool Equals([NotNullWhen(true)] object? obj)
{
if (obj == null || obj.GetType() != typeof(Float3)) return false;
return Equals((Float3)obj);
}
public bool Equals(Float3 other) => x == other.x && y == other.y && z == other.z;
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
public override string ToString() => ToString((string?)null);
public string ToString(string? provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider);
public string ToString(IFormatProvider provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider);
public object Clone() => new Float3(x, y, z);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<float> GetEnumerator()
{
yield return x;
yield return y;
yield return z;
}
public float[] ToArray() => new[] { x, y, z };
public List<float> ToList() => new() { x, y, z };
public static Float3 operator +(Float3 a, Float3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z);
public static Float3 operator -(Float3 d) => new(-d.x, -d.y, -d.z);
public static Float3 operator -(Float3 a, Float3 b) => new(a.x - b.x, a.y - b.y, a.z - b.z);
public static Float3 operator *(Float3 a, Float3 b) => new(a.x * b.x, a.y * b.y, a.z * b.z);
public static Float3 operator *(Float3 a, float b) => new(a.x * b, a.y * b, a.z * b);
public static Float3 operator /(Float3 a, Float3 b) => new(a.x / b.x, a.y / b.y, a.z / b.z);
public static Float3 operator /(Float3 a, float b) => new(a.x / b, a.y / b, a.z / b);
public static bool operator ==(Float3 a, Float3 b) => a.Equals(b);
public static bool operator !=(Float3 a, Float3 b) => !a.Equals(b);
public static bool operator >(Float3 a, Float3 b) => a.CompareTo(b) > 0;
public static bool operator <(Float3 a, Float3 b) => a.CompareTo(b) < 0;
public static bool operator >=(Float3 a, Float3 b) => a == b || a > b;
public static bool operator <=(Float3 a, Float3 b) => a == b || a < b;
public static implicit operator Float3(Float2 val) => new(val.x, val.y, 0);
public static explicit operator Float3(Float4 val) => new(val.x, val.y, val.z);
public static implicit operator Float3(Int2 val) => new(val.x, val.y, 0);
public static implicit operator Float3(Int3 val) => new(val.x, val.y, val.z);
public static explicit operator Float3(Int4 val) => new(val.x, val.y, val.z);
public static implicit operator Float3(Vert val) => new(val.position.x, val.position.y, val.position.z);
public static implicit operator Float3(Fill<float> fill) => new(fill);
public static implicit operator Float3(Fill<int> fill) => new(fill);
}

View File

@ -0,0 +1,218 @@
namespace Nerd_STF.Mathematics;
public struct Float4 : ICloneable, IComparable<Float4>, IEquatable<Float4>, IGroup<float>
{
public static Float4 Back => new(0, 0, -1, 0);
public static Float4 Deep => new(0, 0, 0, -1);
public static Float4 Down => new(0, -1, 0, 0);
public static Float4 Far => new(0, 0, 0, 1);
public static Float4 Forward => new(0, 0, 1, 0);
public static Float4 Left => new(-1, 0, 0, 0);
public static Float4 Right => new(1, 0, 0, 0);
public static Float4 Up => new(0, 1, 0, 0);
public static Float4 One => new(1, 1, 1, 1);
public static Float4 Zero => new(0, 0, 0, 0);
public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z + w * w);
public Float4 Normalized => this / Magnitude;
public Float2 XY => new(x, y);
public Float2 XZ => new(x, z);
public Float2 XW => new(x, w);
public Float2 YW => new(y, w);
public Float2 YZ => new(y, z);
public Float2 ZW => new(z, w);
public Float3 XYW => new(x, y, w);
public Float3 XYZ => new(x, y, z);
public Float3 YZW => new(y, z, w);
public Float3 XZW => new(x, z, w);
public float x, y, z, w;
public Float4(float all) : this(all, all, all, all) { }
public Float4(float x, float y) : this(x, y, 0, 0) { }
public Float4(float x, float y, float z) : this(x, y, z, 0) { }
public Float4(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public Float4(Fill<float> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Float4(Fill<int> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public float this[int index]
{
get => index switch
{
0 => x,
1 => y,
2 => z,
3 => w,
_ => throw new IndexOutOfRangeException(nameof(index)),
};
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
case 3:
w = value;
break;
default: throw new IndexOutOfRangeException(nameof(index));
}
}
}
public static Float4 Absolute(Float4 val) =>
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y), Mathf.Absolute(val.z), Mathf.Absolute(val.w));
public static Float4 Average(params Float4[] vals) => Sum(vals) / vals.Length;
public static Float4 Ceiling(Float4 val) =>
new(Mathf.Ceiling(val.x), Mathf.Ceiling(val.y), Mathf.Ceiling(val.z), Mathf.Ceiling(val.w));
public static Float4 Clamp(Float4 val, Float4 min, Float4 max) =>
new(Mathf.Clamp(val.x, min.x, max.x),
Mathf.Clamp(val.y, min.y, max.y),
Mathf.Clamp(val.z, min.z, max.z),
Mathf.Clamp(val.w, min.w, max.w));
public static Float4 ClampMagnitude(Float4 val, float minMag, float maxMag)
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
float mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
else if (mag > maxMag) val *= maxMag;
return val;
}
public static Float4 Divide(Float4 num, params Float4[] vals)
{
foreach (Float4 d in vals) num /= d;
return num;
}
public static float Dot(Float4 a, Float4 b) => a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
public static float Dot(params Float4[] vals)
{
if (vals.Length < 1) return 0;
float x = 1, y = 1, z = 1, w = 1;
foreach (Float4 d in vals)
{
x *= d.x;
y *= d.y;
z *= d.z;
w *= d.w;
}
return x + y + z;
}
public static Float4 Floor(Float4 val) =>
new(Mathf.Floor(val.x), Mathf.Floor(val.y), Mathf.Floor(val.z), Mathf.Floor(val.w));
public static Float4 Lerp(Float4 a, Float4 b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp),
Mathf.Lerp(a.w, b.w, t, clamp));
public static Float4 Median(params Float4[] vals)
{
float index = Mathf.Average(0, vals.Length - 1);
Float4 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
return Average(valA, valB);
}
public static Float4 Max(params Float4[] vals)
{
if (vals.Length < 1) return Zero;
Float4 val = vals[0];
foreach (Float4 d in vals) val = d > val ? d : val;
return val;
}
public static Float4 Min(params Float4[] vals)
{
if (vals.Length < 1) return Zero;
Float4 val = vals[0];
foreach (Float4 d in vals) val = d < val ? d : val;
return val;
}
public static Float4 Multiply(params Float4[] vals)
{
if (vals.Length < 1) return Zero;
Float4 val = One;
foreach (Float4 d in vals) val *= d;
return val;
}
public static Float4 Subtract(Float4 num, params Float4[] vals)
{
foreach (Float4 d in vals) num -= d;
return num;
}
public static Float4 Sum(params Float4[] vals)
{
Float4 val = Zero;
foreach (Float4 d in vals) val += d;
return val;
}
public int CompareTo(Float4 other) => Magnitude.CompareTo(other.Magnitude);
public override bool Equals([NotNullWhen(true)] object? obj)
{
if (obj == null || obj.GetType() != typeof(Float4)) return false;
return Equals((Float4)obj);
}
public bool Equals(Float4 other) => x == other.x && y == other.y && z == other.z && w == other.w;
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode();
public override string ToString() => ToString((string?)null);
public string ToString(string? provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider)
+ " W: " + w.ToString(provider);
public string ToString(IFormatProvider provider) =>
"X: " + x.ToString(provider) + " Y: " + y.ToString(provider) + " Z: " + z.ToString(provider)
+ " W: " + w.ToString(provider);
public object Clone() => new Float4(x, y, z, w);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<float> GetEnumerator()
{
yield return x;
yield return y;
yield return z;
yield return w;
}
public float[] ToArray() => new[] { x, y, z, w };
public List<float> ToList() => new() { x, y, z, w };
public static Float4 operator +(Float4 a, Float4 b) => new(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
public static Float4 operator -(Float4 d) => new(-d.x, -d.y, -d.z, -d.w);
public static Float4 operator -(Float4 a, Float4 b) => new(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
public static Float4 operator *(Float4 a, Float4 b) => new(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
public static Float4 operator *(Float4 a, float b) => new(a.x * b, a.y * b, a.z * b, a.w * b);
public static Float4 operator /(Float4 a, Float4 b) => new(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
public static Float4 operator /(Float4 a, float b) => new(a.x / b, a.y / b, a.z / b, a.w / b);
public static bool operator ==(Float4 a, Float4 b) => a.Equals(b);
public static bool operator !=(Float4 a, Float4 b) => !a.Equals(b);
public static bool operator >(Float4 a, Float4 b) => a.CompareTo(b) > 0;
public static bool operator <(Float4 a, Float4 b) => a.CompareTo(b) < 0;
public static bool operator >=(Float4 a, Float4 b) => a == b || a > b;
public static bool operator <=(Float4 a, Float4 b) => a == b || a < b;
public static implicit operator Float4(Float2 val) => new(val.x, val.y, 0, 0);
public static implicit operator Float4(Float3 val) => new(val.x, val.y, val.z, 0);
public static implicit operator Float4(Int2 val) => new(val.x, val.y, 0, 0);
public static implicit operator Float4(Int3 val) => new(val.x, val.y, val.z, 0);
public static implicit operator Float4(Int4 val) => new(val.x, val.y, val.z, val.w);
public static implicit operator Float4(Vert val) => new(val.position.x, val.position.y, val.position.z, 0);
public static implicit operator Float4(Fill<float> fill) => new(fill);
public static implicit operator Float4(Fill<int> fill) => new(fill);
}

View File

@ -2,7 +2,7 @@
public struct Box2D : ICloneable, IContainer<Vert>, IEquatable<Box2D>
{
public static Box2D Unit => new(Vert.Zero, Double2.One);
public static Box2D Unit => new(Vert.Zero, Float2.One);
public Vert MaxVert
{
@ -10,7 +10,7 @@ public struct Box2D : ICloneable, IContainer<Vert>, IEquatable<Box2D>
set
{
Vert diff = center - value;
size = (Double2)diff.position * 2;
size = (Float2)diff.position * 2;
}
}
public Vert MinVert
@ -19,25 +19,25 @@ public struct Box2D : ICloneable, IContainer<Vert>, IEquatable<Box2D>
set
{
Vert diff = center + value;
size = (Double2)diff.position * 2;
size = (Float2)diff.position * 2;
}
}
public double Area => size.x * size.y;
public double Perimeter => size.x * 2 + size.y * 2;
public float Area => size.x * size.y;
public float Perimeter => size.x * 2 + size.y * 2;
public Vert center;
public Double2 size;
public Float2 size;
public Box2D(Vert min, Vert max) : this(Vert.Average(min, max), (Double2)(min - max)) { }
public Box2D(Vert center, Double2 size)
public Box2D(Vert min, Vert max) : this(Vert.Average(min, max), (Float2)(min - max)) { }
public Box2D(Vert center, Float2 size)
{
this.center = center;
this.size = size;
}
public Box2D(Fill<double> fill) : this(fill, new Double2(fill(3), fill(4))) { }
public Box2D(Fill<float> fill) : this(fill, new Float2(fill(3), fill(4))) { }
public double this[int index]
public float this[int index]
{
get => size[index];
set => size[index] = value;
@ -46,34 +46,34 @@ public struct Box2D : ICloneable, IContainer<Vert>, IEquatable<Box2D>
public static Box2D Absolute(Box2D val) => new(Vert.Absolute(val.MinVert), Vert.Absolute(val.MaxVert));
public static Box2D Average(params Box2D[] vals)
{
(Vert[] centers, Double2[] sizes) = SplitArray(vals);
return new(Vert.Average(centers), Double2.Average(sizes));
(Vert[] centers, Float2[] sizes) = SplitArray(vals);
return new(Vert.Average(centers), Float2.Average(sizes));
}
public static Box2D Ceiling(Box2D val) => new(Vert.Ceiling(val.center), Double2.Ceiling(val.size));
public static Box2D Ceiling(Box2D val) => new(Vert.Ceiling(val.center), Float2.Ceiling(val.size));
public static Box2D Clamp(Box2D val, Box2D min, Box2D max) =>
new(Vert.Clamp(val.center, min.center, max.center), Double2.Clamp(val.size, min.size, max.size));
public static Box2D Floor(Box2D val) => new(Vert.Floor(val.center), Double2.Floor(val.size));
new(Vert.Clamp(val.center, min.center, max.center), Float2.Clamp(val.size, min.size, max.size));
public static Box2D Floor(Box2D val) => new(Vert.Floor(val.center), Float2.Floor(val.size));
public static Box2D Lerp(Box2D a, Box2D b, float t, bool clamp = true) =>
new(Vert.Lerp(a.center, b.center, t, clamp), Double2.Lerp(a.size, b.size, t, clamp));
new(Vert.Lerp(a.center, b.center, t, clamp), Float2.Lerp(a.size, b.size, t, clamp));
public static Box2D Median(params Box2D[] vals)
{
(Vert[] verts, Double2[] sizes) = SplitArray(vals);
return new(Vert.Median(verts), Double2.Median(sizes));
(Vert[] verts, Float2[] sizes) = SplitArray(vals);
return new(Vert.Median(verts), Float2.Median(sizes));
}
public static Box2D Max(params Box2D[] vals)
{
(Vert[] verts, Double2[] sizes) = SplitArray(vals);
return new(Vert.Max(verts), Double2.Max(sizes));
(Vert[] verts, Float2[] sizes) = SplitArray(vals);
return new(Vert.Max(verts), Float2.Max(sizes));
}
public static Box2D Min(params Box2D[] vals)
{
(Vert[] verts, Double2[] sizes) = SplitArray(vals);
return new(Vert.Min(verts), Double2.Min(sizes));
(Vert[] verts, Float2[] sizes) = SplitArray(vals);
return new(Vert.Min(verts), Float2.Min(sizes));
}
public static (Vert[] centers, Double2[] sizes) SplitArray(params Box2D[] vals)
public static (Vert[] centers, Float2[] sizes) SplitArray(params Box2D[] vals)
{
Vert[] centers = new Vert[vals.Length];
Double2[] sizes = new Double2[vals.Length];
Float2[] sizes = new Float2[vals.Length];
for (int i = 0; i < vals.Length; i++)
{
@ -99,24 +99,24 @@ public struct Box2D : ICloneable, IContainer<Vert>, IEquatable<Box2D>
public bool Contains(Vert vert)
{
Double2 diff = Double2.Absolute((Double2)(center - vert));
Float2 diff = Float2.Absolute((Float2)(center - vert));
return diff.x <= size.x && diff.y <= size.y;
}
public object Clone() => new Box2D(center, size);
public static Box2D operator +(Box2D a, Vert b) => new(a.center + b, a.size);
public static Box2D operator +(Box2D a, Double2 b) => new(a.center, a.size + b);
public static Box2D operator +(Box2D a, Float2 b) => new(a.center, a.size + b);
public static Box2D operator -(Box2D b) => new(-b.MaxVert, -b.MinVert);
public static Box2D operator -(Box2D a, Vert b) => new(a.center - b, a.size);
public static Box2D operator -(Box2D a, Double2 b) => new(a.center, a.size - b);
public static Box2D operator *(Box2D a, double b) => new(a.center * b, a.size * b);
public static Box2D operator *(Box2D a, Double2 b) => new(a.center, a.size * b);
public static Box2D operator /(Box2D a, double b) => new(a.center / b, a.size / b);
public static Box2D operator /(Box2D a, Double2 b) => new(a.center, a.size / b);
public static Box2D operator -(Box2D a, Float2 b) => new(a.center, a.size - b);
public static Box2D operator *(Box2D a, float b) => new(a.center * b, a.size * b);
public static Box2D operator *(Box2D a, Float2 b) => new(a.center, a.size * b);
public static Box2D operator /(Box2D a, float b) => new(a.center / b, a.size / b);
public static Box2D operator /(Box2D a, Float2 b) => new(a.center, a.size / b);
public static bool operator ==(Box2D a, Box2D b) => a.Equals(b);
public static bool operator !=(Box2D a, Box2D b) => !a.Equals(b);
public static implicit operator Box2D(Fill<double> fill) => new(fill);
public static explicit operator Box2D(Box3D box) => new(box.center, (Double2)box.size);
public static implicit operator Box2D(Fill<float> fill) => new(fill);
public static explicit operator Box2D(Box3D box) => new(box.center, (Float2)box.size);
}

View File

@ -2,7 +2,7 @@
public struct Box3D : ICloneable, IContainer<Vert>, IEquatable<Box3D>
{
public static Box3D Unit => new(Vert.Zero, Double3.One);
public static Box3D Unit => new(Vert.Zero, Float3.One);
public Vert MaxVert
{
@ -23,22 +23,22 @@ public struct Box3D : ICloneable, IContainer<Vert>, IEquatable<Box3D>
}
}
public double Area => size.x * size.y * size.z;
public double Perimeter => size.x * 2 + size.y * 2 + size.z * 2;
public float Area => size.x * size.y * size.z;
public float Perimeter => size.x * 2 + size.y * 2 + size.z * 2;
public Vert center;
public Double3 size;
public Float3 size;
public Box3D(Box2D box) : this(box.center, (Double3)box.size) { }
public Box3D(Vert min, Vert max) : this(Vert.Average(min, max), (Double3)(min - max)) { }
public Box3D(Vert center, Double3 size)
public Box3D(Box2D box) : this(box.center, (Float3)box.size) { }
public Box3D(Vert min, Vert max) : this(Vert.Average(min, max), (Float3)(min - max)) { }
public Box3D(Vert center, Float3 size)
{
this.center = center;
this.size = size;
}
public Box3D(Fill<double> fill) : this(fill, new Double3(fill(3), fill(4), fill(5))) { }
public Box3D(Fill<float> fill) : this(fill, new Float3(fill(3), fill(4), fill(5))) { }
public double this[int index]
public float this[int index]
{
get => size[index];
set => size[index] = value;
@ -47,34 +47,34 @@ public struct Box3D : ICloneable, IContainer<Vert>, IEquatable<Box3D>
public static Box3D Absolute(Box3D val) => new(Vert.Absolute(val.MinVert), Vert.Absolute(val.MaxVert));
public static Box3D Average(params Box3D[] vals)
{
(Vert[] centers, Double3[] sizes) = SplitArray(vals);
return new(Vert.Average(centers), Double3.Average(sizes));
(Vert[] centers, Float3[] sizes) = SplitArray(vals);
return new(Vert.Average(centers), Float3.Average(sizes));
}
public static Box3D Ceiling(Box3D val) => new(Vert.Ceiling(val.center), Double3.Ceiling(val.size));
public static Box3D Ceiling(Box3D val) => new(Vert.Ceiling(val.center), Float3.Ceiling(val.size));
public static Box3D Clamp(Box3D val, Box3D min, Box3D max) =>
new(Vert.Clamp(val.center, min.center, max.center), Double3.Clamp(val.size, min.size, max.size));
public static Box3D Floor(Box3D val) => new(Vert.Floor(val.center), Double3.Floor(val.size));
new(Vert.Clamp(val.center, min.center, max.center), Float3.Clamp(val.size, min.size, max.size));
public static Box3D Floor(Box3D val) => new(Vert.Floor(val.center), Float3.Floor(val.size));
public static Box3D Lerp(Box3D a, Box3D b, float t, bool clamp = true) =>
new(Vert.Lerp(a.center, b.center, t, clamp), Double3.Lerp(a.size, b.size, t, clamp));
new(Vert.Lerp(a.center, b.center, t, clamp), Float3.Lerp(a.size, b.size, t, clamp));
public static Box3D Median(params Box3D[] vals)
{
(Vert[] verts, Double3[] sizes) = SplitArray(vals);
return new(Vert.Median(verts), Double3.Median(sizes));
(Vert[] verts, Float3[] sizes) = SplitArray(vals);
return new(Vert.Median(verts), Float3.Median(sizes));
}
public static Box3D Max(params Box3D[] vals)
{
(Vert[] verts, Double3[] sizes) = SplitArray(vals);
return new(Vert.Max(verts), Double3.Max(sizes));
(Vert[] verts, Float3[] sizes) = SplitArray(vals);
return new(Vert.Max(verts), Float3.Max(sizes));
}
public static Box3D Min(params Box3D[] vals)
{
(Vert[] verts, Double3[] sizes) = SplitArray(vals);
return new(Vert.Min(verts), Double3.Min(sizes));
(Vert[] verts, Float3[] sizes) = SplitArray(vals);
return new(Vert.Min(verts), Float3.Min(sizes));
}
public static (Vert[] centers, Double3[] sizes) SplitArray(params Box3D[] vals)
public static (Vert[] centers, Float3[] sizes) SplitArray(params Box3D[] vals)
{
Vert[] centers = new Vert[vals.Length];
Double3[] sizes = new Double3[vals.Length];
Float3[] sizes = new Float3[vals.Length];
for (int i = 0; i < vals.Length; i++)
{
@ -100,23 +100,23 @@ public struct Box3D : ICloneable, IContainer<Vert>, IEquatable<Box3D>
public bool Contains(Vert vert)
{
Double3 diff = Double3.Absolute(center - vert);
Float3 diff = Float3.Absolute(center - vert);
return diff.x <= size.x && diff.y <= size.y && diff.z <= size.z;
}
public object Clone() => new Box3D(center, size);
public static Box3D operator +(Box3D a, Vert b) => new(a.center + b, a.size);
public static Box3D operator +(Box3D a, Double3 b) => new(a.center, a.size + b);
public static Box3D operator +(Box3D a, Float3 b) => new(a.center, a.size + b);
public static Box3D operator -(Box3D b) => new(-b.MaxVert, -b.MinVert);
public static Box3D operator -(Box3D a, Vert b) => new(a.center - b, a.size);
public static Box3D operator -(Box3D a, Double3 b) => new(a.center, a.size - b);
public static Box3D operator *(Box3D a, double b) => new(a.center * b, a.size * b);
public static Box3D operator *(Box3D a, Double3 b) => new(a.center, a.size * b);
public static Box3D operator /(Box3D a, double b) => new(a.center / b, a.size / b);
public static Box3D operator /(Box3D a, Double3 b) => new(a.center, a.size / b);
public static Box3D operator -(Box3D a, Float3 b) => new(a.center, a.size - b);
public static Box3D operator *(Box3D a, float b) => new(a.center * b, a.size * b);
public static Box3D operator *(Box3D a, Float3 b) => new(a.center, a.size * b);
public static Box3D operator /(Box3D a, float b) => new(a.center / b, a.size / b);
public static Box3D operator /(Box3D a, Float3 b) => new(a.center, a.size / b);
public static bool operator ==(Box3D a, Box3D b) => a.Equals(b);
public static bool operator !=(Box3D a, Box3D b) => !a.Equals(b);
public static implicit operator Box3D(Fill<double> fill) => new(fill);
public static implicit operator Box3D(Fill<float> fill) => new(fill);
public static implicit operator Box3D(Box2D box) => new(box);
}

View File

@ -13,7 +13,7 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public static Line One => new(Vert.Zero, Vert.One);
public static Line Zero => new(Vert.Zero, Vert.Zero);
public double Length => (b - a).Magnitude;
public float Length => (b - a).Magnitude;
public Vert a, b;
@ -22,13 +22,13 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
this.a = a;
this.b = b;
}
public Line(double x1, double y1, double x2, double y2) : this(new(x1, y1), new(x2, y2)) { }
public Line(double x1, double y1, double z1, double x2, double y2, double z2)
public Line(float x1, float y1, float x2, float y2) : this(new(x1, y1), new(x2, y2)) { }
public Line(float x1, float y1, float z1, float x2, float y2, float z2)
: this(new(x1, y1, z1), new(x2, y2, z2)) { }
public Line(Fill<Vert> fill) : this(fill(0), fill(1)) { }
public Line(Fill<Double3> fill) : this(new(fill(0)), new(fill(1))) { }
public Line(Fill<Float3> fill) : this(new(fill(0)), new(fill(1))) { }
public Line(Fill<Int3> fill) : this(new(fill(0)), new(fill(1))) { }
public Line(Fill<double> fill) : this(new(fill(0), fill(1), fill(2)), new(fill(3), fill(4), fill(5))) { }
public Line(Fill<float> fill) : this(new(fill(0), fill(1), fill(2)), new(fill(3), fill(4), fill(5))) { }
public Line(Fill<int> fill) : this(new(fill(0), fill(1), fill(2)), new(fill(3), fill(4), fill(5))) { }
public Vert this[int index]
@ -66,7 +66,7 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public static Line Clamp(Line val, Line min, Line max) =>
new(Vert.Clamp(val.a, min.a, max.a), Vert.Clamp(val.b, min.b, max.b));
public static Line Floor(Line val) => new(Vert.Floor(val.a), Vert.Floor(val.b));
public static Line Lerp(Line a, Line b, double t, bool clamp = true) =>
public static Line Lerp(Line a, Line b, float t, bool clamp = true) =>
new(Vert.Lerp(a.a, b.a, t, clamp), Vert.Lerp(a.b, b.b, t, clamp));
public static Line Median(params Line[] vals)
{
@ -114,16 +114,16 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public bool Contains(Vert vert)
{
Double3 diffA = a - vert, diffB = a - b;
double lerpVal = diffA.Magnitude / diffB.Magnitude;
Float3 diffA = a - vert, diffB = a - b;
float lerpVal = diffA.Magnitude / diffB.Magnitude;
return Vert.Lerp(a, b, lerpVal) == vert;
}
public Vert ClosestTo(Vert vert) => ClosestTo(vert, Calculus.DefaultStep);
public Vert ClosestTo(Vert vert, double step)
public Vert ClosestTo(Vert vert, float step)
{
Vert closestA = a, closestB = b;
for (double t = 0; t <= 1; t += step)
for (float t = 0; t <= 1; t += step)
{
Vert valA = Vert.Lerp(a, b, t);
Vert valB = Vert.Lerp(b, a, t);
@ -143,7 +143,7 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public Line[] Subdivide()
{
Vert middle = Vert.Lerp(a, b, 0.5);
Vert middle = Vert.Lerp(a, b, 0.5f);
return new Line[] { new(a, middle), new(middle, b) };
}
public Line[] Subdivide(int iterations)
@ -162,9 +162,9 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public Vert[] ToArray() => new Vert[] { a, b };
public List<Vert> ToList() => new() { a, b };
public double[] ToDoubleArray() => new double[] { a.position.x, a.position.y, a.position.z,
public float[] ToDoubleArray() => new float[] { a.position.x, a.position.y, a.position.z,
b.position.x, b.position.y, b.position.z };
public List<double> ToDoubleList() => new() { a.position.x, a.position.y, a.position.z,
public List<float> ToDoubleList() => new() { a.position.x, a.position.y, a.position.z,
b.position.x, b.position.y, b.position.z };
public static Line operator +(Line a, Line b) => new(a.a + b.a, a.b + b.b);
@ -174,10 +174,10 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public static Line operator -(Line a, Vert b) => new(a.a - b, a.b - b);
public static Line operator *(Line a, Line b) => new(a.a * b.a, a.b * b.b);
public static Line operator *(Line a, Vert b) => new(a.a * b, a.b * b);
public static Line operator *(Line a, double b) => new(a.a * b, a.b * b);
public static Line operator *(Line a, float b) => new(a.a * b, a.b * b);
public static Line operator /(Line a, Line b) => new(a.a / b.a, a.b / b.b);
public static Line operator /(Line a, Vert b) => new(a.a / b, a.b / b);
public static Line operator /(Line a, double b) => new(a.a / b, a.b / b);
public static Line operator /(Line a, float b) => new(a.a / b, a.b / b);
public static bool operator ==(Line a, Line b) => a.Equals(b);
public static bool operator !=(Line a, Line b) => !a.Equals(b);
public static bool operator >(Line a, Line b) => a.CompareTo(b) > 0;
@ -186,8 +186,8 @@ public struct Line : ICloneable, IClosest<Vert>, IComparable<Line>, IContainer<V
public static bool operator <=(Line a, Line b) => a < b || a == b;
public static implicit operator Line(Fill<Vert> fill) => new(fill);
public static implicit operator Line(Fill<Double3> fill) => new(fill);
public static implicit operator Line(Fill<Float3> fill) => new(fill);
public static implicit operator Line(Fill<Int3> fill) => new(fill);
public static implicit operator Line(Fill<double> fill) => new(fill);
public static implicit operator Line(Fill<float> fill) => new(fill);
public static implicit operator Line(Fill<int> fill) => new(fill);
}

View File

@ -26,20 +26,20 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
[Obsolete("This method uses the Polygon.Triangulate() function, which has issues. It will be fixed in a " +
"future update.")]
public double Area
public float Area
{
get
{
double val = 0;
float val = 0;
foreach (Triangle t in Triangulate()) val += t.Area;
return val;
}
}
public double Perimeter
public float Perimeter
{
get
{
double val = 0;
float val = 0;
foreach (Line l in Lines) val += l.Length;
return val;
}
@ -62,7 +62,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
}
this = new(verts.ToArray());
}
public Polygon(Fill<Double3?> fill)
public Polygon(Fill<Float3?> fill)
{
List<Vert> verts = new();
int i = 0;
@ -92,7 +92,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
for (int i = 0; i < length; i++) verts.Add(fill(i));
this = new(verts.ToArray());
}
public Polygon(Fill<Double3> fill, int length)
public Polygon(Fill<Float3> fill, int length)
{
List<Vert> verts = new();
for (int i = 0; i < length; i++) verts.Add(fill(i));
@ -104,7 +104,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
for (int i = 0; i < length; i++) lines.Add(fill(i));
this = new(lines.ToArray());
}
public Polygon(params Double3[] verts)
public Polygon(params Float3[] verts)
{
p_verts = new Vert[verts.Length];
for (int i = 0; i < verts.Length; i++) p_verts[i] = verts[i];
@ -132,7 +132,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
List<Vert> parts = new();
for (int i = 0; i < vertCount; i++)
{
double val = Mathf.Tau * i / vertCount;
float val = Mathf.Tau * i / vertCount;
parts.Add(new(Mathf.Cos(val), Mathf.Sin(val)));
}
return new(parts.ToArray());
@ -182,7 +182,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
for (int i = 0; i < v.Length; i++) v[i] = Vert.Floor(v[i]);
return new(v);
}
public static Polygon Lerp(Polygon a, Polygon b, double t, bool clamp = true)
public static Polygon Lerp(Polygon a, Polygon b, float t, bool clamp = true)
{
if (!CheckVerts(a, b)) throw new DifferingVertCountException(a, b);
Line[][] lines = new Line[2][] { a.Lines, b.Lines };
@ -245,10 +245,10 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
return new(res);
}
public static double[] ToDoubleArrayAll(params Polygon[] polys) => ToDoubleListAll(polys).ToArray();
public static List<double> ToDoubleListAll(params Polygon[] polys)
public static float[] ToDoubleArrayAll(params Polygon[] polys) => ToDoubleListAll(polys).ToArray();
public static List<float> ToDoubleListAll(params Polygon[] polys)
{
List<double> vals = new();
List<float> vals = new();
foreach (Polygon poly in polys) vals.AddRange(poly.ToDoubleArray());
return vals;
}
@ -286,9 +286,9 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
public Vert[] ToArray() => Verts;
public List<Vert> ToList() => new(Verts);
public double[] ToDoubleArray()
public float[] ToDoubleArray()
{
double[] vals = new double[Verts.Length * 3];
float[] vals = new float[Verts.Length * 3];
for (int i = 0; i < Verts.Length; i++)
{
int pos = i * 3;
@ -298,7 +298,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
}
return vals;
}
public List<double> ToDoubleList() => new(ToDoubleArray());
public List<float> ToDoubleList() => new(ToDoubleArray());
public Polygon Subdivide()
{
@ -323,7 +323,7 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
{
for (int factor = 0; factor < segments; factor++)
{
double unit = factor / (double)(segments * 2), unit2 = unit + 0.5, lastUnit = unit * 2;
float unit = factor / (float)(segments * 2), unit2 = unit + 0.5f, lastUnit = unit * 2;
Vert p1, p2;
if (i == Verts.Length - 1)
{
@ -500,10 +500,10 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
public static bool operator !=(Polygon a, Polygon b) => !a.Equals(b);
public static implicit operator Polygon(Fill<Vert?> fill) => new(fill);
public static implicit operator Polygon(Fill<Double3?> fill) => new(fill);
public static implicit operator Polygon(Fill<Float3?> fill) => new(fill);
public static implicit operator Polygon(Fill<Line?> fill) => new(fill);
public static implicit operator Polygon(Vert[] verts) => new(verts);
public static implicit operator Polygon(Double3[] verts) => new(verts);
public static implicit operator Polygon(Float3[] verts) => new(verts);
public static implicit operator Polygon(Line[] lines) => new(lines);
public static implicit operator Polygon(Triangle tri) => new(tri.AB, tri.BC, tri.CA);
public static implicit operator Polygon(Quadrilateral quad) => new(quad.AB, quad.BC, quad.CD, quad.DA);

View File

@ -94,16 +94,16 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
private Vert p_a, p_b, p_c, p_d;
private Line p_ab, p_bc, p_cd, p_da;
public double Area
public float Area
{
get
{
double val = 0;
float val = 0;
foreach (Triangle t in Triangulate()) val += t.Area;
return val;
}
}
public double Perimeter => AB.Length + BC.Length + CD.Length + DA.Length;
public float Perimeter => AB.Length + BC.Length + CD.Length + DA.Length;
public Quadrilateral(Vert a, Vert b, Vert c, Vert d)
{
@ -130,16 +130,16 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
p_cd = cd;
p_da = da;
}
public Quadrilateral(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
public Quadrilateral(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
: this(new Vert(x1, y1), new(x2, y2), new(x3, y3), new(x4, y4)) { }
public Quadrilateral(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3,
double z3, double x4, double y4, double z4)
public Quadrilateral(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3,
float z3, float x4, float y4, float z4)
: this(new Vert(x1, y1, z1), new(x2, y2, z2), new(x3, y3, z3), new(x4, y4, z4)) { }
public Quadrilateral(Fill<Double3> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Quadrilateral(Fill<Float3> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Quadrilateral(Fill<Int3> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Quadrilateral(Fill<Vert> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Quadrilateral(Fill<Line> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
public Quadrilateral(Fill<double> fill) : this(fill(0), fill(1), fill(2), fill(3), fill(4), fill(5), fill(6),
public Quadrilateral(Fill<float> fill) : this(fill(0), fill(1), fill(2), fill(3), fill(4), fill(5), fill(6),
fill(7), fill(8), fill(9), fill(10), fill(11)) { }
public Quadrilateral(Fill<int> fill) : this(fill(0), fill(1), fill(2), fill(3), fill(4), fill(5), fill(6),
fill(7), fill(8), fill(9), fill(10), fill(11)) { }
@ -193,7 +193,7 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
Vert.Clamp(val.D, min.D, max.D));
public static Quadrilateral Floor(Quadrilateral val) =>
new(Vert.Floor(val.A), Vert.Floor(val.B), Vert.Floor(val.C), Vert.Floor(val.D));
public static Quadrilateral Lerp(Quadrilateral a, Quadrilateral b, double t, bool clamp = true) =>
public static Quadrilateral Lerp(Quadrilateral a, Quadrilateral b, float t, bool clamp = true) =>
new(Vert.Lerp(a.A, b.A, t, clamp), Vert.Lerp(a.B, b.B, t, clamp), Vert.Lerp(a.C, b.C, t, clamp),
Vert.Lerp(a.D, b.D, t, clamp));
public static Quadrilateral Max(params Quadrilateral[] vals)
@ -241,9 +241,9 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
return (ab, bc, cd, da);
}
public static double[] ToDoubleArrayAll(params Quadrilateral[] quads)
public static float[] ToDoubleArrayAll(params Quadrilateral[] quads)
{
double[] vals = new double[quads.Length * 12];
float[] vals = new float[quads.Length * 12];
for (int i = 0; i < quads.Length; i++)
{
int pos = i * 12;
@ -262,7 +262,7 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
}
return vals;
}
public static List<double> ToDoubleListAll(params Quadrilateral[] quads) => new(ToDoubleArrayAll(quads));
public static List<float> ToDoubleListAll(params Quadrilateral[] quads) => new(ToDoubleArrayAll(quads));
public override bool Equals([NotNullWhen(true)] object? obj)
{
@ -291,11 +291,11 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
public Vert[] ToArray() => new Vert[] { A, B, C, D };
public List<Vert> ToList() => new() { A, B, C, D };
public double[] ToDoubleArray() => new double[] { A.position.x, A.position.y, A.position.z,
public float[] ToDoubleArray() => new float[] { A.position.x, A.position.y, A.position.z,
B.position.x, B.position.y, B.position.z,
C.position.x, C.position.y, C.position.z,
D.position.x, D.position.y, D.position.z };
public List<double> ToDoubleList() => new() { A.position.x, A.position.y, A.position.z,
public List<float> ToDoubleList() => new() { A.position.x, A.position.y, A.position.z,
B.position.x, B.position.y, B.position.z,
C.position.x, C.position.y, C.position.z,
D.position.x, D.position.y, D.position.z };
@ -313,19 +313,19 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
public static Quadrilateral operator *(Quadrilateral a, Quadrilateral b) => new(a.A * b.A, a.B * b.B,
a.C * b.C, a.D * b.D);
public static Quadrilateral operator *(Quadrilateral a, Vert b) => new(a.A * b, a.B * b, a.C * b, a.D * b);
public static Quadrilateral operator *(Quadrilateral a, double b) => new(a.A * b, a.B * b, a.C * b, a.D * b);
public static Quadrilateral operator *(Quadrilateral a, float b) => new(a.A * b, a.B * b, a.C * b, a.D * b);
public static Quadrilateral operator /(Quadrilateral a, Quadrilateral b) => new(a.A / b.A, a.B / b.B,
a.C / b.C, a.D / b.D);
public static Quadrilateral operator /(Quadrilateral a, Vert b) => new(a.A / b, a.B / b, a.C / b, a.D / b);
public static Quadrilateral operator /(Quadrilateral a, double b) => new(a.A / b, a.B / b, a.C / b, a.D / b);
public static Quadrilateral operator /(Quadrilateral a, float b) => new(a.A / b, a.B / b, a.C / b, a.D / b);
public static bool operator ==(Quadrilateral a, Quadrilateral b) => a.Equals(b);
public static bool operator !=(Quadrilateral a, Quadrilateral b) => !a.Equals(b);
public static implicit operator Quadrilateral(Fill<Vert> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<Double3> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<Float3> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<Int3> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<Line> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<double> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<float> fill) => new(fill);
public static implicit operator Quadrilateral(Fill<int> fill) => new(fill);
public static explicit operator Quadrilateral(Polygon poly) => new(poly.Lines[0], poly.Lines[1],
poly.Lines[2], poly.Lines[3]);

View File

@ -1,64 +1,64 @@
namespace Nerd_STF.Mathematics.Geometry;
public struct Sphere : ICloneable, IClosest<Vert>, IComparable<Sphere>, IComparable<double>, IContainer<Vert>,
IEquatable<Sphere>, IEquatable<double>
public struct Sphere : ICloneable, IClosest<Vert>, IComparable<Sphere>, IComparable<float>, IContainer<Vert>,
IEquatable<Sphere>, IEquatable<float>
{
public static Sphere Unit => new(Vert.Zero, 1);
public Vert center;
public double radius;
public float radius;
public double SurfaceArea => 4 * Mathf.Pi * radius * radius;
public double Volume => 4 / 3 * (Mathf.Pi * radius * radius * radius);
public float SurfaceArea => 4 * Mathf.Pi * radius * radius;
public float Volume => 4 / 3 * (Mathf.Pi * radius * radius * radius);
public static Sphere FromDiameter(Vert a, Vert b) => new(Vert.Average(a, b), (a - b).Magnitude / 2);
public static Sphere FromRadius(Vert center, Vert radius) => new(center, (center - radius).Magnitude);
public Sphere(Vert center, double radius)
public Sphere(Vert center, float radius)
{
this.center = center;
this.radius = radius;
}
public Sphere(double cX, double cY, double radius) : this(new Vert(cX, cY), radius) { }
public Sphere(double cX, double cY, double cZ, double radius) : this(new Vert(cX, cY, cZ), radius) { }
public Sphere(Fill<double> fill, double radius) : this(new Vert(fill), radius) { }
public Sphere(Fill<double> fill) : this(new Vert(fill), fill(3)) { }
public Sphere(Fill<int> fill, double radius) : this(new Vert(fill), radius) { }
public Sphere(float cX, float cY, float radius) : this(new Vert(cX, cY), radius) { }
public Sphere(float cX, float cY, float cZ, float radius) : this(new Vert(cX, cY, cZ), radius) { }
public Sphere(Fill<float> fill, float radius) : this(new Vert(fill), radius) { }
public Sphere(Fill<float> fill) : this(new Vert(fill), fill(3)) { }
public Sphere(Fill<int> fill, float radius) : this(new Vert(fill), radius) { }
public Sphere(Fill<int> fill) : this(new Vert(fill), fill(3)) { }
public Sphere(Fill<Vert> fill, double radius) : this(fill(0), radius) { }
public Sphere(Fill<Vert> fillA, Fill<double> fillB) : this(fillA(0), fillB(0)) { }
public Sphere(Fill<Vert> fill, float radius) : this(fill(0), radius) { }
public Sphere(Fill<Vert> fillA, Fill<float> fillB) : this(fillA(0), fillB(0)) { }
public static Sphere Average(params Sphere[] vals)
{
(Vert[] centers, double[] radii) = SplitArray(vals);
(Vert[] centers, float[] radii) = SplitArray(vals);
return new(Vert.Average(centers), Mathf.Average(radii));
}
public static Sphere Ceiling(Sphere val) => new(Vert.Ceiling(val.center), Mathf.Ceiling(val.radius));
public static Sphere Clamp(Sphere val, Sphere min, Sphere max) =>
new(Vert.Clamp(val.center, min.center, max.center), Mathf.Clamp(val.radius, min.radius, max.radius));
public static Sphere Floor(Sphere val) => new(Vert.Floor(val.center), Mathf.Floor(val.radius));
public static Sphere Lerp(Sphere a, Sphere b, double t, bool clamp = true) =>
public static Sphere Lerp(Sphere a, Sphere b, float t, bool clamp = true) =>
new(Vert.Lerp(a.center, b.center, t, clamp), Mathf.Lerp(a.radius, b.radius, t, clamp));
public static Sphere Max(params Sphere[] vals)
{
(Vert[] centers, double[] radii) = SplitArray(vals);
(Vert[] centers, float[] radii) = SplitArray(vals);
return new(Vert.Max(centers), Mathf.Max(radii));
}
public static Sphere Median(params Sphere[] vals)
{
(Vert[] centers, double[] radii) = SplitArray(vals);
(Vert[] centers, float[] radii) = SplitArray(vals);
return new(Vert.Median(centers), Mathf.Median(radii));
}
public static Sphere Min(params Sphere[] vals)
{
(Vert[] centers, double[] radii) = SplitArray(vals);
(Vert[] centers, float[] radii) = SplitArray(vals);
return new(Vert.Min(centers), Mathf.Min(radii));
}
public static (Vert[] centers, double[] radii) SplitArray(params Sphere[] spheres)
public static (Vert[] centers, float[] radii) SplitArray(params Sphere[] spheres)
{
Vert[] centers = new Vert[spheres.Length];
double[] radii = new double[spheres.Length];
float[] radii = new float[spheres.Length];
for (int i = 0; i < spheres.Length; i++)
{
centers[i] = spheres[i].center;
@ -72,10 +72,10 @@ public struct Sphere : ICloneable, IClosest<Vert>, IComparable<Sphere>, ICompara
if (obj == null) return false;
Type type = obj.GetType();
if (type == typeof(Sphere)) return Equals((Sphere)obj);
if (type == typeof(double)) return Equals((double)obj);
if (type == typeof(float)) return Equals((float)obj);
return false;
}
public bool Equals(double other) => Volume == other;
public bool Equals(float other) => Volume == other;
public bool Equals(Sphere other) => center == other.center && radius == other.radius;
public override int GetHashCode() => center.GetHashCode() ^ radius.GetHashCode();
public override string ToString() => ToString((string?)null);
@ -87,7 +87,7 @@ public struct Sphere : ICloneable, IClosest<Vert>, IComparable<Sphere>, ICompara
public object Clone() => new Sphere(center, radius);
public int CompareTo(Sphere sphere) => Volume.CompareTo(sphere.Volume);
public int CompareTo(double volume) => Volume.CompareTo(volume);
public int CompareTo(float volume) => Volume.CompareTo(volume);
public bool Contains(Vert vert) => (center - vert).Magnitude <= radius;
@ -95,24 +95,24 @@ public struct Sphere : ICloneable, IClosest<Vert>, IComparable<Sphere>, ICompara
public static Sphere operator +(Sphere a, Sphere b) => new(a.center + b.center, a.radius + b.radius);
public static Sphere operator +(Sphere a, Vert b) => new(a.center + b, a.radius);
public static Sphere operator +(Sphere a, double b) => new(a.center, a.radius + b);
public static Sphere operator +(Sphere a, float b) => new(a.center, a.radius + b);
public static Sphere operator -(Sphere a, Sphere b) => new(a.center + b.center, a.radius + b.radius);
public static Sphere operator -(Sphere a, Vert b) => new(a.center + b, a.radius);
public static Sphere operator -(Sphere a, double b) => new(a.center, a.radius + b);
public static Sphere operator -(Sphere a, float b) => new(a.center, a.radius + b);
public static Sphere operator *(Sphere a, Sphere b) => new(a.center * b.center, a.radius * b.radius);
public static Sphere operator *(Sphere a, double b) => new(a.center * b, a.radius * b);
public static Sphere operator *(Sphere a, float b) => new(a.center * b, a.radius * b);
public static Sphere operator /(Sphere a, Sphere b) => new(a.center * b.center, a.radius * b.radius);
public static Sphere operator /(Sphere a, double b) => new(a.center * b, a.radius * b);
public static Sphere operator /(Sphere a, float b) => new(a.center * b, a.radius * b);
public static bool operator ==(Sphere a, Sphere b) => a.Equals(b);
public static bool operator !=(Sphere a, Sphere b) => !a.Equals(b);
public static bool operator ==(Sphere a, double b) => a.Equals(b);
public static bool operator !=(Sphere a, double b) => !a.Equals(b);
public static bool operator ==(Sphere a, float b) => a.Equals(b);
public static bool operator !=(Sphere a, float b) => !a.Equals(b);
public static bool operator >(Sphere a, Sphere b) => a.CompareTo(b) > 0;
public static bool operator <(Sphere a, Sphere b) => a.CompareTo(b) < 0;
public static bool operator >(Sphere a, double b) => a.CompareTo(b) > 0;
public static bool operator <(Sphere a, double b) => a.CompareTo(b) < 0;
public static bool operator >(Sphere a, float b) => a.CompareTo(b) > 0;
public static bool operator <(Sphere a, float b) => a.CompareTo(b) < 0;
public static bool operator >=(Sphere a, Sphere b) => a > b || a == b;
public static bool operator <=(Sphere a, Sphere b) => a < b || a == b;
public static bool operator >=(Sphere a, double b) => a > b || a == b;
public static bool operator <=(Sphere a, double b) => a < b || a == b;
public static bool operator >=(Sphere a, float b) => a > b || a == b;
public static bool operator <=(Sphere a, float b) => a < b || a == b;
}

View File

@ -72,9 +72,10 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
private Vert p_a, p_b, p_c;
private Line p_ab, p_bc, p_ca;
public double Area => Mathf.Absolute((A.position.x * B.position.y) + (B.position.x * C.position.y) + (C.position.x * A.position.y) -
((B.position.x * A.position.y) + (C.position.x * B.position.y) + (A.position.x * C.position.y))) * 0.5;
public double Perimeter => AB.Length + BC.Length + CA.Length;
public float Area => (float)Mathf.Absolute((A.position.x * B.position.y) + (B.position.x * C.position.y) +
(C.position.x * A.position.y) - ((B.position.x * A.position.y) + (C.position.x * B.position.y) +
(A.position.x * C.position.y))) * 0.5f;
public float Perimeter => AB.Length + BC.Length + CA.Length;
public Triangle(Vert a, Vert b, Vert c)
{
@ -97,15 +98,15 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
p_bc = bc;
p_ca = ca;
}
public Triangle(double x1, double y1, double x2, double y2, double x3, double y3)
public Triangle(float x1, float y1, float x2, float y2, float x3, float y3)
: this(new Vert(x1, y1), new Vert(x2, y2), new Vert(x3, y3)) { }
public Triangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3,
double z3) : this(new Vert(x1, y1, z1), new Vert(x2, y2, z2), new Vert(x3, y3, z3)) { }
public Triangle(Fill<Double3> fill) : this(fill(0), fill(1), fill(2)) { }
public Triangle(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3,
float z3) : this(new Vert(x1, y1, z1), new Vert(x2, y2, z2), new Vert(x3, y3, z3)) { }
public Triangle(Fill<Float3> fill) : this(fill(0), fill(1), fill(2)) { }
public Triangle(Fill<Int3> fill) : this(fill(0), fill(1), fill(2)) { }
public Triangle(Fill<Vert> fill) : this(fill(0), fill(1), fill(2)) { }
public Triangle(Fill<Line> fill) : this(fill(0), fill(1), fill(2)) { }
public Triangle(Fill<double> fill) : this(fill(0), fill(1), fill(2), fill(3), fill(4), fill(5), fill(6),
public Triangle(Fill<float> fill) : this(fill(0), fill(1), fill(2), fill(3), fill(4), fill(5), fill(6),
fill(7), fill(8)) { }
public Triangle(Fill<int> fill) : this(fill(0), fill(1), fill(2), fill(3), fill(4), fill(5), fill(6),
fill(7), fill(8)) { }
@ -153,7 +154,7 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
new(Vert.Clamp(val.A, min.A, max.A), Vert.Clamp(val.B, min.B, max.B), Vert.Clamp(val.C, min.C, max.C));
public static Triangle Floor(Triangle val) =>
new(Vert.Floor(val.A), Vert.Floor(val.B), Vert.Floor(val.C));
public static Triangle Lerp(Triangle a, Triangle b, double t, bool clamp = true) =>
public static Triangle Lerp(Triangle a, Triangle b, float t, bool clamp = true) =>
new(Vert.Lerp(a.A, b.A, t, clamp), Vert.Lerp(a.B, b.B, t, clamp), Vert.Lerp(a.C, b.C, t, clamp));
public static Triangle Max(params Triangle[] vals)
{
@ -194,9 +195,9 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
return (ab, bc, ca);
}
public static double[] ToDoubleArrayAll(params Triangle[] tris)
public static float[] ToDoubleArrayAll(params Triangle[] tris)
{
double[] vals = new double[tris.Length * 9];
float[] vals = new float[tris.Length * 9];
for (int i = 0; i < tris.Length; i++)
{
int pos = i * 9;
@ -212,7 +213,7 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
}
return vals;
}
public static List<double> ToDoubleListAll(params Triangle[] tris) => new(ToDoubleArrayAll(tris));
public static List<float> ToDoubleListAll(params Triangle[] tris) => new(ToDoubleArrayAll(tris));
public override bool Equals([NotNullWhen(true)] object? obj)
{
@ -240,10 +241,10 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
public Vert[] ToArray() => new Vert[] { A, B, C };
public List<Vert> ToList() => new() { A, B, C };
public double[] ToDoubleArray() => new double[] { A.position.x, A.position.y, A.position.z,
public float[] ToDoubleArray() => new float[] { A.position.x, A.position.y, A.position.z,
B.position.x, B.position.y, B.position.z,
C.position.x, C.position.y, C.position.z };
public List<double> ToDoubleList() => new() { A.position.x, A.position.y, A.position.z,
public List<float> ToDoubleList() => new() { A.position.x, A.position.y, A.position.z,
B.position.x, B.position.y, B.position.z,
C.position.x, C.position.y, C.position.z };
public static Triangle operator +(Triangle a, Triangle b) => new(a.A + b.A, a.B + b.B, a.C + b.C);
@ -253,18 +254,18 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
public static Triangle operator -(Triangle a, Vert b) => new(a.A - b, a.B - b, a.C - b);
public static Triangle operator *(Triangle a, Triangle b) => new(a.A * b.A, a.B * b.B, a.C * b.C);
public static Triangle operator *(Triangle a, Vert b) => new(a.A * b, a.B * b, a.C * b);
public static Triangle operator *(Triangle a, double b) => new(a.A * b, a.B * b, a.C * b);
public static Triangle operator *(Triangle a, float b) => new(a.A * b, a.B * b, a.C * b);
public static Triangle operator /(Triangle a, Triangle b) => new(a.A / b.A, a.B / b.B, a.C / b.C);
public static Triangle operator /(Triangle a, Vert b) => new(a.A / b, a.B / b, a.C / b);
public static Triangle operator /(Triangle a, double b) => new(a.A / b, a.B / b, a.C / b);
public static Triangle operator /(Triangle a, float b) => new(a.A / b, a.B / b, a.C / b);
public static bool operator ==(Triangle a, Triangle b) => a.Equals(b);
public static bool operator !=(Triangle a, Triangle b) => !a.Equals(b);
public static implicit operator Triangle(Fill<Vert> fill) => new(fill);
public static implicit operator Triangle(Fill<Double3> fill) => new(fill);
public static implicit operator Triangle(Fill<Float3> fill) => new(fill);
public static implicit operator Triangle(Fill<Int3> fill) => new(fill);
public static implicit operator Triangle(Fill<Line> fill) => new(fill);
public static implicit operator Triangle(Fill<double> fill) => new(fill);
public static implicit operator Triangle(Fill<float> fill) => new(fill);
public static implicit operator Triangle(Fill<int> fill) => new(fill);
public static explicit operator Triangle(Polygon poly) => new(poly.Lines[0], poly.Lines[1], poly.Lines[2]);
}

View File

@ -1,6 +1,6 @@
namespace Nerd_STF.Mathematics.Geometry;
public struct Vert : ICloneable, IEquatable<Vert>, IGroup<double>
public struct Vert : ICloneable, IEquatable<Vert>, IGroup<float>
{
public static Vert Back => new(0, 0, -1);
public static Vert Down => new(0, -1, 0);
@ -12,51 +12,51 @@ public struct Vert : ICloneable, IEquatable<Vert>, IGroup<double>
public static Vert One => new(1, 1, 1);
public static Vert Zero => new(0, 0, 0);
public double Magnitude => position.Magnitude;
public float Magnitude => position.Magnitude;
public Vert Normalized => new(this / Magnitude);
public Double3 position;
public Float3 position;
public Vert(Double2 pos) : this(pos.x, pos.y, 0) { }
public Vert(Double3 pos) => position = pos;
public Vert(double x, double y) : this(new Double2(x, y)) { }
public Vert(double x, double y, double z) : this(new Double3(x, y, z)) { }
public Vert(Fill<double> fill) : this(new Double3(fill)) { }
public Vert(Fill<int> fill) : this(new Double3(fill)) { }
public Vert(Float2 pos) : this(pos.x, pos.y, 0) { }
public Vert(Float3 pos) => position = pos;
public Vert(float x, float y) : this(new Float2(x, y)) { }
public Vert(float x, float y, float z) : this(new Float3(x, y, z)) { }
public Vert(Fill<float> fill) : this(new Float3(fill)) { }
public Vert(Fill<int> fill) : this(new Float3(fill)) { }
public double this[int index]
public float this[int index]
{
get => position[index];
set => position[index] = value;
}
public static Vert Absolute(Vert val) => new(Double3.Absolute(val.position));
public static Vert Average(params Vert[] vals) => Double3.Average(ToDouble3Array(vals));
public static Vert Ceiling(Vert val) => new(Double3.Ceiling(val.position));
public static Vert Absolute(Vert val) => new(Float3.Absolute(val.position));
public static Vert Average(params Vert[] vals) => Float3.Average(ToDouble3Array(vals));
public static Vert Ceiling(Vert val) => new(Float3.Ceiling(val.position));
public static Vert Clamp(Vert val, Vert min, Vert max) =>
new(Double3.Clamp(val.position, min.position, max.position));
public static Vert ClampMagnitude(Vert val, double minMag, double maxMag) =>
new(Double3.ClampMagnitude(val.position, minMag, maxMag));
new(Float3.Clamp(val.position, min.position, max.position));
public static Vert ClampMagnitude(Vert val, float minMag, float maxMag) =>
new(Float3.ClampMagnitude(val.position, minMag, maxMag));
public static Vert Cross(Vert a, Vert b, bool normalized = false) =>
new(Double3.Cross(a.position, b.position, normalized));
public static double Dot(Vert a, Vert b) => Double3.Dot(a.position, b.position);
public static double Dot(params Vert[] vals) => Double3.Dot(ToDouble3Array(vals));
public static Vert Floor(Vert val) => new(Double3.Floor(val.position));
public static Vert Lerp(Vert a, Vert b, double t, bool clamp = true) =>
new(Double3.Lerp(a.position, b.position, t, clamp));
new(Float3.Cross(a.position, b.position, normalized));
public static float Dot(Vert a, Vert b) => Float3.Dot(a.position, b.position);
public static float Dot(params Vert[] vals) => Float3.Dot(ToDouble3Array(vals));
public static Vert Floor(Vert val) => new(Float3.Floor(val.position));
public static Vert Lerp(Vert a, Vert b, float t, bool clamp = true) =>
new(Float3.Lerp(a.position, b.position, t, clamp));
public static Vert Median(params Vert[] vals) =>
Double3.Median(ToDouble3Array(vals));
Float3.Median(ToDouble3Array(vals));
public static Vert Max(params Vert[] vals) =>
Double3.Max(ToDouble3Array(vals));
Float3.Max(ToDouble3Array(vals));
public static Vert Min(params Vert[] vals) =>
Double3.Min(ToDouble3Array(vals));
public static Double3[] ToDouble3Array(params Vert[] vals)
Float3.Min(ToDouble3Array(vals));
public static Float3[] ToDouble3Array(params Vert[] vals)
{
Double3[] doubles = new Double3[vals.Length];
Float3[] doubles = new Float3[vals.Length];
for (int i = 0; i < vals.Length; i++) doubles[i] = vals[i].position;
return doubles;
}
public static List<Double3> ToDouble3List(params Vert[] vals) => ToDouble3Array(vals).ToList();
public static List<Float3> ToDouble3List(params Vert[] vals) => ToDouble3Array(vals).ToList();
public override bool Equals([NotNullWhen(true)] object? obj)
{
@ -72,27 +72,27 @@ public struct Vert : ICloneable, IEquatable<Vert>, IGroup<double>
public object Clone() => new Vert(position);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<double> GetEnumerator() => position.GetEnumerator();
public IEnumerator<float> GetEnumerator() => position.GetEnumerator();
public double[] ToArray() => position.ToArray();
public List<double> ToList() => position.ToList();
public float[] ToArray() => position.ToArray();
public List<float> ToList() => position.ToList();
public static Vert operator +(Vert a, Vert b) => new(a.position + b.position);
public static Vert operator -(Vert d) => new(-d.position);
public static Vert operator -(Vert a, Vert b) => new(a.position - b.position);
public static Vert operator *(Vert a, Vert b) => new(a.position * b.position);
public static Vert operator *(Vert a, double b) => new(a.position * b);
public static Vert operator *(Vert a, float b) => new(a.position * b);
public static Vert operator /(Vert a, Vert b) => new(a.position / b.position);
public static Vert operator /(Vert a, double b) => new(a.position / b);
public static Vert operator /(Vert a, float b) => new(a.position / b);
public static bool operator ==(Vert a, Vert b) => a.Equals(b);
public static bool operator !=(Vert a, Vert b) => !a.Equals(b);
public static implicit operator Vert(Double2 val) => new(val);
public static implicit operator Vert(Double3 val) => new(val);
public static explicit operator Vert(Double4 val) => new(val.XYZ);
public static implicit operator Vert(Float2 val) => new(val);
public static implicit operator Vert(Float3 val) => new(val);
public static explicit operator Vert(Float4 val) => new(val.XYZ);
public static implicit operator Vert(Int2 val) => new(val);
public static implicit operator Vert(Int3 val) => new(val);
public static explicit operator Vert(Int4 val) => new(val.XYZ);
public static implicit operator Vert(Fill<double> fill) => new(fill);
public static implicit operator Vert(Fill<float> fill) => new(fill);
public static implicit operator Vert(Fill<int> fill) => new(fill);
}

View File

@ -10,8 +10,8 @@ public struct Int2 : ICloneable, IComparable<Int2>, IEquatable<Int2>, IGroup<int
public static Int2 One => new(1, 1);
public static Int2 Zero => new(0, 0);
public double Magnitude => Mathf.Sqrt(x * x + y * y);
public Int2 Normalized => (Int2)((Double2)this / Magnitude);
public float Magnitude => Mathf.Sqrt(x * x + y * y);
public Int2 Normalized => (Int2)((Float2)this / Magnitude);
public int x, y;
@ -58,7 +58,7 @@ public struct Int2 : ICloneable, IComparable<Int2>, IEquatable<Int2>, IGroup<int
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
double mag = val.Magnitude;
float mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
@ -84,7 +84,7 @@ public struct Int2 : ICloneable, IComparable<Int2>, IEquatable<Int2>, IGroup<int
}
return x + y;
}
public static Int2 Lerp(Int2 a, Int2 b, double t, bool clamp = true) =>
public static Int2 Lerp(Int2 a, Int2 b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp));
public static Int2 Median(params Int2[] vals)
{
@ -168,9 +168,9 @@ public struct Int2 : ICloneable, IComparable<Int2>, IEquatable<Int2>, IGroup<int
public static bool operator >=(Int2 a, Int2 b) => a == b || a > b;
public static bool operator <=(Int2 a, Int2 b) => a == b || a < b;
public static explicit operator Int2(Double2 val) => new((int)val.x, (int)val.y);
public static explicit operator Int2(Double3 val) => new((int)val.x, (int)val.y);
public static explicit operator Int2(Double4 val) => new((int)val.x, (int)val.y);
public static explicit operator Int2(Float2 val) => new((int)val.x, (int)val.y);
public static explicit operator Int2(Float3 val) => new((int)val.x, (int)val.y);
public static explicit operator Int2(Float4 val) => new((int)val.x, (int)val.y);
public static explicit operator Int2(Int3 val) => new(val.x, val.y);
public static explicit operator Int2(Int4 val) => new(val.x, val.y);
public static explicit operator Int2(Vert val) => new((int)val.position.x, (int)val.position.y);

View File

@ -12,8 +12,8 @@ public struct Int3 : ICloneable, IComparable<Int3>, IEquatable<Int3>, IGroup<int
public static Int3 One => new(1, 1, 1);
public static Int3 Zero => new(0, 0, 0);
public double Magnitude => Mathf.Sqrt(x * x + y * y + z * z);
public Int3 Normalized => (Int3)((Double3)this / Magnitude);
public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z);
public Int3 Normalized => (Int3)((Float3)this / Magnitude);
public Int2 XY => new(x, y);
public Int2 XZ => new(x, z);
@ -72,7 +72,7 @@ public struct Int3 : ICloneable, IComparable<Int3>, IEquatable<Int3>, IGroup<int
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
double mag = val.Magnitude;
float mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
@ -104,7 +104,7 @@ public struct Int3 : ICloneable, IComparable<Int3>, IEquatable<Int3>, IGroup<int
}
return x + y + z;
}
public static Int3 Lerp(Int3 a, Int3 b, double t, bool clamp = true) =>
public static Int3 Lerp(Int3 a, Int3 b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp));
public static Int3 Median(params Int3[] vals)
{
@ -186,9 +186,9 @@ public struct Int3 : ICloneable, IComparable<Int3>, IEquatable<Int3>, IGroup<int
public static bool operator >=(Int3 a, Int3 b) => a == b || a > b;
public static bool operator <=(Int3 a, Int3 b) => a == b || a < b;
public static explicit operator Int3(Double2 val) => new((int)val.x, (int)val.y, 0);
public static explicit operator Int3(Double3 val) => new((int)val.x, (int)val.y, (int)val.z);
public static explicit operator Int3(Double4 val) => new((int)val.x, (int)val.y, (int)val.z);
public static explicit operator Int3(Float2 val) => new((int)val.x, (int)val.y, 0);
public static explicit operator Int3(Float3 val) => new((int)val.x, (int)val.y, (int)val.z);
public static explicit operator Int3(Float4 val) => new((int)val.x, (int)val.y, (int)val.z);
public static implicit operator Int3(Int2 val) => new(val.x, val.y, 0);
public static explicit operator Int3(Int4 val) => new(val.x, val.y, val.z);
public static explicit operator Int3(Vert val) => new((int)val.position.x, (int)val.position.y,

View File

@ -14,8 +14,8 @@ public struct Int4 : ICloneable, IComparable<Int4>, IEquatable<Int4>, IGroup<int
public static Int4 One => new(1, 1, 1, 1);
public static Int4 Zero => new(0, 0, 0, 0);
public double Magnitude => Mathf.Sqrt(x * x + y * y + z * z + w * w);
public Int4 Normalized => (Int4)((Double4)this / Magnitude);
public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z + w * w);
public Int4 Normalized => (Int4)((Float4)this / Magnitude);
public Int2 XY => new(x, y);
public Int2 XZ => new(x, z);
@ -90,7 +90,7 @@ public struct Int4 : ICloneable, IComparable<Int4>, IEquatable<Int4>, IGroup<int
{
if (maxMag < minMag) throw new ArgumentOutOfRangeException(nameof(maxMag),
nameof(maxMag) + " must be greater than or equal to " + nameof(minMag));
double mag = val.Magnitude;
float mag = val.Magnitude;
if (mag >= minMag && mag <= maxMag) return val;
val = val.Normalized;
if (mag < minMag) val *= minMag;
@ -116,7 +116,7 @@ public struct Int4 : ICloneable, IComparable<Int4>, IEquatable<Int4>, IGroup<int
}
return x + y + z;
}
public static Int4 Lerp(Int4 a, Int4 b, double t, bool clamp = true) =>
public static Int4 Lerp(Int4 a, Int4 b, float t, bool clamp = true) =>
new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp),
Mathf.Lerp(a.w, b.w, t, clamp));
public static Int4 Median(params Int4[] vals)
@ -205,9 +205,9 @@ public struct Int4 : ICloneable, IComparable<Int4>, IEquatable<Int4>, IGroup<int
public static bool operator >=(Int4 a, Int4 b) => a == b || a > b;
public static bool operator <=(Int4 a, Int4 b) => a == b || a < b;
public static explicit operator Int4(Double2 val) => new((int)val.x, (int)val.y, 0, 0);
public static explicit operator Int4(Double3 val) => new((int)val.x, (int)val.y, (int)val.z, 0);
public static explicit operator Int4(Double4 val) => new((int)val.x, (int)val.y, (int)val.z, (int)val.w);
public static explicit operator Int4(Float2 val) => new((int)val.x, (int)val.y, 0, 0);
public static explicit operator Int4(Float3 val) => new((int)val.x, (int)val.y, (int)val.z, 0);
public static explicit operator Int4(Float4 val) => new((int)val.x, (int)val.y, (int)val.z, (int)val.w);
public static implicit operator Int4(Int2 val) => new(val.x, val.y, 0, 0);
public static implicit operator Int4(Int3 val) => new(val.x, val.y, val.z, 0);
public static explicit operator Int4(Vert val) => new((int)val.position.x, (int)val.position.y,

View File

@ -2,42 +2,42 @@
public static class Mathf
{
public const double RadToDeg = 0.0174532925199; // Pi / 180
public const double E = 2.71828182846;
public const double GoldenRatio = 1.61803398875; // (1 + Sqrt(5)) / 2
public const double HalfPi = 1.57079632679; // Pi / 2
public const double Pi = 3.14159265359;
public const double DegToRad = 57.2957795131; // 180 / Pi
public const double Tau = 6.28318530718; // 2 * Pi
public const float RadToDeg = 0.0174532925199f; // Pi / 180
public const float E = 2.71828182846f;
public const float GoldenRatio = 1.61803398875f; // (1 + Sqrt(5)) / 2
public const float HalfPi = 1.57079632679f; // Pi / 2
public const float Pi = 3.14159265359f;
public const float DegToRad = 57.2957795131f; // 180 / Pi
public const float Tau = 6.28318530718f; // 2 * Pi
public static double Absolute(double val) => val < 0 ? -val : val;
public static float Absolute(float val) => val < 0 ? -val : val;
public static int Absolute(int val) => val < 0 ? -val : val;
public static double ArcCos(double value) => -ArcSin(value) + HalfPi;
public static float ArcCos(float value) => -ArcSin(value) + HalfPi;
public static double ArcCot(double value) => ArcCos(value / Sqrt(1 + value * value));
public static float ArcCot(float value) => ArcCos(value / Sqrt(1 + value * value));
public static double ArcCsc(double value) => ArcSin(1 / value);
public static float ArcCsc(float value) => ArcSin(1 / value);
public static double ArcSec(double value) => ArcCos(1 / value);
public static float ArcSec(float value) => ArcCos(1 / value);
// Maybe one day I'll have a polynomial for this, but the RMSE for an order 10 polynomial is only 0.00876.
public static double ArcSin(double value) => Math.Asin(value);
public static float ArcSin(float value) => (float)Math.Asin(value);
public static double ArcTan(double value) => ArcSin(value / Sqrt(1 + value * value));
public static float ArcTan(float value) => ArcSin(value / Sqrt(1 + value * value));
public static double Average(Equation equ, double min, double max, double step = Calculus.DefaultStep)
public static float Average(Equation equ, float min, float max, float step = Calculus.DefaultStep)
{
List<double> vals = new();
for (double x = min; x <= max; x += step) vals.Add(equ(x));
List<float> vals = new();
for (float x = min; x <= max; x += step) vals.Add(equ(x));
return Average(vals.ToArray());
}
public static double Average(params double[] vals) => Sum(vals) / vals.Length;
public static float Average(params float[] vals) => Sum(vals) / vals.Length;
public static int Average(params int[] vals) => Sum(vals) / vals.Length;
public static int Ceiling(double val) => (int)(val + (1 - (val % 1)));
public static int Ceiling(float val) => (int)(val + (1 - (val % 1)));
public static double Clamp(double val, double min, double max)
public static float Clamp(float val, float min, float max)
{
if (max < min) throw new ArgumentOutOfRangeException(nameof(max),
nameof(max) + " must be greater than or equal to " + nameof(min));
@ -54,15 +54,15 @@ public static class Mathf
return val;
}
public static double Cos(double radians) => Sin(radians + HalfPi);
public static float Cos(float radians) => Sin(radians + HalfPi);
public static double Cot(double radians) => Cos(radians) / Sin(radians);
public static float Cot(float radians) => Cos(radians) / Sin(radians);
public static double Csc(double radians) => 1 / Sin(radians);
public static float Csc(float radians) => 1 / Sin(radians);
public static double Divide(double val, params double[] dividends)
public static float Divide(float val, params float[] dividends)
{
foreach (double d in dividends) val /= d;
foreach (float d in dividends) val /= d;
return val;
}
public static int Divide(int val, params int[] dividends)
@ -79,53 +79,53 @@ public static class Mathf
return val;
}
public static int Floor(double val) => (int)(val - (val % 1));
public static int Floor(float val) => (int)(val - (val % 1));
public static Dictionary<double, double> GetValues(Equation equ, double min, double max,
double step = Calculus.DefaultStep)
public static Dictionary<float, float> GetValues(Equation equ, float min, float max,
float step = Calculus.DefaultStep)
{
Dictionary<double, double> vals = new();
for (double x = min; x <= max; x += step) vals.Add(x, equ(x));
Dictionary<float, float> vals = new();
for (float x = min; x <= max; x += step) vals.Add(x, equ(x));
return vals;
}
public static double Lerp(double a, double b, double t, bool clamp = true)
public static float Lerp(float a, float b, float t, bool clamp = true)
{
double v = a + t * (b - a);
float v = a + t * (b - a);
if (clamp) v = Clamp(v, a, b);
return v;
}
public static int Lerp(int a, int b, double value, bool clamp = true) => Floor(Lerp(a, b, value, clamp));
public static int Lerp(int a, int b, float value, bool clamp = true) => Floor(Lerp(a, b, value, clamp));
public static Equation MakeEquation(Dictionary<double, double> vals) => (x) =>
public static Equation MakeEquation(Dictionary<float, float> vals) => (x) =>
{
double min = -1, max = -1;
foreach (KeyValuePair<double, double> val in vals)
float min = -1, max = -1;
foreach (KeyValuePair<float, float> val in vals)
{
if (val.Key <= x) min = val.Key;
if (val.Key >= x) max = val.Key;
if (min != -1 && max != -1) break;
}
double per = x % (max - min);
float per = x % (max - min);
return Lerp(min, max, per);
};
public static double Max(Equation equ, double min, double max, double step = Calculus.DefaultStep)
public static float Max(Equation equ, float min, float max, float step = Calculus.DefaultStep)
{
double Y = equ(min);
for (double x = min; x <= max; x += step)
float Y = equ(min);
for (float x = min; x <= max; x += step)
{
double val = equ(x);
float val = equ(x);
Y = val > Y ? val : Y;
}
return Y;
}
public static double Max(params double[] vals)
public static float Max(params float[] vals)
{
if (vals.Length < 1) return 0;
double val = vals[0];
foreach (double d in vals) val = d > val ? d : val;
float val = vals[0];
foreach (float d in vals) val = d > val ? d : val;
return val;
}
public static int Max(params int[] vals)
@ -136,29 +136,29 @@ public static class Mathf
return val;
}
public static double Median(params double[] vals)
public static float Median(params float[] vals)
{
double index = Average(0, vals.Length - 1);
double valA = vals[Floor(index)], valB = vals[Ceiling(index)];
float index = Average(0, vals.Length - 1);
float valA = vals[Floor(index)], valB = vals[Ceiling(index)];
return Average(valA, valB);
}
public static int Median(params int[] vals) => vals[Floor(Average(0, vals.Length - 1))];
public static double Min(Equation equ, double min, double max, double step = Calculus.DefaultStep)
public static float Min(Equation equ, float min, float max, float step = Calculus.DefaultStep)
{
double Y = equ(min);
for (double x = min; x <= max; x += step)
float Y = equ(min);
for (float x = min; x <= max; x += step)
{
double val = equ(x);
float val = equ(x);
Y = val < Y ? val : Y;
}
return Y;
}
public static double Min(params double[] vals)
public static float Min(params float[] vals)
{
if (vals.Length < 1) return 0;
double val = vals[0];
foreach (double d in vals) val = d < val ? d : val;
float val = vals[0];
foreach (float d in vals) val = d < val ? d : val;
return val;
}
public static int Min(params int[] vals)
@ -169,11 +169,11 @@ public static class Mathf
return val;
}
public static double Multiply(params double[] vals)
public static float Multiply(params float[] vals)
{
if (vals.Length < 1) return 0;
double val = 1;
foreach (double d in vals) val *= d;
float val = 1;
foreach (float d in vals) val *= d;
return val;
}
public static int Multiply(params int[] vals)
@ -184,7 +184,7 @@ public static class Mathf
return val;
}
public static double Power(double num, double pow) => Math.Pow(num, pow);
public static float Power(float num, float pow) => (float)Math.Pow(num, pow);
public static int Power(int num, int pow)
{
if (pow < 0) return 0;
@ -193,28 +193,28 @@ public static class Mathf
return val;
}
public static double Root(double value, double index) => Math.Exp(index * Math.Log(value));
public static float Root(float value, float index) => (float)Math.Exp(index * Math.Log(value));
public static double Round(double num) => num % 1 >= 0.5 ? Ceiling(num) : Floor(num);
public static double Round(double num, double nearest) => nearest * Round(num / nearest);
public static int RoundInt(double num) => (int)Round(num);
public static float Round(float num) => num % 1 >= 0.5 ? Ceiling(num) : Floor(num);
public static float Round(float num, float nearest) => nearest * Round(num / nearest);
public static int RoundInt(float num) => (int)Round(num);
public static double Sec(double radians) => 1 / Cos(radians);
public static float Sec(float radians) => 1 / Cos(radians);
public static double Sin(double radians)
public static float Sin(float radians)
{
// Really close polynomial to sin(x) (when modded by 2pi). RMSE of 0.000003833
const double a = 0.000013028,
b = 0.999677,
c = 0.00174164,
d = -0.170587,
e = 0.0046494,
f = 0.00508955,
g = 0.00140205,
h = -0.000577413,
i = 0.0000613134,
j = -0.00000216852;
double x = radians % Tau;
const float a = 0.000013028f,
b = 0.999677f,
c = 0.00174164f,
d = -0.170587f,
e = 0.0046494f,
f = 0.00508955f,
g = 0.00140205f,
h = -0.000577413f,
i = 0.0000613134f,
j = -0.00000216852f;
float x = radians % Tau;
return
a + (b * x) + (c * x * x) + (d * x * x * x) + (e * x * x * x * x) + (f * x * x * x * x * x)
@ -222,11 +222,11 @@ public static class Mathf
+ (j * x * x * x * x * x * x * x * x * x);
}
public static double Sqrt(double value) => Root(value, 2);
public static float Sqrt(float value) => Root(value, 2);
public static double Subtract(double num, params double[] vals)
public static float Subtract(float num, params float[] vals)
{
foreach (double d in vals) num -= d;
foreach (float d in vals) num -= d;
return num;
}
public static int Subtract(int num, params int[] vals)
@ -235,10 +235,10 @@ public static class Mathf
return num;
}
public static double Sum(params double[] vals)
public static float Sum(params float[] vals)
{
double val = 0;
foreach (double d in vals) val += d;
float val = 0;
foreach (float d in vals) val += d;
return val;
}
public static int Sum(params int[] vals)
@ -248,5 +248,5 @@ public static class Mathf
return val;
}
public static double Tan(double radians) => Sin(radians) / Cos(radians);
public static float Tan(float radians) => Sin(radians) / Cos(radians);
}