commit
b322a2d811
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# Visual Studio stuff
|
||||
*.sln
|
||||
*.csproj
|
||||
|
||||
/Nerd_STF/.vs
|
||||
/Nerd_STF/Nerd_STF/obj
|
||||
/Nerd_STF/Nerd_STF/bin/Debug
|
||||
/Nerd_STF/Nerd_STF/bin/Release/net6.0/Nerd_STF.deps.json
|
||||
/Nerd_STF/Nerd_STF/bin/Release/net6.0/Nerd_STF.dll
|
||||
/Nerd_STF/Nerd_STF/bin/Release/net6.0/Nerd_STF.pdb
|
||||
BIN
Nerd_STF.dll
BIN
Nerd_STF.dll
Binary file not shown.
4
Nerd_STF/Nerd_STF/Fill.cs
Normal file
4
Nerd_STF/Nerd_STF/Fill.cs
Normal file
@ -0,0 +1,4 @@
|
||||
namespace Nerd_STF
|
||||
{
|
||||
public delegate T Fill<T>(int index);
|
||||
}
|
||||
8
Nerd_STF/Nerd_STF/IGroup.cs
Normal file
8
Nerd_STF/Nerd_STF/IGroup.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Nerd_STF
|
||||
{
|
||||
public interface IGroup<T> : IEnumerable<T>
|
||||
{
|
||||
public T[] ToArray();
|
||||
public List<T> ToList();
|
||||
}
|
||||
}
|
||||
25
Nerd_STF/Nerd_STF/LogMessage.cs
Normal file
25
Nerd_STF/Nerd_STF/LogMessage.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nerd_STF
|
||||
{
|
||||
public struct LogMessage
|
||||
{
|
||||
public string Message;
|
||||
public LogSeverity Severity;
|
||||
public DateTime Timestamp;
|
||||
|
||||
public LogMessage() : this("", LogSeverity.Information, null) { }
|
||||
public LogMessage(string msg, LogSeverity severity, DateTime? time = null)
|
||||
{
|
||||
Message = msg;
|
||||
Severity = severity;
|
||||
Timestamp = time ?? DateTime.Now;
|
||||
}
|
||||
|
||||
public override string ToString() => Timestamp + " " + Severity.ToString().ToUpper() + ": " + Message;
|
||||
}
|
||||
}
|
||||
11
Nerd_STF/Nerd_STF/LogSeverity.cs
Normal file
11
Nerd_STF/Nerd_STF/LogSeverity.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Nerd_STF
|
||||
{
|
||||
public enum LogSeverity
|
||||
{
|
||||
Debug = 1,
|
||||
Information = 2,
|
||||
Warning = 4,
|
||||
Error = 8,
|
||||
Fatal = 16,
|
||||
}
|
||||
}
|
||||
72
Nerd_STF/Nerd_STF/Logger.cs
Normal file
72
Nerd_STF/Nerd_STF/Logger.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Nerd_STF
|
||||
{
|
||||
public class Logger
|
||||
{
|
||||
public event Action<LogMessage> OnMessageRecieved = DefaultLogHandler;
|
||||
|
||||
public LogMessage[] Cache => msgs.ToArray();
|
||||
public int CacheSize = 64;
|
||||
public List<LogSeverity> IncludeSeverities = new()
|
||||
{
|
||||
LogSeverity.Warning,
|
||||
LogSeverity.Error,
|
||||
LogSeverity.Fatal,
|
||||
};
|
||||
public Stream? LogStream;
|
||||
public int WriteSize;
|
||||
|
||||
private readonly List<LogMessage> msgs;
|
||||
private readonly List<string> writeCache;
|
||||
|
||||
public Logger(Stream? logStream = null, int cacheSize = 64, int writeSize = 1)
|
||||
{
|
||||
CacheSize = cacheSize;
|
||||
LogStream = logStream;
|
||||
WriteSize = writeSize;
|
||||
|
||||
msgs = new(CacheSize);
|
||||
writeCache = new();
|
||||
}
|
||||
|
||||
public void Send(LogMessage msg)
|
||||
{
|
||||
if (!IncludeSeverities.Contains(msg.Severity)) return;
|
||||
|
||||
msgs.Insert(0, msg);
|
||||
writeCache.Add(msg.ToString());
|
||||
while (msgs.Count > CacheSize) msgs.RemoveAt(CacheSize);
|
||||
OnMessageRecieved(msg);
|
||||
|
||||
if (writeCache.Count >= WriteSize && LogStream != null)
|
||||
{
|
||||
string s = "";
|
||||
foreach (string cache in writeCache) s += cache + "\n" + (cache.Contains('\n') ? "\n" : "");
|
||||
LogStream.Write(Encoding.Default.GetBytes(s));
|
||||
LogStream.Flush();
|
||||
writeCache.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DefaultLogHandler(LogMessage msg)
|
||||
{
|
||||
ConsoleColor color = msg.Severity switch
|
||||
{
|
||||
LogSeverity.Debug => ConsoleColor.DarkGray,
|
||||
LogSeverity.Information => ConsoleColor.White,
|
||||
LogSeverity.Warning => ConsoleColor.DarkYellow,
|
||||
LogSeverity.Error => ConsoleColor.Red,
|
||||
LogSeverity.Fatal => ConsoleColor.DarkRed,
|
||||
_ => throw new Exception("Unknown log severity " + msg.Severity),
|
||||
};
|
||||
|
||||
ConsoleColor originalCol = Console.ForegroundColor;
|
||||
|
||||
Console.ForegroundColor = color;
|
||||
Console.WriteLine(msg.ToString());
|
||||
|
||||
Console.ForegroundColor = originalCol;
|
||||
}
|
||||
}
|
||||
}
|
||||
190
Nerd_STF/Nerd_STF/Mathematics/Double2.cs
Normal file
190
Nerd_STF/Nerd_STF/Mathematics/Double2.cs
Normal file
@ -0,0 +1,190 @@
|
||||
using Nerd_STF.Mathematics.Geometry;
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
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)
|
||||
{
|
||||
double magA = Magnitude, magB = other.Magnitude;
|
||||
return magA == magB ? 0 : magA > magB ? 1 : -1;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
211
Nerd_STF/Nerd_STF/Mathematics/Double3.cs
Normal file
211
Nerd_STF/Nerd_STF/Mathematics/Double3.cs
Normal file
@ -0,0 +1,211 @@
|
||||
using Nerd_STF.Mathematics.Geometry;
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
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)
|
||||
{
|
||||
double magA = Magnitude, magB = other.Magnitude;
|
||||
return magA == magB ? 0 : magA > magB ? 1 : -1;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
227
Nerd_STF/Nerd_STF/Mathematics/Double4.cs
Normal file
227
Nerd_STF/Nerd_STF/Mathematics/Double4.cs
Normal file
@ -0,0 +1,227 @@
|
||||
using Nerd_STF.Mathematics.Geometry;
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
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)
|
||||
{
|
||||
double magA = Magnitude, magB = other.Magnitude;
|
||||
return magA == magB ? 0 : magA > magB ? 1 : -1;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
13
Nerd_STF/Nerd_STF/Mathematics/Geometry/ITriangulatable.cs
Normal file
13
Nerd_STF/Nerd_STF/Mathematics/Geometry/ITriangulatable.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nerd_STF.Mathematics.Geometry
|
||||
{
|
||||
public interface ITriangulatable
|
||||
{
|
||||
public Triangle[] Triangulate();
|
||||
}
|
||||
}
|
||||
149
Nerd_STF/Nerd_STF/Mathematics/Geometry/Line.cs
Normal file
149
Nerd_STF/Nerd_STF/Mathematics/Geometry/Line.cs
Normal file
@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nerd_STF.Mathematics.Geometry
|
||||
{
|
||||
public struct Line : ICloneable, IEquatable<Line>, IGroup<Vert>
|
||||
{
|
||||
public static Line Back => new(Vert.Zero, Vert.Back);
|
||||
public static Line Down => new(Vert.Zero, Vert.Down);
|
||||
public static Line Forward => new(Vert.Zero, Vert.Forward);
|
||||
public static Line Left => new(Vert.Zero, Vert.Left);
|
||||
public static Line Right => new(Vert.Zero, Vert.Right);
|
||||
public static Line Up => new(Vert.Zero, Vert.Up);
|
||||
|
||||
public static Line One => new(Vert.Zero, Vert.One);
|
||||
public static Line Zero => new(Vert.Zero, Vert.Zero);
|
||||
|
||||
public double Length => (end - start).Magnitude;
|
||||
|
||||
public Vert start, end;
|
||||
|
||||
public Line(Vert start, Vert end)
|
||||
{
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
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)
|
||||
: 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<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<int> fill) : this(new(fill(0), fill(1), fill(2)), new(fill(3), fill(4), fill(5))) { }
|
||||
|
||||
public Vert this[int index]
|
||||
{
|
||||
get => index switch
|
||||
{
|
||||
0 => start,
|
||||
1 => end,
|
||||
_ => throw new IndexOutOfRangeException(nameof(index)),
|
||||
};
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
start = value;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
end = value;
|
||||
break;
|
||||
|
||||
default: throw new IndexOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Line Absolute(Line val) => new(Vert.Absolute(val.start), Vert.Absolute(val.end));
|
||||
public static Line Average(params Line[] vals)
|
||||
{
|
||||
(Vert[] starts, Vert[] ends) = SplitArray(vals);
|
||||
return new(Vert.Average(starts), Vert.Average(ends));
|
||||
}
|
||||
public static Line Ceiling(Line val) => new(Vert.Ceiling(val.start), Vert.Ceiling(val.end));
|
||||
public static Line Clamp(Line val, Line min, Line max) =>
|
||||
new(Vert.Clamp(val.start, min.start, max.start), Vert.Clamp(val.end, min.end, max.end));
|
||||
public static Line Floor(Line val) => new(Vert.Floor(val.start), Vert.Floor(val.end));
|
||||
public static Line Lerp(Line a, Line b, double t, bool clamp = true) =>
|
||||
new(Vert.Lerp(a.start, b.start, t, clamp), Vert.Lerp(a.end, b.end, t, clamp));
|
||||
public static Line Median(params Line[] vals)
|
||||
{
|
||||
(Vert[] starts, Vert[] ends) = SplitArray(vals);
|
||||
return new(Vert.Median(starts), Vert.Median(ends));
|
||||
}
|
||||
public static Line Max(params Line[] vals)
|
||||
{
|
||||
(Vert[] starts, Vert[] ends) = SplitArray(vals);
|
||||
return new(Vert.Max(starts), Vert.Max(ends));
|
||||
}
|
||||
public static Line Min(params Line[] vals)
|
||||
{
|
||||
(Vert[] starts, Vert[] ends) = SplitArray(vals);
|
||||
return new(Vert.Min(starts), Vert.Min(ends));
|
||||
}
|
||||
|
||||
public static (Vert[] starts, Vert[] ends) SplitArray(params Line[] lines)
|
||||
{
|
||||
Vert[] starts = new Vert[lines.Length], ends = new Vert[lines.Length];
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
starts[i] = lines[i].start;
|
||||
ends[i] = lines[i].end;
|
||||
}
|
||||
return (starts, ends);
|
||||
}
|
||||
|
||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != typeof(Line)) return false;
|
||||
return Equals((Line)obj);
|
||||
}
|
||||
public bool Equals(Line other) => start == other.start && end == other.end;
|
||||
public override int GetHashCode() => start.GetHashCode() ^ end.GetHashCode();
|
||||
public override string ToString() => ToString((string?)null);
|
||||
public string ToString(string? provider) =>
|
||||
"A: " + start.ToString(provider) + " B: " + end.ToString(provider);
|
||||
public string ToString(IFormatProvider provider) =>
|
||||
"A: " + start.ToString(provider) + " B: " + end.ToString(provider);
|
||||
|
||||
public object Clone() => new Line(start, end);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
public IEnumerator<Vert> GetEnumerator()
|
||||
{
|
||||
yield return start;
|
||||
yield return end;
|
||||
}
|
||||
|
||||
public Vert[] ToArray() => new Vert[] { start, end };
|
||||
public List<Vert> ToList() => new() { start, end };
|
||||
|
||||
public static Line operator +(Line a, Line b) => new(a.start + b.start, a.end + b.end);
|
||||
public static Line operator +(Line a, Vert b) => new(a.start + b, a.end + b);
|
||||
public static Line operator -(Line a, Line b) => new(a.start - b.start, a.end - b.end);
|
||||
public static Line operator -(Line a, Vert b) => new(a.start - b, a.end - b);
|
||||
public static Line operator *(Line a, Line b) => new(a.start * b.start, a.end * b.end);
|
||||
public static Line operator *(Line a, Vert b) => new(a.start * b, a.end * b);
|
||||
public static Line operator *(Line a, double b) => new(a.start * b, a.end * b);
|
||||
public static Line operator /(Line a, Line b) => new(a.start / b.start, a.end / b.end);
|
||||
public static Line operator /(Line a, Vert b) => new(a.start / b, a.end / b);
|
||||
public static Line operator /(Line a, double b) => new(a.start / b, a.end / 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 implicit operator Line(Fill<Vert> fill) => new(fill);
|
||||
public static implicit operator Line(Fill<Double3> 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<int> fill) => new(fill);
|
||||
}
|
||||
}
|
||||
243
Nerd_STF/Nerd_STF/Mathematics/Geometry/Triangle.cs
Normal file
243
Nerd_STF/Nerd_STF/Mathematics/Geometry/Triangle.cs
Normal file
@ -0,0 +1,243 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Nerd_STF.Mathematics.Geometry
|
||||
{
|
||||
public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
|
||||
{
|
||||
public Vert A
|
||||
{
|
||||
get => p_a;
|
||||
set
|
||||
{
|
||||
p_a = value;
|
||||
p_l1 = new(value, p_b);
|
||||
p_l3 = new(p_c, value);
|
||||
}
|
||||
}
|
||||
public Vert B
|
||||
{
|
||||
get => p_b;
|
||||
set
|
||||
{
|
||||
p_b = value;
|
||||
p_l1 = new(p_a, value);
|
||||
p_l2 = new(value, p_c);
|
||||
}
|
||||
}
|
||||
public Vert C
|
||||
{
|
||||
get => p_c;
|
||||
set
|
||||
{
|
||||
p_c = value;
|
||||
p_l2 = new(p_b, value);
|
||||
p_l3 = new(value, p_a);
|
||||
}
|
||||
}
|
||||
public Line L1
|
||||
{
|
||||
get => p_l1;
|
||||
set
|
||||
{
|
||||
p_a = value.start;
|
||||
p_b = value.end;
|
||||
p_l2 = new(value.end, p_c);
|
||||
p_l3 = new(p_c, value.start);
|
||||
}
|
||||
}
|
||||
public Line L2
|
||||
{
|
||||
get => p_l2;
|
||||
set
|
||||
{
|
||||
p_b = value.start;
|
||||
p_c = value.end;
|
||||
p_l1 = new(p_a, value.start);
|
||||
p_l3 = new(value.end, p_a);
|
||||
}
|
||||
}
|
||||
public Line L3
|
||||
{
|
||||
get => p_l3;
|
||||
set
|
||||
{
|
||||
p_a = value.end;
|
||||
p_c = value.start;
|
||||
p_l1 = new(value.end, p_b);
|
||||
p_l2 = new(p_b, value.start);
|
||||
}
|
||||
}
|
||||
|
||||
private Vert p_a, p_b, p_c;
|
||||
private Line p_l1, p_l2, p_l3;
|
||||
|
||||
public Triangle(Vert a, Vert b, Vert c)
|
||||
{
|
||||
p_a = a;
|
||||
p_b = b;
|
||||
p_c = c;
|
||||
p_l1 = new(a, b);
|
||||
p_l2 = new(b, c);
|
||||
p_l3 = new(c, a);
|
||||
}
|
||||
public Triangle(Line l1, Line l2, Line l3)
|
||||
{
|
||||
if (l1.start != l3.end && l1.end != l2.start && l2.end != l3.start)
|
||||
throw new ArgumentException("Lines are not connected.");
|
||||
|
||||
p_a = l1.start;
|
||||
p_b = l2.start;
|
||||
p_c = l3.start;
|
||||
p_l1 = l1;
|
||||
p_l2 = l2;
|
||||
p_l3 = l3;
|
||||
}
|
||||
public Triangle(double x1, double y1, double x2, double y2, double x3, double 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(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),
|
||||
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))
|
||||
{ }
|
||||
|
||||
public Vert this[int index]
|
||||
{
|
||||
get => index switch
|
||||
{
|
||||
0 => A,
|
||||
1 => B,
|
||||
2 => C,
|
||||
_ => throw new IndexOutOfRangeException(nameof(index)),
|
||||
};
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
A = value;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
B = value;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
C = value;
|
||||
break;
|
||||
|
||||
default: throw new IndexOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Triangle Absolute(Triangle val) =>
|
||||
new(Vert.Absolute(val.A), Vert.Absolute(val.B), Vert.Absolute(val.C));
|
||||
public static Triangle Average(params Triangle[] vals)
|
||||
{
|
||||
(Vert[] As, Vert[] Bs, Vert[] Cs) = SplitVertArray(vals);
|
||||
return new(Vert.Average(As), Vert.Average(Bs), Vert.Average(Cs));
|
||||
}
|
||||
public static Triangle Ceiling(Triangle val) =>
|
||||
new(Vert.Ceiling(val.A), Vert.Ceiling(val.B), Vert.Ceiling(val.C));
|
||||
public static Triangle Clamp(Triangle val, Triangle min, Triangle max) =>
|
||||
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 = false) =>
|
||||
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 Median(params Triangle[] vals)
|
||||
{
|
||||
(Vert[] As, Vert[] Bs, Vert[] Cs) = SplitVertArray(vals);
|
||||
return new(Vert.Median(As), Vert.Median(Bs), Vert.Median(Cs));
|
||||
}
|
||||
public static Triangle Max(params Triangle[] vals)
|
||||
{
|
||||
(Vert[] As, Vert[] Bs, Vert[] Cs) = SplitVertArray(vals);
|
||||
return new(Vert.Max(As), Vert.Max(Bs), Vert.Max(Cs));
|
||||
}
|
||||
public static Triangle Min(params Triangle[] vals)
|
||||
{
|
||||
(Vert[] As, Vert[] Bs, Vert[] Cs) = SplitVertArray(vals);
|
||||
return new(Vert.Min(As), Vert.Min(Bs), Vert.Min(Cs));
|
||||
}
|
||||
|
||||
public static (Vert[] As, Vert[] Bs, Vert[] Cs) SplitVertArray(params Triangle[] tris)
|
||||
{
|
||||
Vert[] a = new Vert[tris.Length], b = new Vert[tris.Length], c = new Vert[tris.Length];
|
||||
for (int i = 0; i < tris.Length; i++)
|
||||
{
|
||||
a[i] = tris[i].A;
|
||||
b[i] = tris[i].B;
|
||||
c[i] = tris[i].C;
|
||||
}
|
||||
|
||||
return (a, b, c);
|
||||
}
|
||||
public static (Line[] L1s, Line[] L2s, Line[] L3s) SplitLineArray(params Triangle[] tris)
|
||||
{
|
||||
Line[] l1 = new Line[tris.Length], l2 = new Line[tris.Length], l3 = new Line[tris.Length];
|
||||
for (int i = 0; i < tris.Length; i++)
|
||||
{
|
||||
l1[i] = tris[i].L1;
|
||||
l2[i] = tris[i].L2;
|
||||
l3[i] = tris[i].L3;
|
||||
}
|
||||
|
||||
return (l1, l2, l3);
|
||||
}
|
||||
|
||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != typeof(Triangle)) return false;
|
||||
return Equals((Triangle)obj);
|
||||
}
|
||||
public bool Equals(Triangle other) => A == other.A && B == other.B && C == other.C;
|
||||
public override int GetHashCode() => A.GetHashCode() ^ B.GetHashCode() ^ C.GetHashCode();
|
||||
public override string ToString() => ToString((string?)null);
|
||||
public string ToString(string? provider) =>
|
||||
"A: " + A.ToString(provider) + " B: " + B.ToString(provider) + " C: " + C.ToString(provider);
|
||||
public string ToString(IFormatProvider provider) =>
|
||||
"A: " + A.ToString(provider) + " B: " + B.ToString(provider) + " C: " + C.ToString(provider);
|
||||
|
||||
public object Clone() => new Triangle(A, B, C);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
public IEnumerator<Vert> GetEnumerator()
|
||||
{
|
||||
yield return A;
|
||||
yield return B;
|
||||
yield return C;
|
||||
}
|
||||
|
||||
public Vert[] ToArray() => new Vert[] { A, B, C };
|
||||
public List<Vert> ToList() => new() { A, B, C };
|
||||
|
||||
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, 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, 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, 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 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<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<int> fill) => new(fill);
|
||||
}
|
||||
}
|
||||
95
Nerd_STF/Nerd_STF/Mathematics/Geometry/Vert.cs
Normal file
95
Nerd_STF/Nerd_STF/Mathematics/Geometry/Vert.cs
Normal file
@ -0,0 +1,95 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Nerd_STF.Mathematics.Geometry
|
||||
{
|
||||
public struct Vert : ICloneable, IEquatable<Vert>
|
||||
{
|
||||
public static Vert Back => new(0, 0, -1);
|
||||
public static Vert Down => new(0, -1, 0);
|
||||
public static Vert Forward => new(0, 0, 1);
|
||||
public static Vert Left => new(-1, 0, 0);
|
||||
public static Vert Right => new(1, 0, 0);
|
||||
public static Vert Up => new(0, 1, 0);
|
||||
|
||||
public static Vert One => new(1, 1, 1);
|
||||
public static Vert Zero => new(0, 0, 0);
|
||||
|
||||
public double Magnitude => position.Magnitude;
|
||||
public Vert Normalized => new(this / Magnitude);
|
||||
|
||||
public Double3 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 double 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 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));
|
||||
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));
|
||||
public static Vert Median(params Vert[] vals) =>
|
||||
Double3.Median(ToDouble3Array(vals));
|
||||
public static Vert Max(params Vert[] vals) =>
|
||||
Double3.Max(ToDouble3Array(vals));
|
||||
public static Vert Min(params Vert[] vals) =>
|
||||
Double3.Min(ToDouble3Array(vals));
|
||||
public static Double3[] ToDouble3Array(params Vert[] vals)
|
||||
{
|
||||
Double3[] doubles = new Double3[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 override bool Equals([NotNullWhen(true)] object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != typeof(Vert)) return false;
|
||||
return Equals((Vert)obj);
|
||||
}
|
||||
public bool Equals(Vert other) => position == other.position;
|
||||
public override int GetHashCode() => position.GetHashCode();
|
||||
public override string ToString() => ToString((string?)null);
|
||||
public string ToString(string? provider) => position.ToString(provider);
|
||||
public string ToString(IFormatProvider provider) => position.ToString(provider);
|
||||
|
||||
public object Clone() => new Vert(position);
|
||||
|
||||
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, Vert b) => new(a.position / b.position);
|
||||
public static Vert operator /(Vert a, double 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(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<int> fill) => new(fill);
|
||||
}
|
||||
}
|
||||
184
Nerd_STF/Nerd_STF/Mathematics/Int2.cs
Normal file
184
Nerd_STF/Nerd_STF/Mathematics/Int2.cs
Normal file
@ -0,0 +1,184 @@
|
||||
using Nerd_STF.Mathematics.Geometry;
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Nerd_STF.Mathematics
|
||||
{
|
||||
public struct Int2 : ICloneable, IComparable<Int2>, IEquatable<Int2>, IGroup<int>
|
||||
{
|
||||
public static Int2 Down => new(0, -1);
|
||||
public static Int2 Left => new(-1, 0);
|
||||
public static Int2 Right => new(1, 0);
|
||||
public static Int2 Up => new(0, 1);
|
||||
|
||||
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 int x, y;
|
||||
|
||||
public Int2(int all) : this(all, all) { }
|
||||
public Int2(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
public Int2(Fill<int> fill) : this(fill(0), fill(1)) { }
|
||||
|
||||
public int 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 Int2 Absolute(Int2 val) =>
|
||||
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y));
|
||||
public static Int2 Average(params Int2[] vals) => Sum(vals) / vals.Length;
|
||||
public static Int2 Clamp(Int2 val, Int2 min, Int2 max) =>
|
||||
new(Mathf.Clamp(val.x, min.x, max.x),
|
||||
Mathf.Clamp(val.y, min.y, max.y));
|
||||
public static Int2 ClampMagnitude(Int2 val, int minMag, int 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 Int3 Cross(Int2 a, Int2 b, bool normalized = false) =>
|
||||
Int3.Cross(a, b, normalized);
|
||||
public static Int2 Divide(Int2 num, params Int2[] vals)
|
||||
{
|
||||
foreach (Int2 d in vals) num /= d;
|
||||
return num;
|
||||
}
|
||||
public static int Dot(Int2 a, Int2 b) => a.x * b.x + a.y * b.y;
|
||||
public static int Dot(params Int2[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
int x = 1, y = 1;
|
||||
foreach (Int2 d in vals)
|
||||
{
|
||||
x *= d.x;
|
||||
y *= d.y;
|
||||
}
|
||||
return x + y;
|
||||
}
|
||||
public static Int2 Lerp(Int2 a, Int2 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 Int2 Median(params Int2[] vals)
|
||||
{
|
||||
int index = Mathf.Average(0, vals.Length - 1);
|
||||
Int2 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
|
||||
return Average(valA, valB);
|
||||
}
|
||||
public static Int2 Max(params Int2[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int2 val = vals[0];
|
||||
foreach (Int2 d in vals) val = d > val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static Int2 Min(params Int2[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int2 val = vals[0];
|
||||
foreach (Int2 d in vals) val = d < val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static Int2 Multiply(params Int2[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int2 val = One;
|
||||
foreach (Int2 d in vals) val *= d;
|
||||
return val;
|
||||
}
|
||||
public static Int2 Subtract(Int2 num, params Int2[] vals)
|
||||
{
|
||||
foreach (Int2 d in vals) num -= d;
|
||||
return num;
|
||||
}
|
||||
public static Int2 Sum(params Int2[] vals)
|
||||
{
|
||||
Int2 val = Zero;
|
||||
foreach (Int2 d in vals) val += d;
|
||||
return val;
|
||||
}
|
||||
|
||||
public int CompareTo(Int2 other)
|
||||
{
|
||||
double magA = Magnitude, magB = other.Magnitude;
|
||||
return magA == magB ? 0 : magA > magB ? 1 : -1;
|
||||
}
|
||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != typeof(Int2)) return false;
|
||||
return Equals((Int2)obj);
|
||||
}
|
||||
public bool Equals(Int2 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 Int2(x, y);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
public IEnumerator<int> GetEnumerator()
|
||||
{
|
||||
yield return x;
|
||||
yield return y;
|
||||
}
|
||||
|
||||
public int[] ToArray() => new[] { x, y };
|
||||
public List<int> ToList() => new() { x, y };
|
||||
|
||||
public static Int2 operator +(Int2 a, Int2 b) => new(a.x + b.x, a.y + b.y);
|
||||
public static Int2 operator -(Int2 i) => new(-i.x, -i.y);
|
||||
public static Int2 operator -(Int2 a, Int2 b) => new(a.x - b.x, a.y - b.y);
|
||||
public static Int2 operator *(Int2 a, Int2 b) => new(a.x * b.x, a.y * b.y);
|
||||
public static Int2 operator *(Int2 a, int b) => new(a.x * b, a.y * b);
|
||||
public static Int2 operator /(Int2 a, Int2 b) => new(a.x / b.x, a.y / b.y);
|
||||
public static Int2 operator /(Int2 a, int b) => new(a.x / b, a.y / b);
|
||||
public static bool operator ==(Int2 a, Int2 b) => a.Equals(b);
|
||||
public static bool operator !=(Int2 a, Int2 b) => !a.Equals(b);
|
||||
public static bool operator >(Int2 a, Int2 b) => a.CompareTo(b) > 0;
|
||||
public static bool operator <(Int2 a, Int2 b) => a.CompareTo(b) < 0;
|
||||
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(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);
|
||||
public static implicit operator Int2(Fill<int> fill) => new(fill);
|
||||
}
|
||||
}
|
||||
206
Nerd_STF/Nerd_STF/Mathematics/Int3.cs
Normal file
206
Nerd_STF/Nerd_STF/Mathematics/Int3.cs
Normal file
@ -0,0 +1,206 @@
|
||||
using Nerd_STF.Mathematics.Geometry;
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Nerd_STF.Mathematics
|
||||
{
|
||||
public struct Int3 : ICloneable, IComparable<Int3>, IEquatable<Int3>, IGroup<int>
|
||||
{
|
||||
public static Int3 Back => new(0, 0, -1);
|
||||
public static Int3 Down => new(0, -1, 0);
|
||||
public static Int3 Forward => new(0, 0, 1);
|
||||
public static Int3 Left => new(-1, 0, 0);
|
||||
public static Int3 Right => new(1, 0, 0);
|
||||
public static Int3 Up => new(0, 1, 0);
|
||||
|
||||
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 Int2 XY => new(x, y);
|
||||
public Int2 XZ => new(x, z);
|
||||
public Int2 YZ => new(y, z);
|
||||
|
||||
public int x, y, z;
|
||||
|
||||
public Int3(int all) : this(all, all, all) { }
|
||||
public Int3(int x, int y) : this(x, y, 0) { }
|
||||
public Int3(int x, int y, int z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
public Int3(Fill<int> fill) : this(fill(0), fill(1), fill(2)) { }
|
||||
|
||||
public int 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 Int3 Absolute(Int3 val) =>
|
||||
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y), Mathf.Absolute(val.z));
|
||||
public static Int3 Average(params Int3[] vals) => Sum(vals) / vals.Length;
|
||||
public static Int3 Clamp(Int3 val, Int3 min, Int3 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 Int3 ClampMagnitude(Int3 val, int minMag, int 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 Int3 Cross(Int3 a, Int3 b, bool normalized = false)
|
||||
{
|
||||
Int3 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 Int3 Divide(Int3 num, params Int3[] vals)
|
||||
{
|
||||
foreach (Int3 d in vals) num /= d;
|
||||
return num;
|
||||
}
|
||||
public static int Dot(Int3 a, Int3 b) => a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
public static int Dot(params Int3[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
int x = 1, y = 1, z = 1;
|
||||
foreach (Int3 d in vals)
|
||||
{
|
||||
x *= d.x;
|
||||
y *= d.y;
|
||||
z *= d.z;
|
||||
}
|
||||
return x + y + z;
|
||||
}
|
||||
public static Int3 Lerp(Int3 a, Int3 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 Int3 Median(params Int3[] vals)
|
||||
{
|
||||
int index = Mathf.Average(0, vals.Length - 1);
|
||||
Int3 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
|
||||
return Average(valA, valB);
|
||||
}
|
||||
public static Int3 Max(params Int3[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int3 val = vals[0];
|
||||
foreach (Int3 d in vals) val = d > val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static Int3 Min(params Int3[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int3 val = vals[0];
|
||||
foreach (Int3 d in vals) val = d < val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static Int3 Multiply(params Int3[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int3 val = One;
|
||||
foreach (Int3 d in vals) val *= d;
|
||||
return val;
|
||||
}
|
||||
public static Int3 Subtract(Int3 num, params Int3[] vals)
|
||||
{
|
||||
foreach (Int3 d in vals) num -= d;
|
||||
return num;
|
||||
}
|
||||
public static Int3 Sum(params Int3[] vals)
|
||||
{
|
||||
Int3 val = Zero;
|
||||
foreach (Int3 d in vals) val += d;
|
||||
return val;
|
||||
}
|
||||
|
||||
public int CompareTo(Int3 other)
|
||||
{
|
||||
double magA = Magnitude, magB = other.Magnitude;
|
||||
return magA == magB ? 0 : magA > magB ? 1 : -1;
|
||||
}
|
||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != typeof(Int3)) return false;
|
||||
return Equals((Int3)obj);
|
||||
}
|
||||
public bool Equals(Int3 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 Int3(x, y, z);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
public IEnumerator<int> GetEnumerator()
|
||||
{
|
||||
yield return x;
|
||||
yield return y;
|
||||
yield return z;
|
||||
}
|
||||
|
||||
public int[] ToArray() => new[] { x, y, z };
|
||||
public List<int> ToList() => new() { x, y, z };
|
||||
|
||||
public static Int3 operator +(Int3 a, Int3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
public static Int3 operator -(Int3 i) => new(-i.x, -i.y, -i.z);
|
||||
public static Int3 operator -(Int3 a, Int3 b) => new(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
public static Int3 operator *(Int3 a, Int3 b) => new(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||
public static Int3 operator *(Int3 a, int b) => new(a.x * b, a.y * b, a.z * b);
|
||||
public static Int3 operator /(Int3 a, Int3 b) => new(a.x / b.x, a.y / b.y, a.z / b.z);
|
||||
public static Int3 operator /(Int3 a, int b) => new(a.x / b, a.y / b, a.z / b);
|
||||
public static bool operator ==(Int3 a, Int3 b) => a.Equals(b);
|
||||
public static bool operator !=(Int3 a, Int3 b) => !a.Equals(b);
|
||||
public static bool operator >(Int3 a, Int3 b) => a.CompareTo(b) > 0;
|
||||
public static bool operator <(Int3 a, Int3 b) => a.CompareTo(b) < 0;
|
||||
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 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,
|
||||
(int)val.position.z);
|
||||
public static implicit operator Int3(Fill<int> fill) => new(fill);
|
||||
}
|
||||
}
|
||||
222
Nerd_STF/Nerd_STF/Mathematics/Int4.cs
Normal file
222
Nerd_STF/Nerd_STF/Mathematics/Int4.cs
Normal file
@ -0,0 +1,222 @@
|
||||
using Nerd_STF.Mathematics.Geometry;
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Nerd_STF.Mathematics
|
||||
{
|
||||
public struct Int4 : ICloneable, IComparable<Int4>, IEquatable<Int4>, IGroup<int>
|
||||
{
|
||||
public static Int4 Back => new(0, 0, -1, 0);
|
||||
public static Int4 Deep => new(0, 0, 0, -1);
|
||||
public static Int4 Down => new(0, -1, 0, 0);
|
||||
public static Int4 Far => new(0, 0, 0, 1);
|
||||
public static Int4 Forward => new(0, 0, 1, 0);
|
||||
public static Int4 Left => new(-1, 0, 0, 0);
|
||||
public static Int4 Right => new(1, 0, 0, 0);
|
||||
public static Int4 Up => new(0, 1, 0, 0);
|
||||
|
||||
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 Int2 XY => new(x, y);
|
||||
public Int2 XZ => new(x, z);
|
||||
public Int2 XW => new(x, w);
|
||||
public Int2 YW => new(y, w);
|
||||
public Int2 YZ => new(y, z);
|
||||
public Int2 ZW => new(z, w);
|
||||
|
||||
public Int3 XYW => new(x, y, w);
|
||||
public Int3 XYZ => new(x, y, z);
|
||||
public Int3 YZW => new(y, z, w);
|
||||
public Int3 XZW => new(x, z, w);
|
||||
|
||||
public int x, y, z, w;
|
||||
|
||||
public Int4(int all) : this(all, all, all, all) { }
|
||||
public Int4(int x, int y) : this(x, y, 0, 0) { }
|
||||
public Int4(int x, int y, int z) : this(x, y, z, 0) { }
|
||||
public Int4(int x, int y, int z, int w)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
public Int4(Fill<int> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
|
||||
|
||||
public int 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 Int4 Absolute(Int4 val) =>
|
||||
new(Mathf.Absolute(val.x), Mathf.Absolute(val.y), Mathf.Absolute(val.z), Mathf.Absolute(val.w));
|
||||
public static Int4 Average(params Int4[] vals) => Sum(vals) / vals.Length;
|
||||
public static Int4 Clamp(Int4 val, Int4 min, Int4 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 Int4 ClampMagnitude(Int4 val, int minMag, int 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 Int4 Divide(Int4 num, params Int4[] vals)
|
||||
{
|
||||
foreach (Int4 d in vals) num /= d;
|
||||
return num;
|
||||
}
|
||||
public static int Dot(Int4 a, Int4 b) => a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||
public static int Dot(params Int4[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
int x = 1, y = 1, z = 1, w = 1;
|
||||
foreach (Int4 d in vals)
|
||||
{
|
||||
x *= d.x;
|
||||
y *= d.y;
|
||||
z *= d.z;
|
||||
w *= d.w;
|
||||
}
|
||||
return x + y + z;
|
||||
}
|
||||
public static Int4 Lerp(Int4 a, Int4 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 Int4 Median(params Int4[] vals)
|
||||
{
|
||||
int index = Mathf.Average(0, vals.Length - 1);
|
||||
Int4 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)];
|
||||
return Average(valA, valB);
|
||||
}
|
||||
public static Int4 Max(params Int4[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int4 val = vals[0];
|
||||
foreach (Int4 d in vals) val = d > val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static Int4 Min(params Int4[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int4 val = vals[0];
|
||||
foreach (Int4 d in vals) val = d < val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static Int4 Multiply(params Int4[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return Zero;
|
||||
Int4 val = One;
|
||||
foreach (Int4 d in vals) val *= d;
|
||||
return val;
|
||||
}
|
||||
public static Int4 Subtract(Int4 num, params Int4[] vals)
|
||||
{
|
||||
foreach (Int4 d in vals) num -= d;
|
||||
return num;
|
||||
}
|
||||
public static Int4 Sum(params Int4[] vals)
|
||||
{
|
||||
Int4 val = Zero;
|
||||
foreach (Int4 d in vals) val += d;
|
||||
return val;
|
||||
}
|
||||
|
||||
public int CompareTo(Int4 other)
|
||||
{
|
||||
double magA = Magnitude, magB = other.Magnitude;
|
||||
return magA == magB ? 0 : magA > magB ? 1 : -1;
|
||||
}
|
||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != typeof(Int4)) return false;
|
||||
return Equals((Int4)obj);
|
||||
}
|
||||
public bool Equals(Int4 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 Int4(x, y, z, w);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
public IEnumerator<int> GetEnumerator()
|
||||
{
|
||||
yield return x;
|
||||
yield return y;
|
||||
yield return z;
|
||||
yield return w;
|
||||
}
|
||||
|
||||
public int[] ToArray() => new[] { x, y, z, w };
|
||||
public List<int> ToList() => new() { x, y, z, w };
|
||||
|
||||
public static Int4 operator +(Int4 a, Int4 b) => new(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
|
||||
public static Int4 operator -(Int4 d) => new(-d.x, -d.y, -d.z, -d.w);
|
||||
public static Int4 operator -(Int4 a, Int4 b) => new(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
|
||||
public static Int4 operator *(Int4 a, Int4 b) => new(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
|
||||
public static Int4 operator *(Int4 a, int b) => new(a.x * b, a.y * b, a.z * b, a.w * b);
|
||||
public static Int4 operator /(Int4 a, Int4 b) => new(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
|
||||
public static Int4 operator /(Int4 a, int b) => new(a.x / b, a.y / b, a.z / b, a.w / b);
|
||||
public static bool operator ==(Int4 a, Int4 b) => a.Equals(b);
|
||||
public static bool operator !=(Int4 a, Int4 b) => !a.Equals(b);
|
||||
public static bool operator >(Int4 a, Int4 b) => a.CompareTo(b) > 0;
|
||||
public static bool operator <(Int4 a, Int4 b) => a.CompareTo(b) < 0;
|
||||
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 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,
|
||||
(int)val.position.z, 0);
|
||||
public static implicit operator Int4(Fill<int> fill) => new(fill);
|
||||
}
|
||||
}
|
||||
205
Nerd_STF/Nerd_STF/Mathematics/Mathf.cs
Normal file
205
Nerd_STF/Nerd_STF/Mathematics/Mathf.cs
Normal file
@ -0,0 +1,205 @@
|
||||
namespace Nerd_STF.Mathematics
|
||||
{
|
||||
public static class Mathf
|
||||
{
|
||||
public const double DegToRad = 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 RadToDeg = 57.2957795131; // 180 / Pi
|
||||
public const double Tau = 6.28318530718; // 2 * Pi
|
||||
|
||||
public static double Absolute(double 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 double ArcCot(double value) => ArcCos(value / Sqrt(1 + value * value));
|
||||
|
||||
public static double ArcCsc(double value) => ArcSin(1 / value);
|
||||
|
||||
public static double ArcSec(double 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 double ArcTan(double value) => ArcSin(value / Sqrt(1 + value * value));
|
||||
|
||||
public static double Average(params double[] 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 double Clamp(double val, double min, double max)
|
||||
{
|
||||
if (max < min) throw new ArgumentOutOfRangeException(nameof(max),
|
||||
nameof(max) + " must be greater than or equal to " + nameof(min));
|
||||
val = val < min ? min : val;
|
||||
val = val > max ? max : val;
|
||||
return val;
|
||||
}
|
||||
public static int Clamp(int val, int min, int max)
|
||||
{
|
||||
if (max < min) throw new ArgumentOutOfRangeException(nameof(max),
|
||||
nameof(max) + " must be greater than or equal to " + nameof(min));
|
||||
val = val < min ? min : val;
|
||||
val = val > max ? max : val;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static double Cos(double radians) => Sin(radians + HalfPi);
|
||||
|
||||
public static double Cot(double radians) => Cos(radians) / Sin(radians);
|
||||
|
||||
public static double Csc(double radians) => 1 / Sin(radians);
|
||||
|
||||
public static double Divide(double val, params double[] dividends)
|
||||
{
|
||||
foreach (double d in dividends) val /= d;
|
||||
return val;
|
||||
}
|
||||
public static int Divide(int val, params int[] dividends)
|
||||
{
|
||||
foreach (int i in dividends) val /= i;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static int Factorial(int amount)
|
||||
{
|
||||
if (amount < 0) return 0;
|
||||
int val = 1;
|
||||
for (int i = 2; i <= amount; i++) val *= i;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static int Floor(double val) => (int)(val - (val % 1));
|
||||
|
||||
public static double Lerp(double a, double b, double t, bool clamp = true)
|
||||
{
|
||||
double 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 double Max(params double[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
double val = vals[0];
|
||||
foreach (double d in vals) val = d > val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static int Max(params int[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
int val = vals[0];
|
||||
foreach (int i in vals) val = i > val ? i : val;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static double Median(params double[] vals)
|
||||
{
|
||||
double index = Average(0, vals.Length - 1);
|
||||
double 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(params double[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
double val = vals[0];
|
||||
foreach (double d in vals) val = d < val ? d : val;
|
||||
return val;
|
||||
}
|
||||
public static int Min(params int[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
int val = vals[0];
|
||||
foreach (int i in vals) val = i < val ? i : val;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static double Multiply(params double[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
double val = 1;
|
||||
foreach (double d in vals) val *= d;
|
||||
return val;
|
||||
}
|
||||
public static int Multiply(params int[] vals)
|
||||
{
|
||||
if (vals.Length < 1) return 0;
|
||||
int val = 1;
|
||||
foreach (int i in vals) val *= i;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static double Power(double num, double pow) => Math.Pow(num, pow);
|
||||
public static int Power(int num, int pow)
|
||||
{
|
||||
if (pow < 0) return 0;
|
||||
int val = 1;
|
||||
for (int i = 0; i < Absolute(pow); i++) val *= num;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static double Root(double value, double index) => 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 double Sec(double radians) => 1 / Cos(radians);
|
||||
|
||||
public static double Sin(double 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;
|
||||
|
||||
return
|
||||
a + (b * x) + (c * x * x) + (d * x * x * x) + (e * x * x * x * x) + (f * x * x * x * x * x)
|
||||
+ (g * x * x * x * x * x * x) + (h * x * x * x * x * x * x * x) + (i * x * x * x * x * x * x * x * x)
|
||||
+ (j * x * x * x * x * x * x * x * x * x);
|
||||
}
|
||||
|
||||
public static double Sqrt(double value) => Root(value, 2);
|
||||
|
||||
public static double Subtract(double num, params double[] vals)
|
||||
{
|
||||
foreach (double d in vals) num -= d;
|
||||
return num;
|
||||
}
|
||||
public static int Subtract(int num, params int[] vals)
|
||||
{
|
||||
foreach (int i in vals) num -= i;
|
||||
return num;
|
||||
}
|
||||
|
||||
public static double Sum(params double[] vals)
|
||||
{
|
||||
double val = 0;
|
||||
foreach (double d in vals) val += d;
|
||||
return val;
|
||||
}
|
||||
public static int Sum(params int[] vals)
|
||||
{
|
||||
int val = 0;
|
||||
foreach (int i in vals) val += i;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static double Tan(double radians) => Sin(radians) / Cos(radians);
|
||||
}
|
||||
}
|
||||
BIN
Nerd_STF/Nerd_STF/bin/Release/net6.0/ref/Nerd_STF.dll
Normal file
BIN
Nerd_STF/Nerd_STF/bin/Release/net6.0/ref/Nerd_STF.dll
Normal file
Binary file not shown.
27
README.md
27
README.md
@ -1,3 +1,28 @@
|
||||
# Nerd_STF
|
||||
|
||||
Nerd_STF is a C# library I made that adds general things I think I (and whoever uses it) will use. I will add onto this library as time passes. Nerd_STF runs on .NET 5.0. Giving me suggestions and calling out bugs would be much appreciated!
|
||||
## What is it?
|
||||
|
||||
Nerd_STF is a C# library that runs on .Net 6.0, and contains added structures and classes I feel would help the default C# library package. Feel free to do with it what you would like.
|
||||
|
||||
Nerd_STF has recently been remade, completely rebuilding many of its topics.
|
||||
|
||||
## What does it include?
|
||||
Nerd_STF will include math structures as well as other computer science topics. Right now, it is mainly focused on mathematics, but will branch out in the future. It currently contains things like lists of 3 doubles or ints, or `Vert`, `Line`, and `Triangle` classes, that are rich in implementation.
|
||||
|
||||
## What about Nerd_STF Versions `2021`?
|
||||
Nerd_STF `2021` used an different version scheme, based on the year, as you might have guessed (it is not the year `2` right now), and while I will be keeping the `2021` versions up, I wouldn't recommend using them, and the code is old code, written by a more naive me. Hell, I wrote an entire `List<T>` class there before I knew of the `System.Collections.Generic.List<T>` class that did literally everything for me already. Oh well. So, keep that in mind when you check out those versions of the library.
|
||||
|
||||
## How do I install it?
|
||||
Well, unfortunately I don't have a nuget package for this library yet (maybe in the future), so here, I'll walk you through installing it in Visual Studio.
|
||||
|
||||
Step 1: Find the `.dll` for this library, found in `/Nerd_STF/Nerd_STF/bin/Release/net6.0/ref/Nerd_STF.dll`. You can either move it, or simply remember where it is.
|
||||
Step 2: Search for "Add Project Reference" in the Visual Studio 2019 or 2022 search bar.
|
||||
Step 3: Click the "Browse" tab on the left, then click the "Browse" button on the bottom-right.
|
||||
Step 4: Select the `.dll` we found earlier.
|
||||
Step 5: Click OK.
|
||||
|
||||
This is what happens the first time you import it. Any other times, simply go to the "Add Project Reference" Window, then the "Browse" tab, and the `.dll` will already be in the list in the middle. Find it, and click the box on its left. Then click OK.
|
||||
|
||||
---
|
||||
|
||||
I hope you enjoy using Nerd_STF!
|
||||
|
||||
261
Scripts/Files.cs
261
Scripts/Files.cs
@ -1,261 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Nerd_STF.Lists;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace Nerd_STF.File.Saving
|
||||
{
|
||||
[Obsolete(nameof(BinaryFile) + " uses the " + nameof(BinaryFormatter) + ", which is considered dangerous. Go to 'https://aka.ms/binaryformatter/' for more information.")]
|
||||
[Serializable]
|
||||
public class BinaryFile
|
||||
{
|
||||
public object Data { get; set; }
|
||||
public string Path { get; set; }
|
||||
|
||||
public BinaryFile(string path) => Path = path;
|
||||
public BinaryFile(string path, object data)
|
||||
{
|
||||
Data = data;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public static BinaryFile Load(string path)
|
||||
{
|
||||
BinaryFile file = new(path);
|
||||
FileStream stream = new(path, FileMode.Open);
|
||||
BinaryFormatter formatter = new();
|
||||
file.Data = formatter.Deserialize(stream);
|
||||
stream.Close();
|
||||
return file;
|
||||
}
|
||||
|
||||
public void Erase() => Data = null;
|
||||
public void Load()
|
||||
{
|
||||
FileStream stream = new(Path, FileMode.Open);
|
||||
BinaryFormatter formatter = new();
|
||||
Data = formatter.Deserialize(stream);
|
||||
stream.Close();
|
||||
}
|
||||
public void Save()
|
||||
{
|
||||
FileStream stream = new(Path, FileMode.Create);
|
||||
BinaryFormatter formatter = new();
|
||||
formatter.Serialize(stream, Data);
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
[Obsolete(nameof(BinaryFile) + " uses the " + nameof(BinaryFormatter) + ", which is considered dangerous. Go to 'https://aka.ms/binaryformatter/' for more information.")]
|
||||
[Serializable]
|
||||
public class BinaryFile<T>
|
||||
{
|
||||
public T Data { get; set; }
|
||||
public string Path { get; set; }
|
||||
|
||||
public BinaryFile(string path) => Path = path;
|
||||
public BinaryFile(string path, T data)
|
||||
{
|
||||
Data = data;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public static BinaryFile<T> Load(string path)
|
||||
{
|
||||
BinaryFile<T> file = new(path);
|
||||
FileStream stream = new(path, FileMode.Open);
|
||||
BinaryFormatter formatter = new();
|
||||
file.Data = (T)formatter.Deserialize(stream);
|
||||
stream.Close();
|
||||
return file;
|
||||
}
|
||||
|
||||
public void Erase() => Data = default;
|
||||
public void Load()
|
||||
{
|
||||
FileStream stream = new(Path, FileMode.Open);
|
||||
BinaryFormatter formatter = new();
|
||||
Data = (T)formatter.Deserialize(stream);
|
||||
stream.Close();
|
||||
}
|
||||
public void Save()
|
||||
{
|
||||
FileStream stream = new(Path, FileMode.Create);
|
||||
BinaryFormatter formatter = new();
|
||||
formatter.Serialize(stream, Data);
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
[Serializable]
|
||||
public class ByteFile : File<List<byte>>
|
||||
{
|
||||
public byte this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= Data.Length) throw new ArgumentOutOfRangeException(nameof(index));
|
||||
return Data[index];
|
||||
}
|
||||
set { Data[index] = value; }
|
||||
}
|
||||
|
||||
public ByteFile(string path) => Path = path;
|
||||
public ByteFile(string path, params byte[] data)
|
||||
{
|
||||
Data = new List<byte>(data);
|
||||
Path = path;
|
||||
}
|
||||
public ByteFile(string path, List<byte> data)
|
||||
{
|
||||
Data = data;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public static ByteFile Load(string path)
|
||||
{
|
||||
ByteFile file = new(path);
|
||||
FileStream stream = new(file.Path, FileMode.Open);
|
||||
byte[] b = new byte[stream.Length];
|
||||
while (stream.Read(b, 0, b.Length) > 0) ;
|
||||
file.Data = new(b);
|
||||
stream.Close();
|
||||
return file;
|
||||
}
|
||||
|
||||
public override void Erase() => Data = new();
|
||||
public void Fill(int length, byte fill = 0) => Data = new List<byte>(length, fill);
|
||||
public override void Load(bool erase = true)
|
||||
{
|
||||
if (erase) Erase();
|
||||
FileStream stream = new(Path, FileMode.Open);
|
||||
byte[] b = new byte[stream.Length];
|
||||
while (stream.Read(b, 0, b.Length) > 0) ;
|
||||
Data.AddRange(b);
|
||||
stream.Close();
|
||||
}
|
||||
public void Remove(int start, int amount)
|
||||
{
|
||||
List<byte> old = Data;
|
||||
Data = new List<byte>(old.Length - amount);
|
||||
for (int i = 0; i < old.Length; i++)
|
||||
{
|
||||
if (i > start && i < start + amount) i = start + amount;
|
||||
Data[i] = old[i];
|
||||
}
|
||||
}
|
||||
public override void Save()
|
||||
{
|
||||
FileStream stream = new(Path, FileMode.Create);
|
||||
stream.Write(Data.ToArray(), 0, Data.Length);
|
||||
stream.Close();
|
||||
}
|
||||
public override bool TryLoad(out File<List<byte>> file)
|
||||
{
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
file = new ByteFile(Path);
|
||||
FileStream stream = new(file.Path, FileMode.Open);
|
||||
byte[] b = new byte[stream.Length];
|
||||
while (stream.Read(b, 0, b.Length) > 0) ;
|
||||
file.Data.AddRange(b);
|
||||
stream.Close();
|
||||
success = true;
|
||||
}
|
||||
catch { file = null; }
|
||||
|
||||
return success;
|
||||
}
|
||||
public void Write(byte write, bool toFile = false)
|
||||
{
|
||||
Data += write;
|
||||
if (toFile) Save();
|
||||
}
|
||||
public override void Write(List<byte> write, bool toFile = false)
|
||||
{
|
||||
Data += write;
|
||||
if (toFile) Save();
|
||||
}
|
||||
}
|
||||
[Serializable]
|
||||
public class TextFile : File<string>
|
||||
{
|
||||
public TextFile(string path) => Path = path;
|
||||
public TextFile(string path, string data)
|
||||
{
|
||||
Data = data;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public static TextFile Load(string path)
|
||||
{
|
||||
TextFile file = new(path);
|
||||
FileStream stream = new(file.Path, FileMode.Open);
|
||||
byte[] b = new byte[stream.Length];
|
||||
while (stream.Read(b, 0, b.Length) > 0) ;
|
||||
file.Data += Encoding.Default.GetString(b);
|
||||
stream.Close();
|
||||
return file;
|
||||
}
|
||||
|
||||
public override void Erase() => Data = "";
|
||||
public override void Load(bool erase = true)
|
||||
{
|
||||
if (erase) Erase();
|
||||
FileStream stream = new(Path, FileMode.Open);
|
||||
byte[] b = new byte[stream.Length];
|
||||
while (stream.Read(b, 0, b.Length) > 0) ;
|
||||
Data += Encoding.Default.GetString(b);
|
||||
stream.Close();
|
||||
}
|
||||
public void Remove(int start, int amount) => Data = Data.Remove(start, amount);
|
||||
public override void Save()
|
||||
{
|
||||
FileStream stream = new(Path, FileMode.Create);
|
||||
byte[] b = Encoding.Default.GetBytes(Data);
|
||||
stream.Write(b, 0, b.Length);
|
||||
stream.Close();
|
||||
}
|
||||
public override bool TryLoad(out File<string> file)
|
||||
{
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
file = new TextFile(Path);
|
||||
FileStream stream = new(file.Path, FileMode.Open);
|
||||
byte[] b = new byte[stream.Length];
|
||||
while (stream.Read(b, 0, b.Length) > 0) ;
|
||||
file.Data += Encoding.Default.GetString(b);
|
||||
stream.Close();
|
||||
success = true;
|
||||
}
|
||||
catch { file = null; }
|
||||
|
||||
return success;
|
||||
}
|
||||
public void Write(char write, bool toFile = false)
|
||||
{
|
||||
Data += write;
|
||||
if (toFile) Save();
|
||||
}
|
||||
public override void Write(string write, bool toFile = false)
|
||||
{
|
||||
Data += write;
|
||||
if (toFile) Save();
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public abstract class File<T>
|
||||
{
|
||||
public T Data { get; set; }
|
||||
public bool Exists => System.IO.File.Exists(Path);
|
||||
public string Path { get; set; }
|
||||
|
||||
public abstract void Erase();
|
||||
public abstract void Load(bool erase = true);
|
||||
public abstract void Save();
|
||||
public abstract bool TryLoad(out File<T> file);
|
||||
public abstract void Write(T write, bool toFile = false);
|
||||
}
|
||||
}
|
||||
@ -1,119 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Nerd_STF
|
||||
{
|
||||
public static class Hashes
|
||||
{
|
||||
public static int Default(object obj) => obj.GetHashCode();
|
||||
public static byte[] MD5(byte[] input) => System.Security.Cryptography.MD5.Create().ComputeHash(input);
|
||||
public static string MD5(string input)
|
||||
{
|
||||
System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
|
||||
|
||||
byte[] inputB = Encoding.ASCII.GetBytes(input);
|
||||
byte[] hash = md5.ComputeHash(inputB);
|
||||
|
||||
string s = "";
|
||||
for (int i = 0; i < hash.Length; i++) s += hash[i].ToString("X2");
|
||||
return s;
|
||||
}
|
||||
public static uint SchechterTurbulence(uint seed)
|
||||
{
|
||||
seed ^= 2747636419u;
|
||||
seed *= 2654435769u;
|
||||
seed ^= seed >> 16;
|
||||
seed *= 2654435769u;
|
||||
seed ^= seed >> 16;
|
||||
seed *= 2654435769u;
|
||||
|
||||
return seed;
|
||||
}
|
||||
public static byte[] SHA1(byte[] input) => System.Security.Cryptography.SHA1.Create().ComputeHash(input);
|
||||
public static string SHA1(string input)
|
||||
{
|
||||
System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
|
||||
|
||||
byte[] inputB = Encoding.ASCII.GetBytes(input);
|
||||
byte[] hash = sha1.ComputeHash(inputB);
|
||||
|
||||
string s = "";
|
||||
for (int i = 0; i < hash.Length; i++) s += hash[i].ToString("X2");
|
||||
return s;
|
||||
}
|
||||
public static byte[] SHA256(byte[] input) => System.Security.Cryptography.SHA256.Create().ComputeHash(input);
|
||||
public static string SHA256(string input)
|
||||
{
|
||||
System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create();
|
||||
|
||||
byte[] inputB = Encoding.ASCII.GetBytes(input);
|
||||
byte[] hash = sha256.ComputeHash(inputB);
|
||||
|
||||
string s = "";
|
||||
for (int i = 0; i < hash.Length; i++) s += hash[i].ToString("X2");
|
||||
return s;
|
||||
}
|
||||
public static byte[] SHA384(byte[] input) => System.Security.Cryptography.SHA384.Create().ComputeHash(input);
|
||||
public static string SHA384(string input)
|
||||
{
|
||||
System.Security.Cryptography.SHA384 sha384 = System.Security.Cryptography.SHA384.Create();
|
||||
|
||||
byte[] inputB = Encoding.ASCII.GetBytes(input);
|
||||
byte[] hash = sha384.ComputeHash(inputB);
|
||||
|
||||
string s = "";
|
||||
for (int i = 0; i < hash.Length; i++) s += hash[i].ToString("X2");
|
||||
return s;
|
||||
}
|
||||
public static byte[] SHA512(byte[] input) => System.Security.Cryptography.SHA512.Create().ComputeHash(input);
|
||||
public static string SHA512(string input)
|
||||
{
|
||||
System.Security.Cryptography.SHA512 sha512 = System.Security.Cryptography.SHA512.Create();
|
||||
|
||||
byte[] inputB = Encoding.ASCII.GetBytes(input);
|
||||
byte[] hash = sha512.ComputeHash(inputB);
|
||||
|
||||
string s = "";
|
||||
for (int i = 0; i < hash.Length; i++) s += hash[i].ToString("X2");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Misc
|
||||
{
|
||||
public static string PlaceMaker(int num)
|
||||
{
|
||||
return num.ToString()[^1] switch
|
||||
{
|
||||
'1' => num + "st",
|
||||
'2' => num + "nd",
|
||||
'3' => num + "rd",
|
||||
_ => num + "th",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class Stats
|
||||
{
|
||||
public static readonly string Creator = "That_One_Nerd";
|
||||
public static readonly string[] Links = new[]
|
||||
{
|
||||
"Discord: https://discord.gg/ySXMtWDTYY/",
|
||||
"Github: https://https://github.com/that-one-nerd",
|
||||
"Itch: https://that-one-nerd.itch.io/"
|
||||
};
|
||||
public static readonly string Version = "2021.2";
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct Optional<T>
|
||||
{
|
||||
public bool Exists => Value != null;
|
||||
public T Value { get; internal set; }
|
||||
|
||||
public Optional(T input) => Value = input;
|
||||
|
||||
public static explicit operator T(Optional<T> input) => input.Value;
|
||||
public static explicit operator Optional<T>(T input) => new(input);
|
||||
}
|
||||
}
|
||||
1095
Scripts/Lists.cs
1095
Scripts/Lists.cs
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
165
changelog.md
165
changelog.md
@ -1,165 +0,0 @@
|
||||
# Version 2021.0:
|
||||
The Original Release of the Library.
|
||||
Includes:
|
||||
* Nerd_STF:
|
||||
* public static class Hashes
|
||||
* Nerd_STF.Interfaces:
|
||||
* public interface INegatives<T>
|
||||
* Nerd_STF.Lists:
|
||||
* public class List<T>
|
||||
* public class Matrix<T>
|
||||
* Nerd_STF.Mathematics:
|
||||
* public struct Angle
|
||||
* public struct Color
|
||||
* public struct ColorByte
|
||||
* public static class Math
|
||||
* public struct Percent
|
||||
* public struct Vector
|
||||
* public struct Vector2
|
||||
* public struct Vector3
|
||||
* public struct Vector4
|
||||
* public class Miscellaneous
|
||||
* public struct Optional<T>
|
||||
* public static class Stats
|
||||
|
||||
# Version 2021.1:
|
||||
This update is mainly centered around files and filesaving.
|
||||
* Nerd_STF
|
||||
+ Nerd_STF.Filesaving
|
||||
+ File<T>
|
||||
+ BinaryFile
|
||||
+ ByteFile
|
||||
+ TextFile
|
||||
- public class Miscellaneous
|
||||
|
||||
# Version 2021.2:
|
||||
This update is centered around lists.
|
||||
* Nerd_STF:
|
||||
* public static class Hashes:
|
||||
+ public static string SHA1(string)
|
||||
+ public static string SHA256(string)
|
||||
+ public static string SHA384(string)
|
||||
+ public static string SHA512(string)
|
||||
+ public static byte[] MD5(byte[])
|
||||
+ public static byte[] SHA1(byte[])
|
||||
+ public static byte[] SHA256(byte[])
|
||||
+ public static byte[] SHA384(byte[])
|
||||
+ public static byte[] SHA512(byte[])
|
||||
= Made `public static string MD5(string)` include more of my own scripting
|
||||
* Nerd_STF.File:
|
||||
= Nerd_STF.Filesaving: Moved to Nerd_STF.File.Saving
|
||||
* Nerd_STF.File.Saving:
|
||||
+ public class BinaryFile<T>
|
||||
* public class ByteFile:
|
||||
+ public override bool TryLoad(out File<List<byte>>)
|
||||
= Made `public static ByteFile Load(string)` load files faster
|
||||
= Made `public override void Load(bool)` load files faster
|
||||
= Made `public override void Save()` save files faster
|
||||
= Made `public override void Write(byte, bool)` save files faster
|
||||
= Made `public override void Write(List<byte>, bool)` save files faster
|
||||
* public abstract class File<T>:
|
||||
+ public bool Exists;
|
||||
+ public abstract bool TryLoad(out File<T>)
|
||||
* public class TextFile:
|
||||
+ public override bool TryLoad(out File<string>)
|
||||
= Made `public static TextFile Load(string)` load files faster
|
||||
= Made `public override void Load(bool)` load files faster
|
||||
= Made `public override Save()` save files faster
|
||||
= Made `public override void Write(char, bool)` save files faster
|
||||
= Made `public override void Write(string, bool)` save files faster
|
||||
- Nerd_STF.Interfaces:
|
||||
= Moved `public interface INegatives<T>` to `Nerd_STF.Mathematics.Interfaces`
|
||||
* Nerd_STF.Lists:
|
||||
+ public class ReadOnlyList<T>
|
||||
= public class List<T>: Completely reworked everything in `List<T>`
|
||||
+ public int this[T] { get; set; }
|
||||
+ public List(IEnumerable)
|
||||
+ public bool IsEmpty { get; }
|
||||
+ public bool IsNull { get; }
|
||||
+ public bool IsNullOrEmpty { get; }
|
||||
+ public bool Contains(Predicate<T>)
|
||||
+ public int Count (Predicate<T>)
|
||||
+ public void AddRange(IEnumerable)
|
||||
+ public bool Any(Predicate<T>)
|
||||
+ public bool Any(T)
|
||||
+ public T Find(Predicate<T>)
|
||||
+ public T Find(Predicate<T>, int)
|
||||
+ public T Find(Predicate<T>, int, int)
|
||||
+ public T FindOrDefault(Predicate<T>)
|
||||
+ public T FindOrDefault(T)
|
||||
+ public T FindOrDefault(Predicate<T>, int)
|
||||
+ public T FindOrDefault(T, int)
|
||||
+ public T FindOrDefault(Predicate<T>, int, int)
|
||||
+ public T FindOrDefault(T, int, int)
|
||||
+ public List<T> FindAll(Predicate<T>)
|
||||
+ public List<T> FindAll(Predicate<T>, int)
|
||||
+ public List<T> FindAll(Predicate<T>, int, int)
|
||||
+ public List<T> FindLast(Predicate<T>)
|
||||
+ public List<T> FindLast(Predicate<T>, int)
|
||||
+ public List<T> FindLast(Predicate<T>, int, int)
|
||||
+ public T FindLastOrDefault(Predicate<T>)
|
||||
+ public T FindLastOrDefault(T)
|
||||
+ public T FindLastOrDefault(Predicate<T>, int)
|
||||
+ public T FindLastOrDefault(T, int)
|
||||
+ public T FindLastOrDefault(Predicate<T>, int, int)
|
||||
+ public T FindLastOrDefault(T, int, int)
|
||||
+ public int FindIndex(Predicate<T>)
|
||||
+ public int FindIndex(Predicate<T>, int)
|
||||
+ public int FindIndex(Predicate<T>, int, int)
|
||||
+ public List<int> FindAllIndex(Predicate<T>)
|
||||
+ public List<int> FindAllIndex(Predicate<T>, int)
|
||||
+ public List<int> FindAllIndex(Predicate<T>, int, int)
|
||||
+ public int FindLastIndex(Predicate<T>)
|
||||
+ public int FindLastIndex(Predicate<T>, int)
|
||||
+ public int FindLastIndex(Predicate<T>, int, int)
|
||||
+ public bool MatchesAll(Predicate<T>)
|
||||
+ public void Remove(Predicate<T>)
|
||||
+ public void RemoveAll(Predicate<T>)
|
||||
+ public void RemoveAll(T)
|
||||
+ public void RemoveLast(Predicate<T>)
|
||||
+ public void RemoveLast(T)
|
||||
+ IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||
+ public void Randomize()
|
||||
+ public List<int> FindAllIndex()
|
||||
+ public void Shuffle()
|
||||
+ public List<int> FindAllIndex(int)
|
||||
+ public List<int> FindAllIndex(int, int)
|
||||
+ public ReadOnlyList<T> ToReadOnly()
|
||||
= Made `public List<T> Duplicate()` a readonly variable and better (`public List<T> Duplicate { get; }`)
|
||||
= Renamed the internal array to `array,` as opposed to `list`
|
||||
= Renamed `public void Add(T[])` to `public void AddRange(T[])`
|
||||
= Renamed `public void Add(List<T>)` to `public void AddRange(List<T>)`
|
||||
= Renamed `public bool Compare(T)` to `public bool Contains(T)`
|
||||
= Renamed `public void Remove(int, bool)` to `public void Remove(int)`
|
||||
= Renamed `public void SetAll(T)` to `public void Fill(T)`
|
||||
= Made `public string ToString(bool)` count up from zero instead of one when the bool is set to true.
|
||||
= Renamed `public ReadOnlyCollection<T> AsReadOnly()` to `public ReadOnlyCollection<T> ToSystemReadOnly()`
|
||||
- public bool Check(int)
|
||||
- public void Convert(T)
|
||||
- public void Convert(T[])
|
||||
- public void Convert(List<T>)
|
||||
- public T Get(int)
|
||||
- public void Get(int, out T)
|
||||
- public T[] GetAll()
|
||||
- public void Set(int, T)
|
||||
- public void Set(T[])
|
||||
- public void Set(List<T>)
|
||||
- public static List<T> AllDefault(int)
|
||||
- public static List<T> operator +(T[], List<T>)
|
||||
- public static List<T> operator +(List<T>, int)
|
||||
- public static List<T> operator +(T, List<T>)
|
||||
- public static List<T> operator *(List<T>, int)
|
||||
- public static explicit operator T[](List<T>)
|
||||
- public static explicit operator List<T>(T[])
|
||||
= Marked `public class Nerd_STF.Lists.Matrix<T>` as deprecated. This class will be removed or heavily modified in a future release. Also removed all instances of removed List<T> methods and replaced them with work-arounds.
|
||||
* Nerd_STF.Mathematics:
|
||||
= Marked `public struct Angle` as serializable
|
||||
= Marked `public struct Color` as serializable
|
||||
= Marked `public struct ColorByte` as serializable
|
||||
= Marked `public struct Percent` as serializable
|
||||
= Marked `public struct Vector` as serializable
|
||||
= Marked `public struct Vector2` as serializable
|
||||
= Marked `public struct Vector3` as serializable
|
||||
= Marked `public struct Vector4` as serializable
|
||||
+ public static class Misc
|
||||
+ public static string PlaceMaker(int)
|
||||
Loading…
x
Reference in New Issue
Block a user