From d6234f0004f9d5e49ad17270a8b21f6e7ba286b8 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Fri, 30 Sep 2022 17:08:09 -0400 Subject: [PATCH] Releasing alpha v2.3.1.39 --- Changelog.md | 361 ++++++++++-------- Nerd_STF/Exceptions/MathException.cs | 12 + Nerd_STF/Exceptions/UndefinedException.cs | 12 + Nerd_STF/Extensions/EquationExtension.cs | 19 + Nerd_STF/Graphics/HSVA.cs | 10 - Nerd_STF/Graphics/HSVAByte.cs | 2 - Nerd_STF/Mathematics/Algebra/Vector2d.cs | 18 +- Nerd_STF/Mathematics/Algebra/Vector3d.cs | 18 - Nerd_STF/Mathematics/Angle.cs | 46 ++- Nerd_STF/Mathematics/Calculus.cs | 18 +- Nerd_STF/Mathematics/Float2.cs | 18 +- Nerd_STF/Mathematics/Float3.cs | 18 +- Nerd_STF/Mathematics/Float4.cs | 22 +- Nerd_STF/Mathematics/Int2.cs | 16 +- Nerd_STF/Mathematics/Int3.cs | 16 +- Nerd_STF/Mathematics/Int4.cs | 20 +- Nerd_STF/Mathematics/Mathf.cs | 169 +++++--- Nerd_STF/Mathematics/NumberSystems/Complex.cs | 13 +- .../Mathematics/NumberSystems/Quaternion.cs | 41 +- Nerd_STF/Mathematics/Samples/Constants.cs | 4 +- Nerd_STF/Mathematics/Samples/Equations.cs | 15 - Nerd_STF/bin/Release/net6.0/ref/Nerd_STF.dll | Bin 111616 -> 112640 bytes 22 files changed, 456 insertions(+), 412 deletions(-) create mode 100644 Nerd_STF/Exceptions/MathException.cs create mode 100644 Nerd_STF/Exceptions/UndefinedException.cs create mode 100644 Nerd_STF/Extensions/EquationExtension.cs diff --git a/Changelog.md b/Changelog.md index 7731b65..59234c9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,173 +1,218 @@ -# Nerd_STF v2.3.0 +# Nerd_STF v2.3.1.39 -This update adds lots of linear algebra tools, like matrixes and vectors, as well as new number systems, like complex numbers and quaternions. +***Read this to know what works and what doesn't!*** + +The `v2.3.1.x` updates go through every single field and method in Nerd_STF to make sure it works correctly. +You see, up until now I haven't actually tested literally anything at all. Partly because I didn't have the tools to and partly because I was lazy. But now, it's guarenteed to work in most cases (unless I like don't pick up some bug, you know). + +The following types have been checked for the most part and can be safe to use: +- `Nerd_STF.FileType` +- `Nerd_STF.Fill` +- `Nerd_STF.Fill2D` +- `Nerd_STF.Foreach` +- `Nerd_STF.IClosest` +- `Nerd_STF.IContainer` +- `Nerd_STF.IEncapsulator` +- `Nerd_STF.IGroup` +- `Nerd_STF.IGroup2D` +- `Nerd_STF.Logger` +- `Nerd_STF.LogMessage` +- `Nerd_STF.LogSeverity` +- `Nerd_STF.Modifier` +- `Nerd_STF.Modifier2D` +- `Nerd_STF.Exceptions.DifferingVertCountException` +- `Nerd_STF.Exceptions.DisconnectedLinesException` +- `Nerd_STF.Exceptions.InvalidSizeException` +- `Nerd_STF.Exceptions.Nerd_STFException` +- `Nerd_STF.Exceptions.NoInverseException` +- `Nerd_STF.Extensions.ToFillExtension` +- `Nerd_STF.Graphics.ColorChannel` +- `Nerd_STF.Graphics.IlluminationFlags` +- `Nerd_STF.Graphics.IlluminationModel` +- `Nerd_STF.Graphics.Material` +- `Nerd_STF.Graphics.TextureConfig` +- `Nerd_STF.Mathematics.Angle` +- `Nerd_STF.Mathematics.Calculus` +- `Nerd_STF.Mathematics.Equation` +- `Nerd_STF.Mathematics.Float2` +- `Nerd_STF.Mathematics.Float3` +- `Nerd_STF.Mathematics.Float4` +- `Nerd_STF.Mathematics.Int2` +- `Nerd_STF.Mathematics.Int3` +- `Nerd_STF.Mathematics.Int4` +- `Nerd_STF.Mathematics.Mathf` +- `Nerd_STF.Mathematics.NumberSystems.Complex` +- `Nerd_STF.Mathematics.NumberSystems.Quaternion` + - With the exception of the following methods: + - `Quaternion.FromAngles(Angle, Angle, Angle?)` + - `Quaternion.FromAngles(Float3, Angle.Type)` + - `Quaternion.FromVector(Vector3d)` + - `GetAngle()` + - `GetAxis()` + - `ToAngles()` + - `ToVector()` +- `Nerd_STF.Mathematics.Samples.Constants` +- `Nerd_STF.Mathematics.Samples.Equations` + +The following types haven't been checked yet, and should still be taken with a grain of salt: +- `Nerd_STF.Extensions.Container2DExtension` +- `Nerd_STF.Extensions.ConversionExtension` +- `Nerd_STF.Extensions.EquationExtension` +- `Nerd_STF.Graphics.CMYKA` +- `Nerd_STF.Graphics.CMYKAByte` +- `Nerd_STF.Graphics.HSVA` +- `Nerd_STF.Graphics.HSVAByte` +- `Nerd_STF.Graphics.IColor` +- `Nerd_STF.Graphics.IColorByte` +- `Nerd_STF.Graphics.Image` +- `Nerd_STF.Graphics.RGBA` +- `Nerd_STF.Graphics.RGBAByte` +- `Nerd_STF.Mathematics.Algebra.IMatrix` +- `Nerd_STF.Mathematics.Algebra.Matrix` +- `Nerd_STF.Mathematics.Algebra.Matrix2x2` +- `Nerd_STF.Mathematics.Algebra.Matrix3x3` +- `Nerd_STF.Mathematics.Algebra.Matrix4x4` +- `Nerd_STF.Mathematics.Algebra.Vector2d` +- `Nerd_STF.Mathematics.Algebra.Vector3d` +- `Nerd_STF.Mathematics.Geometry.Box2D` +- `Nerd_STF.Mathematics.Geometry.Box3D` +- `Nerd_STF.Mathematics.Geometry.ISubdividable` +- `Nerd_STF.Mathematics.Geometry.ITriangulatable` +- `Nerd_STF.Mathematics.Geometry.Line` +- `Nerd_STF.Mathematics.Geometry.Polygon` +- `Nerd_STF.Mathematics.Geometry.Quadrilateral` +- `Nerd_STF.Mathematics.Geometry.Sphere` +- `Nerd_STF.Mathematics.Geometry.Triangle` +- `Nerd_STF.Mathematics.Geometry.Vert` + +I've checked a total of 39 types, with 29 left to go. It sounds like I'm over halfway, but really I've saved all of the annoying ones that are likely wrong to be checked next. My 39 done includes a bunch of really simple types that never needed checking in the first place too. But there are some done, like any type in the Mathematics directory. ``` * Nerd_STF - + Extensions - + ConversionExtension - + Container2DExtension - + ToFillExtension - + Foreach - + IGroup2D - + Modifier - + Modifier2D - * IGroup - + ToFill() * Exceptions - + InvalidSizeException - + NoInverseException - * Graphics - * CMYKA - + ToFill() - + static Round(CMYKA) - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * CMYKAByte - + ToFill() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * HSVA - + ToFill() - + static Round(HSVA, Angle.Type) - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * HSVAByte - + ToFill() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Image - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Material - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - = Merged 2 if statements into 1 in `override bool Equals(object?)` - * RGBA - + ToFill() - + ToVector() - + static Round(RGBA) - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * RGBAByte - + ToFill() - + ToVector() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + + MathException + + UndefinedException + * Extensions + + EquationExtension * Mathematics - + Algebra - + IMatrix - + Matrix2x2 - + Matrix3x3 - + Matrix4x4 - + Vector2d - + Vector3d - + NumberSystems - + Complex - + Quaternion - + Samples - + Equations - + ScaleType - = Moved `Constants` file to Samples folder. - * Geometry - * Box2D - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Box3D - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Line - + ToFill() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Polygon - + ToFill() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Quadrilateral - + ToFill() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Sphere - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Triangle - + ToFill() - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - * Vert - + ToFill() - + ToVector() - = Made `Vert(Float2)` not recreate a float group, and instead use itself. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + * NumberSystems + * Complex + + Inverse + + GetAngle() + = Fixed `ToString()` and all overloads from adding a redundant negative sign sometimes in the imaginary component. + = Replaced the `/` operator with a multiplication by its inverse. + * Quaternion + + Inverse + = Fixed `ToString()` and all overloads from adding a redundant negative sign sometimes in the i, j, and k components. + = Replaced the `/` operator with a multiplication by its inverse. + * Algebra + * Vector2d + - static Product(params Vector2d[]) + - static Divide(Vector2d, params Vector2d[]) + - operator *(Vector2d, Angle) + - operator *(Vector2d, Vector2d) + - operator /(Vector2d, Angle) + - operator /(Vector2d, Vector2d) + = Made `ToXYZ()` actually work + * Vector3d + - static Product(params Vector3d[]) + - static Divide(Vector3d, params Vector3d[]) + - operator *(Vector3d, Angle) + - operator *(Vector3d, Vector3d) + - operator /(Vector3d, Angle) + - operator /(Vector3d, Vector3d) + * Calculus + + GetDynamicIntegral(Equation, Equation, Equation, float) + = Made `GetDerivative(Equation, float)` calculate specific values on the fly, and removed the min/max. + * Graphics + * HSVA + - static LerpSquared(HSVA, HSVA, float, Angle.Type, bool = true) + - operator *(HSVA, HSVA) + - operator /(HSVA, HSVA) + * HSVAByte + - static LerpSquared(HSVAByte, HSVAByte, float, Angle.Type, bool = true) * Angle - + static Down - + static Left - + static Right - + static Up - + static Round(Angle, Type) - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + + Reflected + + static Max(bool, params Angle[]) + + static Min(bool, params Angle[]) + - operator *(Angle, Angle) + - operator /(Angle, Angle) + = Made `Angle(float, Type)` use a lambda expression + = Made `Bounded` use the `AbsoluteMod()` function instead of the default `%` expression + = Replaced an accidental `Mathf.Floor()` call with a `Mathf.Round()` call in `Floor()` + = Made `operator -(Angle)` actually give you the reverse angle (not the reflected angle) * Float2 - + ToFill() - + ToVector() - + static Round(Float2) - + implicit operator Float2(Complex) - + explicit operator Float2(Quaternion) - + explicit operator Float2(Matrix) - + operator *(Float2, Matrix) - + operator /(Float2, Matrix) - = Made `Normalized` multiply by the inverse square root instead of dividing by the square root. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + = Made `Median(params Float2)` not use an unneccesary average + = Made `ToVector()` not create an angle out of `ArcTan(float)`, as it already is one + = Optimized `Divide(Float2, params Float2[])` to divide a product instead of individually dividing + = Optimized `Subtract(Float2, params Float2[])` to subtract a sum instead of individually subtracting * Float3 - + ToFill() - + ToVector() - + static Round(Float3) - + implicit operator Float3(Complex) - + explicit operator Float3(Quaternion) - + explicit operator Float3(Matrix) - + operator *(Float3, Matrix) - + operator /(Float3, Matrix) - = Made `Normalized` multiply by the inverse square root instead of dividing by the square root. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + = Made `Median(params Float3)` not use an unneccesary average + = Made `ToVector()` not create an angle out of the arc trig functions, as they already are angles + = Optimized `Divide(Float3, params Float3[])` to divide a product instead of individually dividing + = Optimized `Subtract(Float3, params Float3[])` to subtract a sum instead of individually subtracting * Float4 - + ToFill() - + static Round(Float4) - + implicit operator Float4(Complex) - + implicit operator Float4(Quaternion) - + explicit operator Float4(Matrix) - + operator *(Float4, Matrix) - + operator /(Float4, Matrix) - = Made `Normalized` multiply by the inverse square root instead of dividing by the square root. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` - = Renamed `Float4.Deep` to `Float4.Near` + = Marked `Far` and `Near` as obsolete/deprecated, as they have been replaced by `HighW` and `LowW` + = Made `Median(params Float4)` not use an unneccesary average + = Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing + = Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting * Int2 - + ToFill() - + explicit operator Int2(Complex) - + explicit operator Int2(Quaternion) - + explicit operator Int2(Matrix) - + operator *(Int2, Matrix) - + operator /(Int2, Matrix) - = Made `Normalized` multiply by the inverse square root instead of dividing by the square root. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + = Made `Median(params Float4)` not use an unneccesary average + = Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing + = Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting * Int3 - + ToFill() - + explicit operator Int3(Complex) - + explicit operator Int3(Quaternion) - + explicit operator Int3(Matrix) - + operator *(Int3, Matrix) - + operator /(Int3, Matrix) - = Made `Normalized` multiply by the inverse square root instead of dividing by the square root. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + = Made `Median(params Float4)` not use an unneccesary average + = Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing + = Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting * Int4 - + explicit operator Int4(Complex) - + explicit operator Int4(Quaternion) - + explicit operator Int4(Matrix) - + operator *(Int4, Matrix) - + operator /(Int4, Matrix) - = Made `Normalized` multiply by the inverse square root instead of dividing by the square root. - = Replaced a false statement with `base.Equals(object?)` in `override bool Equals(object?)` + + LowW + = Marked `Far` as obsolete/deprecated, as it has been replaced by `HighW` + = Made `Median(params Float4)` not use an unneccesary average + = Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing + = Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting * Mathf - + Cos(Angle) - + Cot(Angle) - + Csc(Angle) - + Dot(float[], float[]) - + Dot(float[][]) - + Max(T[]) where T : IComparable - + Median(T[]) - + Min(T[]) where T : IComparable - + Sec(Angle) - + Sin(Angle) - + Tan(Angle) - * Miscellaneous - * GlobalUsings.cs - + global using Nerd_STF.Collections - + global using Nerd_STF.Extensions - + global using Nerd_STF.Mathematics.Algebra - + global using Nerd_STF.Mathematics.NumberSystems - + global using Nerd_STF.Mathematics.Samples + + AbsoluteMod(float) + + Binomial(int, int, float) + + Factors(int) + + PowerMod(int, int, int) + = Fixed `Ceiling(float)` from rounding up when it shouldn't + = Made `Median(params float[])` actually calculate the right midpoint + = Removed two unneeded `Average(float, float)` calls in `Median(params float[])` + = Replaced the `Floor(float)` and `Ceiling(float)` calls in `Median(params float[])` with a better alternative + = Replaced the mod in `Sin(float)` with an `AbsoluteMod(float, float)` call + = Made `MadeEquation(Dictionary)` actually work. + = Added caching to Power(float, int) for the absolute max + = Fixed an if statement and added another one to prevent extra computation in `Power(float, int)` + = Added caching to Power(int, int) for the absolute max + = Fixed an if statement and added another one to prevent extra computation in `Power(int, int)` + = Made the `Lerp(int, int, float, bool)` function not call itself infinitely many times. + = Replaced a multiplication with a division in `Root(float, float)` + = Made the `Average(int[])` function give you the int average instead of the float average (unlike `Average(float[])`) + = Replaced the float return statement with an Angle in `ArcCos(float)` + = Replaced the float return statement with an Angle in `ArcCot(float)` + = Replaced the float return statement with an Angle in `ArcCsc(float)` + = Replaced the float return statement with an Angle in `ArcSec(float)` + = Replaced the float return statement with an Angle in `ArcSin(float)` + = Replaced the float return statement with an Angle in `ArcTan(float)` + = Replaced the float return statement with an Angle in `ArcTan2(float, float)` + = Optimized `ArcCos(float)` to use presets + = Optimized `Divide(float, params float[])` to use other functions. + = Optimized `Divide(int, params int[])` to use other functions. + = Optimized `Subtract(float, params float[])` to subtract a sum instead of individually subtracting + = Optimized `Subtract(int, params int[])` to subtract a sum instead of individually subtracting + = Made `Clamp(int, int, int)` not remake code and use `Clamp(float, float, float)` + = Made `Lerp(int, int, float, bool)` cast to an int instead of flooring + = Made `Lerp(float, float, float, bool)` not break when clamping and A is greater than B + = Made `Median(params T[])` not use an unneccesary average + = Made `Power(int, int)` not care about absolutes + = Made `Variance(params float[])` correctly calculate variance. + * Quaternion + = Made `GetAngle()` not create an angle out of `ArcCos(float)`, as it already is one + = Made `ToAngles()` not create angles out of arc trig functions, as they are already angles + * Samples + * Constants + = Swapped `DegToRad` and `RadToDeg` + * Equations + = Moved `static Scale(Equation, float, ScaleType)` to `EquationExtension` + = Moved `ScaleType` to `EquationExtension` ``` diff --git a/Nerd_STF/Exceptions/MathException.cs b/Nerd_STF/Exceptions/MathException.cs new file mode 100644 index 0000000..eee2d3f --- /dev/null +++ b/Nerd_STF/Exceptions/MathException.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; + +namespace Nerd_STF.Exceptions; + +[Serializable] +public class MathException : Nerd_STFException +{ + public MathException() : base() { } + public MathException(string message) : base(message) { } + public MathException(string message, Exception inner) : base(message, inner) { } + protected MathException(SerializationInfo info, StreamingContext context) : base(info, context) { } +} diff --git a/Nerd_STF/Exceptions/UndefinedException.cs b/Nerd_STF/Exceptions/UndefinedException.cs new file mode 100644 index 0000000..e166788 --- /dev/null +++ b/Nerd_STF/Exceptions/UndefinedException.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; + +namespace Nerd_STF.Exceptions; + +[Serializable] +public class UndefinedException : MathException +{ + public UndefinedException() : this("The equation calculated resulted in an undefined number.") { } + public UndefinedException(string message) : base(message) { } + public UndefinedException(string message, Exception inner) : base(message, inner) { } + protected UndefinedException(SerializationInfo info, StreamingContext context) : base(info, context) { } +} diff --git a/Nerd_STF/Extensions/EquationExtension.cs b/Nerd_STF/Extensions/EquationExtension.cs new file mode 100644 index 0000000..f39faf6 --- /dev/null +++ b/Nerd_STF/Extensions/EquationExtension.cs @@ -0,0 +1,19 @@ +namespace Nerd_STF.Extensions; + +public static class EquationExtension +{ + public static Equation Scale(this Equation equ, float value, ScaleType type = ScaleType.Both) => type switch + { + ScaleType.X => x => equ(value / x), + ScaleType.Y => x => x * equ(value), + ScaleType.Both => x => x * equ(value / x), + _ => throw new ArgumentException("Unknown scale type " + type) + }; + + public enum ScaleType + { + X = 1, + Y = 2, + Both = X | Y + } +} diff --git a/Nerd_STF/Graphics/HSVA.cs b/Nerd_STF/Graphics/HSVA.cs index f2b2d0f..455b833 100644 --- a/Nerd_STF/Graphics/HSVA.cs +++ b/Nerd_STF/Graphics/HSVA.cs @@ -112,14 +112,6 @@ public struct HSVA : IColor, IEquatable public static HSVA Lerp(HSVA a, HSVA b, float t, bool clamp = true) => new(Angle.Lerp(a.H, b.H, t, clamp), Mathf.Lerp(a.S, b.S, t, clamp), Mathf.Lerp(a.V, b.V, t, clamp), Mathf.Lerp(a.A, b.A, t, clamp)); - public static HSVA LerpSquared(HSVA a, HSVA b, float t, Angle.Type type = Angle.Type.Normalized, - bool clamp = true) - { - HSVA val = Lerp(a * a, b * b, t, clamp); - float H = Mathf.Sqrt(val.H.ValueFromType(type)), S = Mathf.Sqrt(val.S), V = Mathf.Sqrt(val.V), - A = Mathf.Sqrt(val.A); - return new(new Angle(H, Angle.Type.Normalized), S, V, A); - } public static HSVA Median(params HSVA[] vals) { float index = Mathf.Average(0, vals.Length - 1); @@ -235,9 +227,7 @@ public struct HSVA : IColor, IEquatable public static HSVA operator +(HSVA a, HSVA b) => new(a.H + b.H, a.S + b.S, a.V + b.V, a.A + b.A); public static HSVA operator -(HSVA c) => new(1 - c.H.Normalized, 1 - c.S, 1 - c.V, c.A != 1 ? 1 - c.A : 1); public static HSVA operator -(HSVA a, HSVA b) => new(a.H - b.H, a.S - b.S, a.V - b.V, a.A - b.A); - public static HSVA operator *(HSVA a, HSVA b) => new(a.H * b.H, a.S * b.S, a.V * b.V, a.A * b.A); public static HSVA operator *(HSVA a, float b) => new(a.H * b, a.S * b, a.V * b, a.A * b); - public static HSVA operator /(HSVA a, HSVA b) => new(a.H / b.H, a.S / b.S, a.V / b.V, a.A / b.A); public static HSVA operator /(HSVA a, float b) => new(a.H / b, a.S / b, a.V / b, a.A / b); public static bool operator ==(HSVA a, RGBA b) => a.Equals(b); public static bool operator !=(HSVA a, RGBA b) => !a.Equals(b); diff --git a/Nerd_STF/Graphics/HSVAByte.cs b/Nerd_STF/Graphics/HSVAByte.cs index 2134cdc..8d2bb80 100644 --- a/Nerd_STF/Graphics/HSVAByte.cs +++ b/Nerd_STF/Graphics/HSVAByte.cs @@ -86,8 +86,6 @@ public struct HSVAByte : IColorByte, IEquatable public static HSVAByte Lerp(HSVAByte a, HSVAByte b, byte t, bool clamp = true) => new(Mathf.Lerp(a.H, b.H, t, clamp), Mathf.Lerp(a.S, b.S, t, clamp), Mathf.Lerp(a.V, b.V, t, clamp), Mathf.Lerp(a.A, b.A, t, clamp)); - public static HSVAByte LerpSquared(HSVAByte a, HSVAByte b, byte t, Angle.Type type, bool clamp = true) => - HSVA.LerpSquared(a.ToHSVA(), b.ToHSVA(), t, type, clamp).ToHSVAByte(); public static HSVAByte Median(params HSVAByte[] vals) { float index = Mathf.Average(0, vals.Length - 1); diff --git a/Nerd_STF/Mathematics/Algebra/Vector2d.cs b/Nerd_STF/Mathematics/Algebra/Vector2d.cs index 630959b..36b1831 100644 --- a/Nerd_STF/Mathematics/Algebra/Vector2d.cs +++ b/Nerd_STF/Mathematics/Algebra/Vector2d.cs @@ -40,11 +40,6 @@ public struct Vector2d : ICloneable, IComparable, IEquatable } public static Vector3d Cross(Vector2d a, Vector2d b, bool normalized = false) => Float2.Cross(a.ToXYZ(), b.ToXYZ(), normalized).ToVector(); - public static Vector2d Divide(Vector2d num, params Vector2d[] vals) - { - foreach (Vector2d v in vals) num /= v; - return num; - } public static float Dot(Vector2d a, Vector2d b) => Float2.Dot(a.ToXYZ(), b.ToXYZ()); public static float Dot(params Vector2d[] vals) { @@ -76,13 +71,6 @@ public struct Vector2d : ICloneable, IComparable, IEquatable foreach (Vector2d f in vals) val = f < val ? f : val; return val; } - public static Vector2d Product(params Vector2d[] vals) - { - if (vals.Length < 1) return Zero; - Vector2d val = One; - foreach (Vector2d v in vals) val *= v; - return val; - } public static Vector2d Round(Vector2d val, Angle.Type angleRound = Angle.Type.Degrees) => new(Angle.Round(val.theta, angleRound), Mathf.Round(val.magnitude)); public static Vector2d Subtract(Vector2d num, params Vector2d[] vals) @@ -127,18 +115,14 @@ public struct Vector2d : ICloneable, IComparable, IEquatable public object Clone() => new Vector2d(theta, magnitude); - public Float2 ToXYZ() => new(Mathf.Cos(theta)); + public Float2 ToXYZ() => new Float2(Mathf.Cos(theta), Mathf.Sin(theta)) * magnitude; public static Vector2d operator +(Vector2d a, Vector2d b) => new(a.theta + b.theta, a.magnitude + b.magnitude); public static Vector2d operator -(Vector2d v) => v.Inverse; public static Vector2d operator -(Vector2d a, Vector2d b) => new(a.theta - b.theta, a.magnitude - b.magnitude); - public static Vector2d operator *(Vector2d a, Angle b) => new(a.theta * b, a.magnitude); public static Vector2d operator *(Vector2d a, float b) => new(a.theta, a.magnitude * b); - public static Vector2d operator *(Vector2d a, Vector2d b) => new(a.theta * b.theta, a.magnitude * b.magnitude); public static Vector2d operator *(Vector2d a, Matrix b) => (Vector2d)((Matrix)a * b); - public static Vector2d operator /(Vector2d a, Angle b) => new(a.theta / b, a.magnitude); public static Vector2d operator /(Vector2d a, float b) => new(a.theta, a.magnitude / b); - public static Vector2d operator /(Vector2d a, Vector2d b) => new(a.theta / b.theta, a.magnitude / b.magnitude); public static Vector2d operator /(Vector2d a, Matrix b) => (Vector2d)((Matrix)a / b); public static bool operator ==(Vector2d a, Vector2d b) => a.Equals(b); public static bool operator !=(Vector2d a, Vector2d b) => !a.Equals(b); diff --git a/Nerd_STF/Mathematics/Algebra/Vector3d.cs b/Nerd_STF/Mathematics/Algebra/Vector3d.cs index 6a5393a..8b47cee 100644 --- a/Nerd_STF/Mathematics/Algebra/Vector3d.cs +++ b/Nerd_STF/Mathematics/Algebra/Vector3d.cs @@ -76,11 +76,6 @@ public struct Vector3d : ICloneable, IComparable, IEquatable } public static Vector3d Cross(Vector3d a, Vector3d b, bool normalized = false) => Float3.Cross(a.ToXYZ(), b.ToXYZ(), normalized).ToVector(); - public static Vector3d Divide(Vector3d num, params Vector3d[] vals) - { - foreach (Vector3d v in vals) num /= v; - return num; - } public static float Dot(Vector3d a, Vector3d b) => Float3.Dot(a.ToXYZ(), b.ToXYZ()); public static float Dot(params Vector3d[] vals) { @@ -113,13 +108,6 @@ public struct Vector3d : ICloneable, IComparable, IEquatable foreach (Vector3d f in vals) val = f < val ? f : val; return val; } - public static Vector3d Product(params Vector3d[] vals) - { - if (vals.Length < 1) return Zero; - Vector3d val = One; - foreach (Vector3d v in vals) val *= v; - return val; - } public static Vector3d Round(Vector3d val, Angle.Type angleRound = Angle.Type.Degrees) => new(Angle.Round(val.yaw, angleRound), Angle.Round(val.pitch, angleRound), Mathf.Round(val.magnitude)); public static Vector3d Subtract(Vector3d num, params Vector3d[] vals) @@ -172,15 +160,9 @@ public struct Vector3d : ICloneable, IComparable, IEquatable public static Vector3d operator -(Vector3d v) => v.Inverse; public static Vector3d operator -(Vector3d a, Vector3d b) => new(a.yaw - b.yaw, a.pitch - b.pitch, a.magnitude - b.magnitude); - public static Vector3d operator *(Vector3d a, Angle b) => new(a.yaw * b, a.pitch * b, a.magnitude); public static Vector3d operator *(Vector3d a, float b) => new(a.yaw, a.pitch, a.magnitude * b); - public static Vector3d operator *(Vector3d a, Vector3d b) => new(a.yaw * b.yaw, a.pitch * b.pitch, - a.magnitude * b.magnitude); public static Vector3d operator *(Vector3d a, Matrix b) => (Vector3d)((Matrix)a * b); - public static Vector3d operator /(Vector3d a, Angle b) => new(a.yaw / b, a.pitch / b, a.magnitude); public static Vector3d operator /(Vector3d a, float b) => new(a.yaw, a.pitch, a.magnitude / b); - public static Vector3d operator /(Vector3d a, Vector3d b) => new(a.yaw / b.yaw, a.pitch / b.pitch, - a.magnitude / b.magnitude); public static Vector3d operator /(Vector3d a, Matrix b) => (Vector3d)((Matrix)a / b); public static bool operator ==(Vector3d a, Vector3d b) => a.Equals(b); public static bool operator !=(Vector3d a, Vector3d b) => !a.Equals(b); diff --git a/Nerd_STF/Mathematics/Angle.cs b/Nerd_STF/Mathematics/Angle.cs index 9636ca7..c80ed87 100644 --- a/Nerd_STF/Mathematics/Angle.cs +++ b/Nerd_STF/Mathematics/Angle.cs @@ -34,21 +34,19 @@ public struct Angle : ICloneable, IComparable, IEquatable set => p_deg = value * Constants.RadToDeg; } - public Angle Bounded => new(p_deg % 360); + public Angle Bounded => new(Mathf.AbsoluteMod(p_deg, 360)); + public Angle Reflected => new Angle(-p_deg).Bounded; private float p_deg; - public Angle(float value, Type valueType = Type.Degrees) + public Angle(float value, Type valueType = Type.Degrees) => p_deg = valueType switch { - p_deg = valueType switch - { - Type.Degrees => value, - Type.Gradians => value * 0.9f, - Type.Normalized => value * 360, - Type.Radians => value * Constants.RadToDeg, - _ => throw new ArgumentException("Unknown type.", nameof(valueType)), - }; - } + Type.Degrees => value, + Type.Gradians => value * 0.9f, + Type.Normalized => value * 360, + Type.Radians => value * Constants.RadToDeg, + _ => throw new ArgumentException("Unknown type.", nameof(valueType)), + }; public static Angle Absolute(Angle val) => new(Mathf.Absolute(val.p_deg)); public static Angle Average(params Angle[] vals) => new(Mathf.Average(SplitArray(Type.Degrees, vals))); @@ -59,11 +57,27 @@ public struct Angle : ICloneable, IComparable, IEquatable new(Mathf.Floor(val.ValueFromType(type)), type); public static Angle Lerp(Angle a, Angle b, float t, bool clamp = true) => new(Mathf.Lerp(a.p_deg, b.p_deg, t, clamp)); - public static Angle Max(params Angle[] vals) => new(Mathf.Max(SplitArray(Type.Degrees, vals))); + public static Angle Max(params Angle[] vals) => Max(true, vals); + public static Angle Max(bool useBounded, params Angle[] vals) + { + if (!useBounded) return new(Mathf.Max(SplitArray(Type.Degrees, vals))); + + Angle[] boundeds = new Angle[vals.Length]; + for (int i = 0; i < vals.Length; i++) boundeds[i] = vals[i].Bounded; + return new(Mathf.Max(SplitArray(Type.Degrees, boundeds))); + } public static Angle Median(params Angle[] vals) => new(Mathf.Median(SplitArray(Type.Degrees, vals))); - public static Angle Min(params Angle[] vals) => new(Mathf.Min(SplitArray(Type.Degrees, vals))); + public static Angle Min(params Angle[] vals) => Min(true, vals); + public static Angle Min(bool useBounded, params Angle[] vals) + { + if (!useBounded) return new(Mathf.Min(SplitArray(Type.Degrees, vals))); + + Angle[] boundeds = new Angle[vals.Length]; + for (int i = 0; i < vals.Length; i++) boundeds[i] = vals[i].Bounded; + return new(Mathf.Min(SplitArray(Type.Degrees, boundeds))); + } public static Angle Round(Angle val, Type type = Type.Degrees) => - new(Mathf.Floor(val.ValueFromType(type)), type); + new(Mathf.Round(val.ValueFromType(type)), type); public static float[] SplitArray(Type outputType, params Angle[] vals) { @@ -121,11 +135,9 @@ public struct Angle : ICloneable, IComparable, IEquatable }; public static Angle operator +(Angle a, Angle b) => new(a.p_deg + b.p_deg); - public static Angle operator -(Angle a) => new(-a.p_deg); + public static Angle operator -(Angle a) => new(a.p_deg + 180); public static Angle operator -(Angle a, Angle b) => new(a.p_deg - b.p_deg); - public static Angle operator *(Angle a, Angle b) => new(a.p_deg * b.p_deg); public static Angle operator *(Angle a, float b) => new(a.p_deg * b); - public static Angle operator /(Angle a, Angle b) => new(a.p_deg / b.p_deg); public static Angle operator /(Angle a, float b) => new(a.p_deg / b); public static bool operator ==(Angle a, Angle b) => a.Equals(b); public static bool operator !=(Angle a, Angle b) => !a.Equals(b); diff --git a/Nerd_STF/Mathematics/Calculus.cs b/Nerd_STF/Mathematics/Calculus.cs index a39cc1b..5eba207 100644 --- a/Nerd_STF/Mathematics/Calculus.cs +++ b/Nerd_STF/Mathematics/Calculus.cs @@ -4,16 +4,8 @@ public static class Calculus { public const float DefaultStep = 0.001f; - public static Equation GetDerivative(Equation equ, float min, float max, float step = DefaultStep) - { - Dictionary vals = new(); - for (float x = min; x <= max; x += step) - { - float val1 = equ(x), val2 = equ(x + step), change = (val2 - val1) / step; - vals.Add(x, change); - } - return Mathf.MakeEquation(vals); - } + public static Equation GetDerivative(Equation equ, float step = DefaultStep) => + x => GetDerivativeAtPoint(equ, x, step); public static float GetDerivativeAtPoint(Equation equ, float x, float step = DefaultStep) => (equ(x + DefaultStep) - equ(x)) / step; @@ -24,6 +16,12 @@ public static class Calculus return val; } + public static Equation GetDynamicIntegral(Equation equ, Equation lowerBound, Equation upperBound, + float step = DefaultStep) => x => GetIntegral(equ, lowerBound(x), upperBound(x), step); + + // Unfortunately, I cannot test this function, as I have literally no idea how it works and + // I can't find any tools online (and couldn't make my own) to compare my results. + // Something to know, though I didn't feel like it deserved its own [Obsolete] attribute. public static float GradientDescent(Equation equ, float initial, float rate, float stepCount = 1000, float step = DefaultStep) { diff --git a/Nerd_STF/Mathematics/Float2.cs b/Nerd_STF/Mathematics/Float2.cs index 274ca9b..3f9f29e 100644 --- a/Nerd_STF/Mathematics/Float2.cs +++ b/Nerd_STF/Mathematics/Float2.cs @@ -70,11 +70,7 @@ public struct Float2 : ICloneable, IComparable, IEquatable, IGro } public static Float3 Cross(Float2 a, Float2 b, bool normalized = false) => Float3.Cross(a, b, normalized); - public static Float2 Divide(Float2 num, params Float2[] vals) - { - foreach (Float2 f in vals) num /= f; - return num; - } + public static Float2 Divide(Float2 num, params Float2[] vals) => num / Product(vals); public static float Dot(Float2 a, Float2 b) => a.x * b.x + a.y * b.y; public static float Dot(params Float2[] vals) { @@ -93,9 +89,9 @@ public struct Float2 : ICloneable, IComparable, IEquatable, IGro new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp)); public static Float2 Median(params Float2[] vals) { - float index = Mathf.Average(0, vals.Length - 1); + float index = (vals.Length - 1) * 0.5f; Float2 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)]; - return Average(valA, valB); + return (valA + valB) * 0.5f; } public static Float2 Max(params Float2[] vals) { @@ -120,11 +116,7 @@ public struct Float2 : ICloneable, IComparable, IEquatable, IGro } public static Float2 Round(Float2 val) => new(Mathf.Round(val.x), Mathf.Round(val.y)); - public static Float2 Subtract(Float2 num, params Float2[] vals) - { - foreach (Float2 f in vals) num -= f; - return num; - } + public static Float2 Subtract(Float2 num, params Float2[] vals) => num - Sum(vals); public static Float2 Sum(params Float2[] vals) { Float2 val = Zero; @@ -174,7 +166,7 @@ public struct Float2 : ICloneable, IComparable, IEquatable, IGro } public List ToList() => new() { x, y }; - public Vector2d ToVector() => new(new(Mathf.ArcTan(y / x), Angle.Type.Radians), Magnitude); + public Vector2d ToVector() => new(Mathf.ArcTan(y / x), Magnitude); public static Float2 operator +(Float2 a, Float2 b) => new(a.x + b.x, a.y + b.y); public static Float2 operator -(Float2 d) => new(-d.x, -d.y); diff --git a/Nerd_STF/Mathematics/Float3.cs b/Nerd_STF/Mathematics/Float3.cs index 08dd48d..9d28ee4 100644 --- a/Nerd_STF/Mathematics/Float3.cs +++ b/Nerd_STF/Mathematics/Float3.cs @@ -89,11 +89,7 @@ public struct Float3 : ICloneable, IComparable, IEquatable, IGro a.x * b.y - b.x * a.y); return normalized ? val.Normalized : val; } - public static Float3 Divide(Float3 num, params Float3[] vals) - { - foreach (Float3 d in vals) num /= d; - return num; - } + public static Float3 Divide(Float3 num, params Float3[] vals) => num / Product(vals); public static float Dot(Float3 a, Float3 b) => a.x * b.x + a.y * b.y + a.z * b.z; public static float Dot(params Float3[] vals) { @@ -113,9 +109,9 @@ public struct Float3 : ICloneable, IComparable, IEquatable, IGro new(Mathf.Lerp(a.x, b.x, t, clamp), Mathf.Lerp(a.y, b.y, t, clamp), Mathf.Lerp(a.z, b.z, t, clamp)); public static Float3 Median(params Float3[] vals) { - float index = Mathf.Average(0, vals.Length - 1); + float index = (vals.Length - 1) * 0.5f; Float3 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)]; - return Average(valA, valB); + return (valA + valB) * 0.5f; } public static Float3 Max(params Float3[] vals) { @@ -140,11 +136,7 @@ public struct Float3 : ICloneable, IComparable, IEquatable, IGro } public static Float3 Round(Float3 val) => new(Mathf.Round(val.x), Mathf.Round(val.y), Mathf.Round(val.z)); - public static Float3 Subtract(Float3 num, params Float3[] vals) - { - foreach (Float3 d in vals) num -= d; - return num; - } + public static Float3 Subtract(Float3 num, params Float3[] vals) => num - Sum(vals); public static Float3 Sum(params Float3[] vals) { Float3 val = Zero; @@ -199,7 +191,7 @@ public struct Float3 : ICloneable, IComparable, IEquatable, IGro public Vector3d ToVector() { float mag = Magnitude; - return new(new Angle(Mathf.ArcTan(y / x), Angle.Type.Radians), new(Mathf.ArcCos(z / mag), Angle.Type.Radians), mag); + return new(Mathf.ArcTan(y / x), Mathf.ArcCos(z / mag), mag); } public static Float3 operator +(Float3 a, Float3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z); diff --git a/Nerd_STF/Mathematics/Float4.cs b/Nerd_STF/Mathematics/Float4.cs index 7c80274..54ea508 100644 --- a/Nerd_STF/Mathematics/Float4.cs +++ b/Nerd_STF/Mathematics/Float4.cs @@ -4,9 +4,15 @@ public struct Float4 : ICloneable, IComparable, IEquatable, IGro { public static Float4 Back => new(0, 0, -1, 0); public static Float4 Down => new(0, -1, 0, 0); + [Obsolete("Field has been replaced by " + nameof(HighW) + ", because it has a better name. " + + "This field will be removed in v2.4.0.", false)] public static Float4 Far => new(0, 0, 0, 1); public static Float4 Forward => new(0, 0, 1, 0); + public static Float4 HighW => new(0, 0, 0, 1); public static Float4 Left => new(-1, 0, 0, 0); + public static Float4 LowW => new(0, 0, 0, -1); + [Obsolete("Field has been replaced by " + nameof(LowW) + ", because it has a better name. " + + "This field will be removed in v2.4.0.", false)] public static Float4 Near => new(0, 0, 0, -1); public static Float4 Right => new(1, 0, 0, 0); public static Float4 Up => new(0, 1, 0, 0); @@ -100,11 +106,7 @@ public struct Float4 : ICloneable, IComparable, IEquatable, IGro else if (mag > maxMag) val *= maxMag; return val; } - public static Float4 Divide(Float4 num, params Float4[] vals) - { - foreach (Float4 d in vals) num /= d; - return num; - } + public static Float4 Divide(Float4 num, params Float4[] vals) => num / Product(vals); public static float Dot(Float4 a, Float4 b) => a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; public static float Dot(params Float4[] vals) { @@ -126,9 +128,9 @@ public struct Float4 : ICloneable, IComparable, IEquatable, IGro Mathf.Lerp(a.w, b.w, t, clamp)); public static Float4 Median(params Float4[] vals) { - float index = Mathf.Average(0, vals.Length - 1); + float index = (vals.Length - 1) * 0.5f; Float4 valA = vals[Mathf.Floor(index)], valB = vals[Mathf.Ceiling(index)]; - return Average(valA, valB); + return (valA + valB) * 0.5f; } public static Float4 Max(params Float4[] vals) { @@ -153,11 +155,7 @@ public struct Float4 : ICloneable, IComparable, IEquatable, IGro foreach (Float4 d in vals) val *= d; return val; } - public static Float4 Subtract(Float4 num, params Float4[] vals) - { - foreach (Float4 d in vals) num -= d; - return num; - } + public static Float4 Subtract(Float4 num, params Float4[] vals) => num - Sum(vals); public static Float4 Sum(params Float4[] vals) { Float4 val = Zero; diff --git a/Nerd_STF/Mathematics/Int2.cs b/Nerd_STF/Mathematics/Int2.cs index ce62c13..aefd30e 100644 --- a/Nerd_STF/Mathematics/Int2.cs +++ b/Nerd_STF/Mathematics/Int2.cs @@ -67,11 +67,7 @@ public struct Int2 : ICloneable, IComparable, IEquatable, IGroup 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 Int2 Divide(Int2 num, params Int2[] vals) => num / Product(vals); public static int Dot(Int2 a, Int2 b) => a.x * b.x + a.y * b.y; public static int Dot(params Int2[] vals) { @@ -88,9 +84,9 @@ public struct Int2 : ICloneable, IComparable, IEquatable, IGroup, IEquatable, IGroup num - Sum(vals); public static Int2 Sum(params Int2[] vals) { Int2 val = Zero; diff --git a/Nerd_STF/Mathematics/Int3.cs b/Nerd_STF/Mathematics/Int3.cs index e023215..7b47634 100644 --- a/Nerd_STF/Mathematics/Int3.cs +++ b/Nerd_STF/Mathematics/Int3.cs @@ -86,11 +86,7 @@ public struct Int3 : ICloneable, IComparable, IEquatable, IGroup num / Product(vals); 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) { @@ -108,9 +104,9 @@ public struct Int3 : ICloneable, IComparable, IEquatable, IGroup, IEquatable, IGroup num - Sum(vals); public static Int3 Sum(params Int3[] vals) { Int3 val = Zero; diff --git a/Nerd_STF/Mathematics/Int4.cs b/Nerd_STF/Mathematics/Int4.cs index 2007bbc..192d98a 100644 --- a/Nerd_STF/Mathematics/Int4.cs +++ b/Nerd_STF/Mathematics/Int4.cs @@ -5,9 +5,13 @@ public struct Int4 : ICloneable, IComparable, IEquatable, IGroup new(0, 0, -1, 0); public static Int4 Deep => new(0, 0, 0, -1); public static Int4 Down => new(0, -1, 0, 0); + [Obsolete("Field has been replaced by " + nameof(HighW) + ", because it has a better name. " + + "This field will be removed in v2.4.0.", false)] public static Int4 Far => new(0, 0, 0, 1); public static Int4 Forward => new(0, 0, 1, 0); + public static Int4 HighW => new(0, 0, 0, 1); public static Int4 Left => new(-1, 0, 0, 0); + public static Int4 LowW => new(0, 0, 0, -1); public static Int4 Right => new(1, 0, 0, 0); public static Int4 Up => new(0, 1, 0, 0); @@ -97,11 +101,7 @@ public struct Int4 : ICloneable, IComparable, IEquatable, IGroup 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 Int4 Divide(Int4 num, params Int4[] vals) => num / Product(vals); 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) { @@ -121,9 +121,9 @@ public struct Int4 : ICloneable, IComparable, IEquatable, IGroup, IEquatable, IGroup num - Sum(vals); public static Int4 Sum(params Int4[] vals) { Int4 val = Zero; diff --git a/Nerd_STF/Mathematics/Mathf.cs b/Nerd_STF/Mathematics/Mathf.cs index ec73c8a..bebb2ad 100644 --- a/Nerd_STF/Mathematics/Mathf.cs +++ b/Nerd_STF/Mathematics/Mathf.cs @@ -5,19 +5,32 @@ public static class Mathf public static float Absolute(float val) => val < 0 ? -val : val; public static int Absolute(int val) => val < 0 ? -val : val; - public static float ArcCos(float value) => -ArcSin(value) + Constants.HalfPi; + public static float AbsoluteMod(float val, float mod) + { + while (val >= mod) val -= mod; + while (val < 0) val += mod; + return val; + } + public static int AbsoluteMod(int val, int mod) + { + while (val >= mod) val -= mod; + while (val < 0) val += mod; + return val; + } - public static float ArcCot(float value) => ArcCos(value / Sqrt(1 + value * value)); + public static Angle ArcCos(float value) => ArcSin(-value) + Angle.Quarter; - public static float ArcCsc(float value) => ArcSin(1 / value); + public static Angle ArcCot(float value) => ArcCos(value / Sqrt(1 + value * value)); - public static float ArcSec(float value) => ArcCos(1 / value); + public static Angle ArcCsc(float value) => ArcSin(1 / value); + + public static Angle ArcSec(float value) => ArcCos(1 / value); // Maybe one day I'll have a polynomial for this, but the RMSE for an order 10 polynomial is only 0.00876. - public static float ArcSin(float value) => (float)Math.Asin(value); - - public static float ArcTan(float value) => ArcSin(value / Sqrt(1 + value * value)); - public static float ArcTan2(float a, float b) => ArcTan(a / b); + public static Angle ArcSin(float value) => new((float)Math.Asin(value), Angle.Type.Radians); + + public static Angle ArcTan(float value) => ArcSin(value / Sqrt(1 + value * value)); + public static Angle ArcTan2(float a, float b) => ArcTan(a / b); public static float Average(Equation equ, float min, float max, float step = Calculus.DefaultStep) { @@ -26,9 +39,16 @@ public static class Mathf return Average(vals.ToArray()); } public static float Average(params float[] vals) => Sum(vals) / vals.Length; - public static float Average(params int[] vals) => Sum(vals) / (float)vals.Length; + public static int Average(params int[] vals) => Sum(vals) / vals.Length; - public static int Ceiling(float val) => (int)(val + (1 - (val % 1))); + public static float Binomial(int n, int total, float successRate) => + Combinations(total, n) * Power(successRate, n) * Power(1 - successRate, total - n); + + public static int Ceiling(float val) + { + float mod = val % 1; + return (int)(mod == 0 ? val : (val + (1 - mod))); + } public static float Clamp(float val, float min, float max) { @@ -38,14 +58,7 @@ public static class Mathf 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 int Clamp(int val, int min, int max) => (int)Clamp((float)val, min, max); // nCr (n = total, r = size) public static int Combinations(int total, int size) => Factorial(total) / @@ -60,16 +73,8 @@ public static class Mathf public static float Csc(Angle angle) => Csc(angle.Radians); public static float Csc(float radians) => 1 / Sin(radians); - public static float Divide(float val, params float[] dividends) - { - foreach (float 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 float Divide(float val, params float[] dividends) => val / Product(dividends); + public static int Divide(int val, params int[] dividends) => val / Product(dividends); public static float Dot(float[] a, float[] b) { @@ -98,6 +103,15 @@ public static class Mathf return val; } + public static int[] Factors(int val) + { + List factors = new(); + factors.Add(1); + for (int i = 2; i < val; i++) if (val % i == 0) factors.Add(i); + factors.Add(val); + return factors.ToArray(); + } + public static int Floor(float val) => (int)(val - (val % 1)); public static Dictionary GetValues(Equation equ, float min, float max, @@ -127,23 +141,51 @@ public static class Mathf public static float Lerp(float a, float b, float t, bool clamp = true) { float v = a + t * (b - a); - if (clamp) v = Clamp(v, a, b); + if (clamp) v = Clamp(v, Min(a, b), Max(a, b)); return v; } - public static int Lerp(int a, int b, float value, bool clamp = true) => Floor(Lerp(a, b, value, clamp)); + public static int Lerp(int a, int b, float value, bool clamp = true) => (int)Lerp((float)a, b, value, clamp); - public static Equation MakeEquation(Dictionary vals) => (x) => + public static Equation MakeEquation(Dictionary vals) => delegate (float x) { - float min = -1, max = -1; - foreach (KeyValuePair val in vals) - { - if (val.Key <= x) min = val.Key; - if (val.Key >= x) max = val.Key; + if (vals.Count < 1) throw new UndefinedException(); + if (vals.Count == 1) return vals.Values.First(); - if (min != -1 && max != -1) break; + if (vals.ContainsKey(x)) return vals[x]; + float? min, max; + + if (x < (min = vals.Keys.Min())) + { + max = vals.Keys.Where(x => x != min).Min(); + float distX = x - min.Value, distAB = max.Value - min.Value; + return Lerp(vals[min.Value], vals[max.Value], distX / distAB, false); } - float per = x % (max - min); - return Lerp(min, max, per); + else if (x > (max = vals.Keys.Max())) + { + min = vals.Keys.Where(x => x != max).Max(); + float distX = x - min.Value, distAB = max.Value - min.Value; + return Lerp(vals[min.Value], vals[max.Value], distX / distAB, false); + } + + float curDistMax = float.MaxValue, curDistMin = float.MaxValue; + foreach (float keyX in vals.Keys) + { + float dist = Absolute(keyX - x); + if (keyX < x && dist <= curDistMin) + { + min = keyX; + curDistMin = dist; + } + if (keyX > x && dist <= curDistMax) + { + max = keyX; + curDistMax = dist; + } + } + + if (!min.HasValue || !max.HasValue || min == max) throw new UndefinedException(); + float all = max.Value - min.Value, diff = x - min.Value; + return Lerp(vals[min.Value], vals[max.Value], diff / all); }; public static float Max(Equation equ, float min, float max, float step = Calculus.DefaultStep) @@ -180,12 +222,13 @@ public static class Mathf public static float Median(params float[] vals) { - float index = Average(0, vals.Length - 1); - float valA = vals[Floor(index)], valB = vals[Ceiling(index)]; - return Average(valA, valB); + float index = (vals.Length - 1) * 0.5f; + if (index % 1 == 0) return vals[(int)index]; + float valA = vals[(int)index], valB = vals[(int)index + 1]; + return (valA + valB) * 0.5f; } public static int Median(params int[] vals) => Median(vals); - public static T Median(params T[] vals) => vals[Floor(Average(0, vals.Length - 1))]; + public static T Median(params T[] vals) => vals[(vals.Length - 1) / 2]; public static float Min(Equation equ, float min, float max, float step = Calculus.DefaultStep) { @@ -262,22 +305,34 @@ public static class Mathf public static float Power(float num, float pow) => (float)Math.Pow(num, pow); public static float Power(float num, int pow) { - if (pow < 0) return 0; + if (pow <= 0) return 0; + if (pow == 1) return num; float val = 1; - for (int i = 0; i < Absolute(pow); i++) val *= num; + float abs = Absolute(pow); + for (int i = 0; i < abs; i++) val *= num; if (pow < 1) val = 1 / val; return val; } public static int Power(int num, int pow) { - if (pow < 0) return 0; + if (pow == 1) return num; + if (pow < 1) return 0; int val = 1; - for (int i = 0; i < Absolute(pow); i++) val *= num; - if (pow < 1) val = 1 / val; + for (int i = 0; i < pow; i++) val *= num; return val; } - public static float Root(float value, float index) => (float)Math.Exp(index * Math.Log(value)); + public static int PowerMod(int num, int pow, int mod) + { + if (pow == 1) return num; + if (pow < 1) return 0; + int val = 1; + int abs = Absolute(pow); + for (int i = 0; i < abs; i++) val = val * num % mod; + return val; + } + + public static float Root(float value, float index) => (float)Math.Exp(Math.Log(value) / index); public static float Round(float num) => num % 1 >= 0.5 ? Ceiling(num) : Floor(num); public static float Round(float num, float nearest) => nearest * Round(num / nearest); @@ -300,7 +355,7 @@ public static class Mathf h = -0.000577413f, i = 0.0000613134f, j = -0.00000216852f; - float x = radians % Constants.Tau; + float x = AbsoluteMod(radians, Constants.Tau); return a + (b * x) + (c * x * x) + (d * x * x * x) + (e * x * x * x * x) + (f * x * x * x * x * x) @@ -310,16 +365,8 @@ public static class Mathf public static float Sqrt(float value) => Root(value, 2); - public static float Subtract(float num, params float[] vals) - { - foreach (float 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 float Subtract(float num, params float[] vals) => num - Sum(vals); + public static int Subtract(int num, params int[] vals) => num - Sum(vals); public static float Sum(params float[] vals) { @@ -361,7 +408,7 @@ public static class Mathf float val = vals[i] - mean; sum += val * val; } - return sum / vals.Length; + return sum / (vals.Length - 1); } public static float ZScore(float val, params float[] vals) => ZScore(val, Average(vals), StandardDeviation(vals)); diff --git a/Nerd_STF/Mathematics/NumberSystems/Complex.cs b/Nerd_STF/Mathematics/NumberSystems/Complex.cs index 94a2bc5..fa4db6a 100644 --- a/Nerd_STF/Mathematics/NumberSystems/Complex.cs +++ b/Nerd_STF/Mathematics/NumberSystems/Complex.cs @@ -11,6 +11,7 @@ public struct Complex : ICloneable, IComparable, IEquatable, I public static Complex Zero => new(0, 0); public Complex Conjugate => new(u, -i); + public Complex Inverse => Conjugate / (u * u + i * i); public float Magnitude => Mathf.Sqrt(u * u + i * i); public Complex Normalized => this * Mathf.InverseSqrt(u * u + i * i); @@ -125,6 +126,8 @@ public struct Complex : ICloneable, IComparable, IEquatable, I return (Us, Is); } + public Angle GetAngle() => Mathf.ArcTan(i / u); + public int CompareTo(Complex other) => Magnitude.CompareTo(other.Magnitude); public override bool Equals([NotNullWhen(true)] object? obj) { @@ -135,9 +138,9 @@ public struct Complex : ICloneable, IComparable, IEquatable, I public override int GetHashCode() => u.GetHashCode() ^ i.GetHashCode(); public override string ToString() => ToString((string?)null); public string ToString(string? provider) => - u.ToString(provider) + (i >= 0 ? " + " : " - ") + i.ToString(provider) + "i"; + u.ToString(provider) + (i >= 0 ? " + " : " - ") + Mathf.Absolute(i).ToString(provider) + "i"; public string ToString(IFormatProvider provider) => - u.ToString(provider) + (i >= 0 ? " + " : " - ") + i.ToString(provider) + "i"; + u.ToString(provider) + (i >= 0 ? " + " : " - ") + Mathf.Absolute(i).ToString(provider) + "i"; public object Clone() => new Complex(u, i); @@ -164,11 +167,7 @@ public struct Complex : ICloneable, IComparable, IEquatable, I public static Complex operator *(Complex a, Complex b) => new(a.u * b.u - a.i * b.i, a.u * b.i + a.i * b.u); public static Complex operator *(Complex a, float b) => new(a.u * b, a.i * b); public static Complex operator *(Complex a, Matrix b) => (Complex)((Matrix)a * b); - public static Complex operator /(Complex a, Complex b) - { - float c = b.u * b.u + b.i * b.i; - return new((a.u * b.u + a.i * b.i) / c, (a.i * b.u - a.u * b.i) / c); - } + public static Complex operator /(Complex a, Complex b) => a * b.Inverse; public static Complex operator /(Complex a, float b) => new(a.u / b, a.i / b); public static Complex operator /(Complex a, Matrix b) => (Complex)((Matrix)a / b); public static bool operator ==(Complex a, Complex b) => a.Equals(b); diff --git a/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs b/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs index 7ef32ec..d3eba84 100644 --- a/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs +++ b/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs @@ -15,6 +15,7 @@ public struct Quaternion : ICloneable, IComparable, IEquatable new(0, 0, 0, 0); public Quaternion Conjugate => new(u, -i, -j, -k); + public Quaternion Inverse => Conjugate / (u * u + i * i + j * j + k * k); public float Magnitude => Mathf.Sqrt(u * u + i * i + j * j + k * k); public Quaternion Normalized => this * Mathf.InverseSqrt(u * u + i * i + j * j + k * k); @@ -135,6 +136,7 @@ public struct Quaternion : ICloneable, IComparable, IEquatable, IEquatable FromAngles(new(vals.x, valType), new(vals.y, valType), new(vals.z, valType)); + [Obsolete("This method does not produce the correct output. Please update to a newer release.")] public static Quaternion FromVector(Vector3d vec) => FromAngles(vec.yaw, vec.pitch); public static (float[] Us, float[] Is, float[] Js, float[] Ks) SplitArray(params Quaternion[] vals) @@ -179,17 +183,19 @@ public struct Quaternion : ICloneable, IComparable, IEquatable u.GetHashCode() ^ i.GetHashCode() ^ j.GetHashCode() ^ k.GetHashCode(); public override string ToString() => ToString((string?)null); public string ToString(string? provider) => u.ToString(provider) - + (i >= 0 ? " + " : " - ") + i.ToString(provider) + "i" - + (j >= 0 ? " + " : " - ") + j.ToString(provider) + "j" - + (k >= 0 ? " + " : " - ") + k.ToString(provider) + "k"; + + (i >= 0 ? " + " : " - ") + Mathf.Absolute(i).ToString(provider) + "i" + + (j >= 0 ? " + " : " - ") + Mathf.Absolute(j).ToString(provider) + "j" + + (k >= 0 ? " + " : " - ") + Mathf.Absolute(k).ToString(provider) + "k"; public string ToString(IFormatProvider provider) => u.ToString(provider) - + (i >= 0 ? " + " : " - ") + i.ToString(provider) + "i" - + (j >= 0 ? " + " : " - ") + j.ToString(provider) + "j" - + (k >= 0 ? " + " : " - ") + k.ToString(provider) + "k"; + + (i >= 0 ? " + " : " - ") + Mathf.Absolute(i).ToString(provider) + "i" + + (j >= 0 ? " + " : " - ") + Mathf.Absolute(j).ToString(provider) + "j" + + (k >= 0 ? " + " : " - ") + Mathf.Absolute(k).ToString(provider) + "k"; public object Clone() => new Quaternion(u, i, j, k); - public Angle GetAngle() => new(2 * Mathf.ArcCos(u), Angle.Type.Radians); + [Obsolete("This method does not produce the correct output. Please update to a newer release.")] + public Angle GetAngle() => Mathf.ArcCos(u) * 2; + [Obsolete("This method does not produce the correct output. Please update to a newer release.")] public Float3 GetAxis() { Float3 axis = IJK; @@ -198,6 +204,7 @@ public struct Quaternion : ICloneable, IComparable, IEquatable, IEquatable, IEquatable new(a.u * b, a.i * b, a.j * b, a.k * b); public static Quaternion operator *(Quaternion a, Matrix b) => (Quaternion)((Matrix)a * b); public static Quaternion operator *(Quaternion a, Float3 b) => a * new Quaternion(b); - public static Quaternion operator /(Quaternion x, Quaternion y) - { - float a = x.u, b = x.i, c = x.j, d = x.k, e = y.u, f = y.i, g = y.j, h = y.k, - u = a * e + b * f + c * g + d * h, - i = b * e + c * h + d * g - a * f, - j = c * e + d * f - a * g - b * h, - k = c * f + d * e - a * h - b * g, - q = e * e + f * f + g * g + h * h; - return new(u / q, i / q, j / q, k / q); - } + public static Quaternion operator /(Quaternion x, Quaternion y) => x * y.Inverse; public static Quaternion operator /(Quaternion a, float b) => new(a.u / b, a.i / b, a.j / b, a.k / b); public static Quaternion operator /(Quaternion a, Matrix b) => (Quaternion)((Matrix)a / b); public static Quaternion operator /(Quaternion a, Float3 b) => a / new Quaternion(b); diff --git a/Nerd_STF/Mathematics/Samples/Constants.cs b/Nerd_STF/Mathematics/Samples/Constants.cs index 096f5d4..6b916c7 100644 --- a/Nerd_STF/Mathematics/Samples/Constants.cs +++ b/Nerd_STF/Mathematics/Samples/Constants.cs @@ -2,10 +2,10 @@ public static class Constants { - public const float DegToRad = 180 / Pi; + public const float DegToRad = Pi / 180; public const float HalfPi = Pi / 2; public const float Pi = 3.14159265359f; - public const float RadToDeg = Pi / 180; + public const float RadToDeg = 180 / Pi; public const float Tau = Pi * 2; public const float E = 2.71828182846f; diff --git a/Nerd_STF/Mathematics/Samples/Equations.cs b/Nerd_STF/Mathematics/Samples/Equations.cs index 1ded66e..033622d 100644 --- a/Nerd_STF/Mathematics/Samples/Equations.cs +++ b/Nerd_STF/Mathematics/Samples/Equations.cs @@ -8,19 +8,4 @@ public static class Equations public static readonly Equation SinWave = x => Mathf.Sin(x); public static readonly Equation SawWave = x => x % 1; public static readonly Equation SquareWave = x => x % 2 < 1 ? 1 : 0; - - public static Equation Scale(Equation equ, float value, ScaleType type = ScaleType.Both) => type switch - { - ScaleType.X => x => equ(value / x), - ScaleType.Y => x => x * equ(value), - ScaleType.Both => x => x * equ(value / x), - _ => throw new ArgumentException("Unknown scale type " + type) - }; - - public enum ScaleType - { - X = 1, - Y = 2, - Both = X | Y - } } diff --git a/Nerd_STF/bin/Release/net6.0/ref/Nerd_STF.dll b/Nerd_STF/bin/Release/net6.0/ref/Nerd_STF.dll index 3020460b25091546c55797c750ae0cee78803ab6..33252d88f621d5c17de6225e6b2f70ce6ddc3199 100644 GIT binary patch literal 112640 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
nHfscv3~%zpJc4XuN|BT3XFv# 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 literal 111616 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

5u!*<7$cEsl8wa|rm_wl@zB+R>}Mkmx= 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

jma|i9Sp87SV&EheeNoDSx^*iPG&5`+(?s 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 -- 2.49.0.windows.1