v2.3.1 #17
224
Changelog.md
224
Changelog.md
@ -1,150 +1,106 @@
|
||||
# Nerd_STF v2.3.1.52
|
||||
# Nerd_STF v2.3.1
|
||||
|
||||
***Read this to know what works and what doesn't!***
|
||||
***Everything has been tested and most things work!***
|
||||
|
||||
**WARNING:**
|
||||
All of the matrix classes have had all of their constructors' row and column variables swapped. You'll have to switch all your variables around.
|
||||
Sorry for the inconvenience :(.
|
||||
|
||||
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.Container2DExtension`
|
||||
- `Nerd_STF.Extensions.ConversionExtension`
|
||||
- `Nerd_STF.Extensions.EquationExtension`
|
||||
- `Nerd_STF.Extensions.ToFillExtension`
|
||||
- `Nerd_STF.Graphics.CMYKA`
|
||||
- `Nerd_STF.Graphics.CMYKAByte`
|
||||
- `Nerd_STF.Graphics.ColorChannel`
|
||||
- `Nerd_STF.Graphics.HSVA`
|
||||
- `Nerd_STF.Graphics.HSVAByte`
|
||||
- `Nerd_STF.Graphics.IColor`
|
||||
- `Nerd_STF.Graphics.IColorByte`
|
||||
- `Nerd_STF.Graphics.IlluminationFlags`
|
||||
- `Nerd_STF.Graphics.IlluminationModel`
|
||||
- `Nerd_STF.Graphics.Image`
|
||||
- `Nerd_STF.Graphics.Material`
|
||||
- `Nerd_STF.Graphics.RGBA`
|
||||
- `Nerd_STF.Graphics.RGBAByte`
|
||||
- `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.Geometry.ISubdividable`
|
||||
- `Nerd_STF.Mathematics.NumberSystems.Complex`
|
||||
- `Nerd_STF.Mathematics.NumberSystems.Quaternion`
|
||||
- `Nerd_STF.Mathematics.Samples.Constants`
|
||||
- `Nerd_STF.Mathematics.Samples.Equations`
|
||||
Hi everyone! Everything has been checked now and most stuff works! Not everything, like the triangle and quadrilateral area stuff, but for the most part, it's all cool and good.
|
||||
|
||||
The following types haven't been checked yet, and should still be taken with a grain of salt:
|
||||
- `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.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 just now remembered how bad the Polygon struct was. It's getting remade. The v2.4.0 update will be mostly geometry focused, so that'll be the best time to figure out how to fix this stuff. The new Polygon struct will be much better, trust me.
|
||||
|
||||
16 left to go.
|
||||
But all the matrix structs work like charm now! I'm honestly suprised they worked as well as they did before (especially the dynamic matrix). They can now be relied on.
|
||||
|
||||
Honestly, most of the time taken for this update was spent on Quaternions. Turns out my multiply function was subtley wrong. Who knew!
|
||||
Just a relief to be done with it. The other stuff wasn't too much of a problem. Matrixes are probably going to be a huge pain if they don't work first try, though. That'll be in the next update, probably.
|
||||
|
||||
I should also note that I just realized after way to long that the `.csproj` file isn't included in the Github. It's included in this new release, and sometime in the future I'll go back and add a correctly working `.csproj` file to all the other releases as well (with the exception of the legacy Nerd_STF 2021 versions likely. We'll see). I'll now not include the `/bin` build files. They'll be in the release and you can build it yourself if you need to now. Anyway, have fun.
|
||||
Next up is the documentation update. Stay tuned!
|
||||
(This may be another update with beta parts, but I'm not sure yet. We'll see).
|
||||
|
||||
```
|
||||
* Nerd_STF
|
||||
* Exceptions
|
||||
* DifferingVertCountException
|
||||
= Marked as deprecated (uses deprecated struct `Polygon`)
|
||||
* Extensions
|
||||
* Container2DExtension
|
||||
= Fixed `Flatten<T>(T[,], Int2)`
|
||||
= `GetColumn<T>(T[,], int, int)` and `GetRow<T>(T[,], int, int)` have been fixed (They had swapped roles)
|
||||
* ConversionExtension
|
||||
+ ToFill<T>(T[])
|
||||
+ ToFill<T>(T[,], Int2)
|
||||
+ ToFill2D<T>(T[,])
|
||||
* EquationExtension
|
||||
= Fixed `Scale(Equation, float, ScaleType)` by swapping all instances of `x` and `value` (oops)
|
||||
= Moved `ScaleType` out of parent class `EquationExtension` and into namespace `Nerd_STF`
|
||||
* Geometry
|
||||
* ITriangulatable
|
||||
+ TriangulateAll<T>(T[]) where T : ITriangulatable
|
||||
* Graphics
|
||||
+ Renamed `IColor` to `IColorFloat`
|
||||
= Made IColor an object both `IColorFloat` and `IColorByte` inherit from.
|
||||
* CMYKA
|
||||
= Made `ToRGBA()` include the alpha value of the color.
|
||||
* CMYKAByte
|
||||
= In `ToHSVA()` and `ToHSVAByte()`, swapped some conversions from `RGBA` to `CMYKA`
|
||||
* HSVA
|
||||
= Made `ToRGBA()` include the alpha value of the color.
|
||||
* Image
|
||||
- Removed some useless constructors
|
||||
= Fixed some broken constructors
|
||||
+ GetSize<T>(T[,])
|
||||
+ SwapDimensions<T>(T[,], Int2?)
|
||||
* Flatten<T>(T[,])
|
||||
= Replaced a `size` parameter from an `Int2` to an `Int2?`
|
||||
* Mathematics
|
||||
* Algebra
|
||||
* Vector2d
|
||||
= Removed a default parameter value in `ToString(Angle.Type)` to prevent confusion.
|
||||
* Vector3d
|
||||
+ string ToString()
|
||||
+ string ToString(Angle.Type)
|
||||
+ string ToString(IFormatProvider, Angle.Type)
|
||||
= Fixed `ToXYZ()`
|
||||
* NumberSystems
|
||||
* Complex
|
||||
+ operator ~(Complex)
|
||||
* Quaternion
|
||||
+ Rotate(Float3)
|
||||
+ Rotate(Vector3d)
|
||||
+ operator ~(Quaternion)
|
||||
- ToVector()
|
||||
= Gave `IJK` proper get and set accessors.
|
||||
= Renamed some terms in `ToString()`
|
||||
= Fixed the `Quaternion.FromAngles(*)` methods to do the proper thing.
|
||||
= Fixed `Quaternion.Rotate(Quaternion)`
|
||||
= Fixed `Quaternion.Rotate(Float3)`
|
||||
= Fixed `operator *(Quaternion, Quaternion)`
|
||||
= Optimized `GetAxis()`
|
||||
= Simplified `ToXYZ()`
|
||||
= Swapped the order of `Rotate(Quaternion)`
|
||||
= Made `GetAxis()` not accidentally create an infinite vector.
|
||||
* Angle
|
||||
+ Complimentary
|
||||
+ Supplementary
|
||||
* Float2
|
||||
+ operator *(Float2, Quaternion)
|
||||
* Float3
|
||||
+ operator *(Float3, Quaternion)
|
||||
= Fixed `ToVector()`
|
||||
* IMatrix
|
||||
- ToDictionary()
|
||||
* Matrix
|
||||
+ Cofactor()
|
||||
+ IdentityIsh(Int2)
|
||||
+ MinorOf(Int2)
|
||||
- ToDictionary()
|
||||
= Fixed `Determinant()`
|
||||
= Fixed `Minors()`
|
||||
= Fixed `Inverse()`
|
||||
= Made `Identity(Int2)` only work with square matricies (since that's only when an identity exists)
|
||||
= Marked the struct as `readonly`
|
||||
= Simplified `Transpose()`
|
||||
= Swapped row variables with column variables in all constructors (and methods that require those constructors).
|
||||
= Swapped code for `Adjugate()` with `Cofactor()`
|
||||
* Matrix2x2
|
||||
+ Cofactor()
|
||||
+ operator *(Matrix2x2, Float2)
|
||||
+ operator /(Matrix2x2, Float2)
|
||||
- ToDictionary()
|
||||
= Swapped code for `Adjugate()` with `Cofactor()`
|
||||
= Swapped row variables with column variables in all constructors (and methods that require those constructors).
|
||||
= Fixed `this[int, int]` to compensate for the swapped variables.
|
||||
= Fixed `operator -(Matrix2x2, Matrix2x2)` to not have an addition in one of the variables (fun).
|
||||
= Fixed `Inverse()`
|
||||
= Fixed `explicit operator Matrix2x2(Matrix)`
|
||||
* Matrix3x3
|
||||
+ Cofactor()
|
||||
+ operator *(Matrix3x3, Float3)
|
||||
+ operator /(Matrix3x3, Float3)
|
||||
- ToDictionary()
|
||||
= Swapped code for `Adjugate()` with `Cofactor()`
|
||||
= Swapped row variables with column variables in all constructors (and methods that require those constructors).
|
||||
= Fixed `this[int, int]` to compensate for the swapped variables.
|
||||
= Fixed `Determinant()`
|
||||
= Fixed `Inverse()`
|
||||
= Fixed `explicit operator Matrix3x3(Matrix)`
|
||||
* Matrix4x4
|
||||
+ Cofactor()
|
||||
+ override string ToString()
|
||||
+ operator *(Matrix4x4, Float4)
|
||||
+ operator /(Matrix4x4, Float4)
|
||||
- ToDictionary()
|
||||
= Swapped code for `Adjugate()` with `Cofactor()`
|
||||
= Swapped row variables with column variables in all constructors (and methods that require those constructors).
|
||||
= Fixed `this[int, int]` to compensate for the swapped variables.
|
||||
= Fixed `Determinant()`
|
||||
= Fixed a typo in `Absolute(Matrix4x4)`, `Ceiling(Matrix4x4)`, `Floor(Matrix4x4)`, and `Round(Matrix4x4)`
|
||||
= Fixed a typo in `Row1`, `Row2`, `Row3`, and `Row4`. Oops.
|
||||
= Fixed some missing elements in `SplitArray(Matrix4x4[])`
|
||||
= Fixed `explicit operator Matrix4x4(Matrix)`
|
||||
* Geometry
|
||||
* Box2D
|
||||
= Simplified some code in `Perimeter`
|
||||
* Box3D
|
||||
+ SurfaceArea
|
||||
= Renamed `Area` to `Volume`
|
||||
= Simplified some code in `Perimeter`
|
||||
* Polygon
|
||||
= Marked as deprecated (will be redone in v2.4.0)
|
||||
= Simplified collection initialization in `Triangulate()`
|
||||
* Quadrilateral
|
||||
- explicit operator Triangle(Polygon)
|
||||
= Marked `Area` as deprecated (uses deprecated `Triangle.Area` field)
|
||||
* Sphere
|
||||
= Fixed `ClosestTo(Vert)`
|
||||
* Triangle
|
||||
- explicit operator Triangle(Polygon)
|
||||
= Marked `Area` as deprecated (will be fixed in v2.4.0)
|
||||
* Vert
|
||||
= Marked as deprecated (will be removed in v2.4.0).
|
||||
= Optimized `Normalized` to not clone more than required.
|
||||
```
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace Nerd_STF.Exceptions;
|
||||
|
||||
[Serializable]
|
||||
[Obsolete("The Polygon struct is a garbage fire, and will be fixed in v2.4.0", false)]
|
||||
public class DifferingVertCountException : Nerd_STFException
|
||||
{
|
||||
public string? ParamName;
|
||||
|
||||
@ -2,10 +2,12 @@
|
||||
|
||||
public static class Container2DExtension
|
||||
{
|
||||
public static T[] Flatten<T>(this T[,] array, Int2 size)
|
||||
public static T[] Flatten<T>(this T[,] array, Int2? size = null)
|
||||
{
|
||||
T[] res = new T[size.x * size.y];
|
||||
for (int x = 0; x < size.x; x++) for (int y = 0; y < size.y; y++) res[x + y * size.x] = array[y, x];
|
||||
size ??= GetSize(array);
|
||||
T[] res = new T[size.Value.x * size.Value.y];
|
||||
for (int x = 0; x < size.Value.x; x++) for (int y = 0; y < size.Value.y; y++)
|
||||
res[x + y * size.Value.x] = array[y, x];
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -21,4 +23,39 @@ public static class Container2DExtension
|
||||
for (int i = 0; i < length; i++) res[i] = array[row, i];
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Int2 GetSize<T>(this T[,] array)
|
||||
{
|
||||
Int2 size = Int2.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
_ = array[size.x, 0];
|
||||
size.x++;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException) { }
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
_ = array[0, size.y];
|
||||
size.y++;
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException) { }
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public static T[,] SwapDimensions<T>(this T[,] array, Int2? size = null)
|
||||
{
|
||||
size ??= GetSize(array);
|
||||
T[,] vals = new T[size.Value.y, size.Value.x];
|
||||
for (int x = 0; x < size.Value.y; x++) for (int y = 0; y < size.Value.x; y++) vals[x, y] = array[y, x];
|
||||
return vals;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,6 @@ public interface IMatrix<T> : ICloneable, IEnumerable, IEquatable<T>, IGroup2D<f
|
||||
public float Determinant();
|
||||
public T Inverse();
|
||||
public T Transpose();
|
||||
|
||||
public Dictionary<Int2, float> ToDictionary();
|
||||
}
|
||||
|
||||
public interface IMatrix<This, TMinor> : IMatrix<This> where This : IMatrix<This, TMinor>
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
namespace Nerd_STF.Mathematics.Algebra;
|
||||
|
||||
public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
public readonly struct Matrix : IMatrix<Matrix, Matrix>
|
||||
{
|
||||
public static Matrix Identity(Int2 size)
|
||||
{
|
||||
if (size.x != size.y) throw new InvalidSizeException("Can only create an identity matrix of a square matrix.");
|
||||
Matrix m = Zero(size);
|
||||
for (int i = 0; i < size.x; i++) m[i, i] = 1;
|
||||
return m;
|
||||
}
|
||||
public static Matrix IdentityIsh(Int2 size)
|
||||
{
|
||||
Matrix m = Zero(size);
|
||||
int max = Mathf.Min(size.x, size.y);
|
||||
@ -27,7 +34,7 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
array = new float[size.x, size.y];
|
||||
|
||||
if (all == 0) return;
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = all;
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = all;
|
||||
}
|
||||
public Matrix(Int2 size, float[] vals)
|
||||
{
|
||||
@ -37,7 +44,7 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
if (vals.Length < size.x * size.y)
|
||||
throw new InvalidSizeException("Array must contain enough values to fill the matrix.");
|
||||
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals[c + r * size.y];
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals[c + r * size.y];
|
||||
}
|
||||
public Matrix(Int2 size, int[] vals)
|
||||
{
|
||||
@ -47,45 +54,45 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
if (vals.Length < size.x * size.y)
|
||||
throw new InvalidSizeException("Array must contain enough values to fill the matrix.");
|
||||
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals[c + r * size.y];
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals[c + r * size.y];
|
||||
}
|
||||
public Matrix(Int2 size, Fill<float> vals)
|
||||
{
|
||||
Size = size;
|
||||
array = new float[size.x, size.y];
|
||||
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals(c + r * size.y);
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals(c + r * size.y);
|
||||
}
|
||||
public Matrix(Int2 size, Fill<int> vals)
|
||||
{
|
||||
Size = size;
|
||||
array = new float[size.x, size.y];
|
||||
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals(c + r * size.y);
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals(c + r * size.y);
|
||||
}
|
||||
public Matrix(Int2 size, float[,] vals)
|
||||
{
|
||||
Size = size;
|
||||
array = new float[size.x, size.y];
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals[c, r];
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals[r, c];
|
||||
}
|
||||
public Matrix(Int2 size, int[,] vals)
|
||||
{
|
||||
Size = size;
|
||||
array = new float[size.x, size.y];
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals[c, r];
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals[r, c];
|
||||
}
|
||||
public Matrix(Int2 size, Fill2D<float> vals)
|
||||
{
|
||||
Size = size;
|
||||
array = new float[size.x, size.y];
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals(c, r);
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals(r, c);
|
||||
}
|
||||
public Matrix(Int2 size, Fill2D<int> vals)
|
||||
{
|
||||
Size = size;
|
||||
array = new float[size.x, size.y];
|
||||
for (int r = 0; r < size.y; r++) for (int c = 0; c < size.x; c++) array[c, r] = vals(c, r);
|
||||
for (int r = 0; r < size.x; r++) for (int c = 0; c < size.y; c++) array[r, c] = vals(r, c);
|
||||
}
|
||||
|
||||
public float this[int r, int c]
|
||||
@ -135,37 +142,38 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
|
||||
public void Apply(Modifier2D modifier)
|
||||
{
|
||||
for (int r = 0; r < Size.y; r++) for (int c = 0; c < Size.x; c++)
|
||||
for (int r = 0; r < Size.x; r++) for (int c = 0; c < Size.y; c++)
|
||||
array[r, c] = modifier(new(r, c), array[r, c]);
|
||||
}
|
||||
|
||||
public float[] GetColumn(int column)
|
||||
{
|
||||
float[] vals = new float[Size.y];
|
||||
for (int i = 0; i < Size.y; i++) vals[i] = array[i, column];
|
||||
float[] vals = new float[Size.x];
|
||||
for (int i = 0; i < Size.x; i++) vals[i] = array[i, column];
|
||||
return vals;
|
||||
}
|
||||
public float[] GetRow(int row)
|
||||
{
|
||||
float[] vals = new float[Size.x];
|
||||
for (int i = 0; i < Size.x; i++) vals[i] = array[row, i];
|
||||
float[] vals = new float[Size.y];
|
||||
for (int i = 0; i < Size.y; i++) vals[i] = array[row, i];
|
||||
return vals;
|
||||
}
|
||||
|
||||
public void SetColumn(int column, float[] vals)
|
||||
{
|
||||
if (vals.Length < Size.y)
|
||||
if (vals.Length < Size.x)
|
||||
throw new InvalidSizeException("Array must contain enough values to fill the column.");
|
||||
for (int i = 0; i < Size.y; i++) array[i, column] = vals[i];
|
||||
for (int i = 0; i < Size.x; i++) array[i, column] = vals[i];
|
||||
}
|
||||
public void SetRow(int row, float[] vals)
|
||||
{
|
||||
if (vals.Length < Size.x)
|
||||
if (vals.Length < Size.y)
|
||||
throw new InvalidSizeException("Array must contain enough values to fill the row.");
|
||||
for (int i = 0; i < Size.x; i++) array[row, i] = vals[i];
|
||||
for (int i = 0; i < Size.y; i++) array[row, i] = vals[i];
|
||||
}
|
||||
|
||||
public Matrix Adjugate()
|
||||
public Matrix Adjugate() => Cofactor().Transpose();
|
||||
public Matrix Cofactor()
|
||||
{
|
||||
Matrix dets = new(Size);
|
||||
Matrix[,] minors = Minors();
|
||||
@ -175,12 +183,12 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
public float Determinant()
|
||||
{
|
||||
if (!IsSquare) throw new InvalidSizeException("Matrix must be square to calculate determinant.");
|
||||
if (Size.x <= 0 || Size.y <= 0) return 0;
|
||||
if (Size.x == 1 || Size.y == 1) return array[0, 0];
|
||||
if (Size.x <= 0) return 0;
|
||||
if (Size.x == 1) return array[0, 0];
|
||||
|
||||
Matrix[] minors = Minors().GetRow(0, Size.x);
|
||||
float det = 0;
|
||||
for (int i = 0; i < minors.Length; i++) det += minors[i].Determinant() * (i % 2 == 0 ? 1 : -1);
|
||||
for (int i = 0; i < minors.Length; i++) det += array[0, i] * minors[i].Determinant() * (i % 2 == 0 ? 1 : -1);
|
||||
|
||||
return det;
|
||||
}
|
||||
@ -188,45 +196,30 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
{
|
||||
float d = Determinant();
|
||||
if (d == 0) throw new NoInverseException();
|
||||
return Transpose().Adjugate() / d;
|
||||
return Adjugate() / d;
|
||||
}
|
||||
public Matrix[,] Minors()
|
||||
{
|
||||
// This will absolutely blow my mind if it works.
|
||||
// Remember that whole "don't have a way to test" thing?
|
||||
|
||||
if (!HasMinors) return new Matrix[0,0];
|
||||
|
||||
Int2 newSize = Size - Int2.One;
|
||||
Matrix[,] array = new Matrix[Size.x, Size.y];
|
||||
for (int r1 = 0; r1 < Size.y; r1++) for (int c1 = 0; c1 < Size.x; c1++)
|
||||
{
|
||||
Matrix m = new(newSize);
|
||||
for (int r2 = 0; r2 < newSize.y; r2++) for (int c2 = 0; c2 < newSize.x; c2++)
|
||||
{
|
||||
int toSkip = c2 + r2 * newSize.y;
|
||||
for (int r3 = 0; r3 < newSize.y; r3++) for (int c3 = 0; c3 < newSize.x; c3++)
|
||||
{
|
||||
if (r3 == r1 || c3 == c1) continue;
|
||||
if (toSkip > 0)
|
||||
{
|
||||
toSkip--;
|
||||
continue;
|
||||
}
|
||||
m[c2, r2] = this.array[c3, r3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
array[c1, r1] = m;
|
||||
}
|
||||
return array;
|
||||
Matrix[,] minors = new Matrix[Size.x, Size.y];
|
||||
for (int r = 0; r < Size.x; r++) for (int c = 0; c < Size.y; c++) minors[r, c] = MinorOf(new(r, c));
|
||||
return minors;
|
||||
}
|
||||
public Matrix Transpose()
|
||||
{
|
||||
Matrix m = new(new(Size.y, Size.x));
|
||||
for (int r = 0; r < Size.y; r++) m.SetColumn(r, GetRow(r));
|
||||
for (int c = 0; c < Size.x; c++) m.SetRow(c, GetColumn(c));
|
||||
return m;
|
||||
Matrix @this = this;
|
||||
return new(Size, (r, c) => @this[c, r]);
|
||||
}
|
||||
|
||||
public Matrix MinorOf(Int2 index)
|
||||
{
|
||||
Matrix @this = this;
|
||||
return new(@this.Size - Int2.One, delegate (int r, int c)
|
||||
{
|
||||
if (r >= index.x) r++;
|
||||
if (c >= index.y) c++;
|
||||
return @this[r, c];
|
||||
});
|
||||
}
|
||||
|
||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||
@ -246,9 +239,9 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
public string ToString(string? provider)
|
||||
{
|
||||
string res = "";
|
||||
for (int r = 0; r < Size.y; r++)
|
||||
for (int r = 0; r < Size.x; r++)
|
||||
{
|
||||
for (int c = 0; c < Size.x; c++) res += array[c, r].ToString(provider) + " ";
|
||||
for (int c = 0; c < Size.y; c++) res += array[r, c].ToString(provider) + " ";
|
||||
res += "\n";
|
||||
}
|
||||
return res;
|
||||
@ -258,7 +251,7 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
string res = "";
|
||||
for (int r = 0; r < Size.y; r++)
|
||||
{
|
||||
for (int c = 0; c < Size.x; c++) res += array[c, r].ToString(provider) + " ";
|
||||
for (int c = 0; c < Size.x; c++) res += array[r, c].ToString(provider) + " ";
|
||||
res += "\n";
|
||||
}
|
||||
return res;
|
||||
@ -272,14 +265,8 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
for (int r = 0; r < Size.y; r++) for (int c = 0; c < Size.x; c++) yield return array[c, r];
|
||||
}
|
||||
|
||||
public float[] ToArray() => array.Flatten(Size);
|
||||
public float[] ToArray() => array.Flatten(new(Size.y, Size.x));
|
||||
public float[,] ToArray2D() => array;
|
||||
public Dictionary<Int2, float> ToDictionary()
|
||||
{
|
||||
Dictionary<Int2, float> dict = new();
|
||||
for (int r = 0; r < Size.y; r++) for (int c = 0; c < Size.x; c++) dict.Add(new(c, r), array[c, r]);
|
||||
return dict;
|
||||
}
|
||||
public Fill<float> ToFill() => ToFillExtension.ToFill(this);
|
||||
public Fill2D<float> ToFill2D()
|
||||
{
|
||||
@ -292,8 +279,11 @@ public struct Matrix : IMatrix<Matrix, Matrix>
|
||||
public static Matrix operator -(Matrix m) => m.Inverse();
|
||||
public static Matrix operator -(Matrix a, Matrix b) => new(a.Size, (r, c) => a[r, c] - b[r, c]);
|
||||
public static Matrix operator *(Matrix a, float b) => new(a.Size, (r, c) => a[r, c] * b);
|
||||
public static Matrix operator *(Matrix a, Matrix b) =>
|
||||
new(new(a.Size.y, b.Size.x), (r, c) => Mathf.Dot(a.GetRow(r), b.GetColumn(c)));
|
||||
public static Matrix operator *(Matrix a, Matrix b)
|
||||
{
|
||||
if (a.Size.y != b.Size.x) throw new InvalidSizeException("Incompatible Dimensions.");
|
||||
return new(new(a.Size.x, b.Size.y), (r, c) => Mathf.Dot(a.GetRow(r), b.GetColumn(c)));
|
||||
}
|
||||
public static Complex operator *(Matrix a, Complex b) => (Complex)(a * (Matrix)b);
|
||||
public static Quaternion operator *(Matrix a, Quaternion b) => (Quaternion)(a * (Matrix)b);
|
||||
public static Float2 operator *(Matrix a, Float2 b) => (Float2)(a * (Matrix)b);
|
||||
|
||||
@ -55,11 +55,11 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
public float r1c1, r2c1, r1c2, r2c2;
|
||||
|
||||
public Matrix2x2(float all) : this(all, all, all, all) { }
|
||||
public Matrix2x2(float r1c1, float r2c1, float r1c2, float r2c2)
|
||||
public Matrix2x2(float r1c1, float r1c2, float r2c1, float r2c2)
|
||||
{
|
||||
this.r1c1 = r1c1;
|
||||
this.r2c1 = r2c1;
|
||||
this.r1c2 = r1c2;
|
||||
this.r2c1 = r2c1;
|
||||
this.r2c2 = r2c2;
|
||||
}
|
||||
public Matrix2x2(float[] nums) : this(nums[0], nums[1], nums[2], nums[3]) { }
|
||||
@ -70,17 +70,17 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
public Matrix2x2(int[,] nums) : this(nums[0, 0], nums[0, 1], nums[1, 0], nums[1, 1]) { }
|
||||
public Matrix2x2(Fill2D<float> fill) : this(fill(0, 0), fill(0, 1), fill(1, 0), fill(1, 1)) { }
|
||||
public Matrix2x2(Fill2D<int> fill) : this(fill(0, 0), fill(0, 1), fill(1, 0), fill(1, 1)) { }
|
||||
public Matrix2x2(Float2 c1, Float2 c2) : this(c1.x, c1.y, c2.x, c2.y) { }
|
||||
public Matrix2x2(Float2 r1, Float2 r2) : this(r1.x, r1.y, r2.x, r2.y) { }
|
||||
public Matrix2x2(Fill<Float2> fill) : this(fill(0), fill(1)) { }
|
||||
public Matrix2x2(Fill<Int2> fill) : this((IEnumerable<int>)fill(0), fill(1)) { }
|
||||
public Matrix2x2(IEnumerable<float> c1, IEnumerable<float> c2) : this(c1.ToFill(), c2.ToFill()) { }
|
||||
public Matrix2x2(IEnumerable<int> c1, IEnumerable<int> c2) : this(c1.ToFill(), c2.ToFill()) { }
|
||||
public Matrix2x2(Fill<float> c1, Fill<float> c2) : this(c1(0), c1(1), c2(0), c2(1)) { }
|
||||
public Matrix2x2(Fill<int> c1, Fill<int> c2) : this(c1(0), c1(1), c2(0), c2(1)) { }
|
||||
public Matrix2x2(IEnumerable<float> r1, IEnumerable<float> r2) : this(r1.ToFill(), r2.ToFill()) { }
|
||||
public Matrix2x2(IEnumerable<int> r1, IEnumerable<int> r2) : this(r1.ToFill(), r2.ToFill()) { }
|
||||
public Matrix2x2(Fill<float> r1, Fill<float> r2) : this(r1(0), r1(1), r2(0), r2(1)) { }
|
||||
public Matrix2x2(Fill<int> r1, Fill<int> r2) : this(r1(0), r1(1), r2(0), r2(1)) { }
|
||||
|
||||
public float this[int r, int c]
|
||||
{
|
||||
get => ToArray2D()[c, r];
|
||||
get => ToArray2D()[r, c];
|
||||
set
|
||||
{
|
||||
// Maybe this could be improved?
|
||||
@ -117,24 +117,24 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
set => this[index.x, index.y] = value;
|
||||
}
|
||||
|
||||
public static Matrix2x2 Absolute(Matrix2x2 val) => new(Mathf.Absolute(val.r1c1), Mathf.Absolute(val.r2c1),
|
||||
Mathf.Absolute(val.r1c2), Mathf.Absolute(val.r2c2));
|
||||
public static Matrix2x2 Absolute(Matrix2x2 val) => new(Mathf.Absolute(val.r1c1), Mathf.Absolute(val.r1c2),
|
||||
Mathf.Absolute(val.r2c1), Mathf.Absolute(val.r2c2));
|
||||
public static Matrix2x2 Average(params Matrix2x2[] vals) => Sum(vals) / vals.Length;
|
||||
public static Matrix2x2 Ceiling(Matrix2x2 val) => new(Mathf.Ceiling(val.r1c1), Mathf.Ceiling(val.r2c1),
|
||||
Mathf.Ceiling(val.r1c2), Mathf.Ceiling(val.r2c2));
|
||||
public static Matrix2x2 Ceiling(Matrix2x2 val) => new(Mathf.Ceiling(val.r1c1), Mathf.Ceiling(val.r1c2),
|
||||
Mathf.Ceiling(val.r2c1), Mathf.Ceiling(val.r2c2));
|
||||
public static Matrix2x2 Clamp(Matrix2x2 val, Matrix2x2 min, Matrix2x2 max) =>
|
||||
new(Mathf.Clamp(val.r1c1, min.r1c1, max.r1c1), Mathf.Clamp(val.r2c1, min.r2c1, max.r2c1),
|
||||
Mathf.Clamp(val.r1c2, min.r1c2, max.r1c2), Mathf.Clamp(val.r2c2, min.r2c2, max.r2c2));
|
||||
new(Mathf.Clamp(val.r1c1, min.r1c1, max.r1c1), Mathf.Clamp(val.r1c2, min.r1c2, max.r1c2),
|
||||
Mathf.Clamp(val.r2c1, min.r2c1, max.r2c1), Mathf.Clamp(val.r2c2, min.r2c2, max.r2c2));
|
||||
public static Matrix2x2 Divide(Matrix2x2 num, params Matrix2x2[] vals)
|
||||
{
|
||||
foreach (Matrix2x2 m in vals) num /= m;
|
||||
return num;
|
||||
}
|
||||
public static Matrix2x2 Floor(Matrix2x2 val) => new(Mathf.Floor(val.r1c1), Mathf.Floor(val.r2c1),
|
||||
Mathf.Floor(val.r1c2), Mathf.Floor(val.r2c2));
|
||||
public static Matrix2x2 Floor(Matrix2x2 val) => new(Mathf.Floor(val.r1c1), Mathf.Floor(val.r1c2),
|
||||
Mathf.Floor(val.r2c1), Mathf.Floor(val.r2c2));
|
||||
public static Matrix2x2 Lerp(Matrix2x2 a, Matrix2x2 b, float t, bool clamp = true) =>
|
||||
new(Mathf.Lerp(a.r1c1, b.r1c1, t, clamp), Mathf.Lerp(a.r2c1, b.r2c1, t, clamp),
|
||||
Mathf.Lerp(a.r1c2, b.r1c2, t, clamp), Mathf.Lerp(a.r2c2, b.r2c2, t, clamp));
|
||||
new(Mathf.Lerp(a.r1c1, b.r1c1, t, clamp), Mathf.Lerp(a.r1c2, b.r1c2, t, clamp),
|
||||
Mathf.Lerp(a.r2c1, b.r2c1, t, clamp), Mathf.Lerp(a.r2c2, b.r2c2, t, clamp));
|
||||
public static Matrix2x2 Median(params Matrix2x2[] vals)
|
||||
{
|
||||
float index = Mathf.Average(0, vals.Length - 1);
|
||||
@ -148,8 +148,8 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
foreach (Matrix2x2 m in vals) val *= m;
|
||||
return val;
|
||||
}
|
||||
public static Matrix2x2 Round(Matrix2x2 val) => new(Mathf.Round(val.r1c1), Mathf.Round(val.r2c1),
|
||||
Mathf.Round(val.r1c2), Mathf.Round(val.r2c2));
|
||||
public static Matrix2x2 Round(Matrix2x2 val) => new(Mathf.Round(val.r1c1), Mathf.Round(val.r1c2),
|
||||
Mathf.Round(val.r2c1), Mathf.Round(val.r2c2));
|
||||
public static Matrix2x2 Subtract(Matrix2x2 num, params Matrix2x2[] vals)
|
||||
{
|
||||
foreach (Matrix2x2 m in vals) num -= m;
|
||||
@ -162,21 +162,22 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
return val;
|
||||
}
|
||||
|
||||
public static (float[] r1c1s, float[] r2c1s, float[] r1c2s, float[] r2c2s) SplitArray(params Matrix2x2[] vals)
|
||||
public static (float[] r1c1s, float[] r1c2s, float[] r2c1s, float[] r2c2s) SplitArray(params Matrix2x2[] vals)
|
||||
{
|
||||
float[] r1c1s = new float[vals.Length], r2c1s = new float[vals.Length], r1c2s = new float[vals.Length],
|
||||
float[] r1c1s = new float[vals.Length], r1c2s = new float[vals.Length], r2c1s = new float[vals.Length],
|
||||
r2c2s = new float[vals.Length];
|
||||
for (int i = 0; i < vals.Length; i++)
|
||||
{
|
||||
r1c1s[i] = vals[i].r1c1;
|
||||
r2c1s[i] = vals[i].r2c1;
|
||||
r1c2s[i] = vals[i].r1c2;
|
||||
r2c1s[i] = vals[i].r2c1;
|
||||
r2c2s[i] = vals[i].r2c2;
|
||||
}
|
||||
return (r1c1s, r2c1s, r1c2s, r2c2s);
|
||||
return (r1c1s, r1c2s, r2c1s, r2c2s);
|
||||
}
|
||||
|
||||
public Matrix2x2 Adjugate()
|
||||
public Matrix2x2 Adjugate() => Cofactor().Transpose();
|
||||
public Matrix2x2 Cofactor()
|
||||
{
|
||||
Matrix2x2 swapped = new(new[,]
|
||||
{
|
||||
@ -203,10 +204,10 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
if (obj == null || obj.GetType() != typeof(Matrix2x2)) return base.Equals(obj);
|
||||
return Equals((Matrix2x2)obj);
|
||||
}
|
||||
public bool Equals(Matrix2x2 other) => r1c1 == other.r1c1 && r2c1 == other.r2c1
|
||||
&& r1c2 == other.r1c2&& r2c2 == other.r2c2;
|
||||
public override int GetHashCode() => r1c1.GetHashCode() ^ r2c1.GetHashCode()
|
||||
^ r1c2.GetHashCode() ^ r2c2.GetHashCode();
|
||||
public bool Equals(Matrix2x2 other) => r1c1 == other.r1c1 && r1c2 == other.r1c2
|
||||
&& r2c1 == other.r2c1 && r2c2 == other.r2c2;
|
||||
public override int GetHashCode() => r1c1.GetHashCode() ^ r1c2.GetHashCode()
|
||||
^ r2c1.GetHashCode() ^ r2c2.GetHashCode();
|
||||
public override string ToString() => ToString((string?)null);
|
||||
public string ToString(string? provider) => r1c1.ToString(provider) + " " + r1c2.ToString(provider) + "\n"
|
||||
+ r2c1.ToString(provider) + " " + r2c2.ToString(provider);
|
||||
@ -219,47 +220,42 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
public IEnumerator<float> GetEnumerator()
|
||||
{
|
||||
yield return r1c1;
|
||||
yield return r2c1;
|
||||
yield return r1c2;
|
||||
yield return r2c1;
|
||||
yield return r2c2;
|
||||
}
|
||||
|
||||
public float[] ToArray() => new[] { r1c1, r2c1, r1c2, r2c2 };
|
||||
public float[] ToArray() => new[] { r1c1, r1c2, r2c1, r2c2 };
|
||||
public float[,] ToArray2D() => new[,]
|
||||
{
|
||||
{ r1c1, r1c2 },
|
||||
{ r2c1, r2c2 }
|
||||
};
|
||||
public Dictionary<Int2, float> ToDictionary()
|
||||
{
|
||||
Dictionary<Int2, float> dict = new();
|
||||
float[] arr = ToArray();
|
||||
for (int i = 0; i < arr.Length; i++) dict.Add(new(i % 2, i / 2), arr[i]);
|
||||
return dict;
|
||||
}
|
||||
public Fill<float> ToFill() => ToFillExtension.ToFill(this);
|
||||
public Fill2D<float> ToFill2D()
|
||||
{
|
||||
Matrix2x2 @this = this;
|
||||
return (x, y) => @this[x, y];
|
||||
}
|
||||
public List<float> ToList() => new() { r1c1, r2c1, r1c2, r2c2 };
|
||||
public List<float> ToList() => new() { r1c1, r1c2, r2c1, r2c2 };
|
||||
|
||||
public static Matrix2x2 operator +(Matrix2x2 a, Matrix2x2 b) => new(a.r1c1 + b.r1c1, a.r2c1 + b.r2c1,
|
||||
a.r1c2 + b.r1c2, a.r2c2 + b.r2c2);
|
||||
public static Matrix2x2 operator +(Matrix2x2 a, Matrix2x2 b) => new(a.r1c1 + b.r1c1, a.r1c2 + b.r1c2,
|
||||
a.r2c1 + b.r2c1, a.r2c2 + b.r2c2);
|
||||
public static Matrix2x2? operator -(Matrix2x2 m) => m.Inverse();
|
||||
public static Matrix2x2 operator -(Matrix2x2 a, Matrix2x2 b) => new(a.r1c1 - b.r1c1, a.r2c1 - b.r2c1,
|
||||
a.r1c2 - b.r1c2, a.r2c2 + b.r2c2);
|
||||
public static Matrix2x2 operator *(Matrix2x2 a, float b) => new(a.r1c1 * b, a.r2c1 * b, a.r1c2 * b, a.r2c2 * b);
|
||||
public static Matrix2x2 operator -(Matrix2x2 a, Matrix2x2 b) => new(a.r1c1 - b.r1c1, a.r1c2 - b.r1c2,
|
||||
a.r2c1 - b.r2c1, a.r2c2 - b.r2c2);
|
||||
public static Matrix2x2 operator *(Matrix2x2 a, float b) => new(a.r1c1 * b, a.r1c2 * b, a.r2c1 * b, a.r2c2 * b);
|
||||
public static Matrix2x2 operator *(Matrix2x2 a, Matrix2x2 b) => new(new[,]
|
||||
{
|
||||
{ Float2.Dot(a.Row1, b.Column1), Float2.Dot(a.Row1, b.Column2) },
|
||||
{ Float2.Dot(a.Row2, b.Column1), Float2.Dot(a.Row2, b.Column2) },
|
||||
});
|
||||
public static Matrix2x2 operator /(Matrix2x2 a, float b) => new(a.r1c1 / b, a.r2c1 / b, a.r1c2 / b, a.r2c2 / b);
|
||||
public static Float2 operator *(Matrix2x2 a, Float2 b) => (Matrix)a * b;
|
||||
public static Matrix2x2 operator /(Matrix2x2 a, float b) => new(a.r1c1 / b, a.r1c2 / b, a.r2c1 / b, a.r2c2 / b);
|
||||
public static Matrix2x2 operator /(Matrix2x2 a, Matrix2x2 b) => a * b.Inverse();
|
||||
public static Float2 operator /(Matrix2x2 a, Float2 b) => (Matrix)a / b;
|
||||
public static Matrix2x2 operator ^(Matrix2x2 a, Matrix2x2 b) => // Single number multiplication.
|
||||
new(a.r1c1 * b.r1c1, a.r2c1 * b.r2c1, a.r1c2 * b.r1c2, a.r2c2 * b.r2c2);
|
||||
new(a.r1c1 * b.r1c1, a.r1c2 * b.r1c2, a.r2c1 * b.r2c1, a.r2c2 * b.r2c2);
|
||||
public static bool operator ==(Matrix2x2 a, Matrix2x2 b) => a.Equals(b);
|
||||
public static bool operator !=(Matrix2x2 a, Matrix2x2 b) => !a.Equals(b);
|
||||
|
||||
@ -267,7 +263,7 @@ public struct Matrix2x2 : IMatrix<Matrix2x2>
|
||||
{
|
||||
Matrix2x2 res = Zero, identity = Identity;
|
||||
for (int r = 0; r < 2; r++) for (int c = 0; c < 2; c++)
|
||||
res[c, r] = m.Size.x < c && m.Size.y < r ? m[r, c] : identity[r, c];
|
||||
res[c, r] = m.Size.x > r && m.Size.y > c ? m[r, c] : identity[r, c];
|
||||
return res;
|
||||
}
|
||||
public static explicit operator Matrix2x2(Matrix3x3 m) => new(m.r1c1, m.r2c1, m.r1c2, m.r2c2);
|
||||
|
||||
@ -81,17 +81,17 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
public float r1c1, r2c1, r3c1, r1c2, r2c2, r3c2, r1c3, r2c3, r3c3;
|
||||
|
||||
public Matrix3x3(float all) : this(all, all, all, all, all, all, all, all, all) { }
|
||||
public Matrix3x3(float r1c1, float r2c1, float r3c1, float r1c2,
|
||||
float r2c2, float r3c2, float r1c3, float r2c3, float r3c3)
|
||||
public Matrix3x3(float r1c1, float r1c2, float r1c3, float r2c1,
|
||||
float r2c2, float r2c3, float r3c1, float r3c2, float r3c3)
|
||||
{
|
||||
this.r1c1 = r1c1;
|
||||
this.r2c1 = r2c1;
|
||||
this.r3c1 = r3c1;
|
||||
this.r1c2 = r1c2;
|
||||
this.r2c2 = r2c2;
|
||||
this.r3c2 = r3c2;
|
||||
this.r1c3 = r1c3;
|
||||
this.r2c1 = r2c1;
|
||||
this.r2c2 = r2c2;
|
||||
this.r2c3 = r2c3;
|
||||
this.r3c1 = r3c1;
|
||||
this.r3c2 = r3c2;
|
||||
this.r3c3 = r3c3;
|
||||
}
|
||||
public Matrix3x3(float[] nums) : this(nums[0], nums[1], nums[2],
|
||||
@ -110,21 +110,21 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
fill(1, 0), fill(1, 1), fill(1, 2), fill(2, 0), fill(2, 1), fill(2, 2)) { }
|
||||
public Matrix3x3(Fill2D<int> fill) : this(fill(0, 0), fill(0, 1), fill(0, 2),
|
||||
fill(1, 0), fill(1, 1), fill(1, 2), fill(2, 0), fill(2, 1), fill(2, 2)) { }
|
||||
public Matrix3x3(Float3 c1, Float3 c2, Float3 c3) : this(c1.x, c1.y, c1.z, c2.x, c2.y, c2.z, c3.x, c3.y, c3.z) { }
|
||||
public Matrix3x3(Float3 r1, Float3 r2, Float3 r3) : this(r1.x, r1.y, r1.z, r2.x, r2.y, r2.z, r3.x, r3.y, r3.z) { }
|
||||
public Matrix3x3(Fill<Float3> fill) : this(fill(0), fill(1), fill(2)) { }
|
||||
public Matrix3x3(Fill<Int3> fill) : this((IEnumerable<int>)fill(0), fill(1), fill(2)) { }
|
||||
public Matrix3x3(IEnumerable<float> c1, IEnumerable<float> c2, IEnumerable<float> c3)
|
||||
: this(c1.ToFill(), c2.ToFill(), c3.ToFill()) { }
|
||||
public Matrix3x3(IEnumerable<int> c1, IEnumerable<int> c2, IEnumerable<int> c3)
|
||||
: this(c1.ToFill(), c2.ToFill(), c3.ToFill()) { }
|
||||
public Matrix3x3(Fill<float> c1, Fill<float> c2, Fill<float> c3)
|
||||
: this(c1(0), c1(1), c1(2), c2(0), c2(1), c2(2), c3(0), c3(1), c3(2)) { }
|
||||
public Matrix3x3(Fill<int> c1, Fill<int> c2, Fill<int> c3)
|
||||
: this(c1(0), c1(1), c1(2), c2(0), c2(1), c2(2), c3(0), c3(1), c3(2)) { }
|
||||
public Matrix3x3(IEnumerable<float> r1, IEnumerable<float> r2, IEnumerable<float> r3)
|
||||
: this(r1.ToFill(), r2.ToFill(), r3.ToFill()) { }
|
||||
public Matrix3x3(IEnumerable<int> r1, IEnumerable<int> r2, IEnumerable<int> r3)
|
||||
: this(r1.ToFill(), r2.ToFill(), r3.ToFill()) { }
|
||||
public Matrix3x3(Fill<float> r1, Fill<float> r2, Fill<float> r3)
|
||||
: this(r1(0), r1(1), r1(2), r2(0), r2(1), r2(2), r3(0), r3(1), r3(2)) { }
|
||||
public Matrix3x3(Fill<int> r1, Fill<int> r2, Fill<int> r3)
|
||||
: this(r1(0), r1(1), r1(2), r2(0), r2(1), r2(2), r3(0), r3(1), r3(2)) { }
|
||||
|
||||
public float this[int r, int c]
|
||||
{
|
||||
get => ToArray2D()[c, r];
|
||||
get => ToArray2D()[r, c];
|
||||
set
|
||||
{
|
||||
// Maybe this could be improved?
|
||||
@ -182,19 +182,19 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
}
|
||||
|
||||
public static Matrix3x3 Absolute(Matrix3x3 val) =>
|
||||
new(Mathf.Absolute(val.r1c1), Mathf.Absolute(val.r2c1), Mathf.Absolute(val.r3c1),
|
||||
Mathf.Absolute(val.r1c2), Mathf.Absolute(val.r2c2), Mathf.Absolute(val.r3c2),
|
||||
Mathf.Absolute(val.r1c3), Mathf.Absolute(val.r2c3), Mathf.Absolute(val.r3c3));
|
||||
new(Mathf.Absolute(val.r1c1), Mathf.Absolute(val.r1c2), Mathf.Absolute(val.r1c3),
|
||||
Mathf.Absolute(val.r2c1), Mathf.Absolute(val.r2c2), Mathf.Absolute(val.r2c3),
|
||||
Mathf.Absolute(val.r3c1), Mathf.Absolute(val.r3c2), Mathf.Absolute(val.r3c3));
|
||||
public static Matrix3x3 Average(params Matrix3x3[] vals) => Sum(vals) / vals.Length;
|
||||
public static Matrix3x3 Ceiling(Matrix3x3 val) =>
|
||||
new(Mathf.Ceiling(val.r1c1), Mathf.Ceiling(val.r2c1), Mathf.Ceiling(val.r3c1),
|
||||
Mathf.Ceiling(val.r1c2), Mathf.Ceiling(val.r2c2), Mathf.Ceiling(val.r3c2),
|
||||
Mathf.Ceiling(val.r1c3), Mathf.Ceiling(val.r2c3), Mathf.Ceiling(val.r3c3));
|
||||
new(Mathf.Ceiling(val.r1c1), Mathf.Ceiling(val.r1c2), Mathf.Ceiling(val.r1c3),
|
||||
Mathf.Ceiling(val.r2c1), Mathf.Ceiling(val.r2c2), Mathf.Ceiling(val.r2c3),
|
||||
Mathf.Ceiling(val.r3c1), Mathf.Ceiling(val.r3c2), Mathf.Ceiling(val.r3c3));
|
||||
public static Matrix3x3 Clamp(Matrix3x3 val, Matrix3x3 min, Matrix3x3 max) =>
|
||||
new(Mathf.Clamp(val.r1c1, min.r1c1, max.r1c1), Mathf.Clamp(val.r2c1, min.r2c1, max.r2c1),
|
||||
Mathf.Clamp(val.r3c1, min.r3c1, max.r3c1), Mathf.Clamp(val.r1c2, min.r1c2, max.r1c2),
|
||||
Mathf.Clamp(val.r2c2, min.r2c2, max.r2c2), Mathf.Clamp(val.r3c2, min.r3c2, max.r3c2),
|
||||
Mathf.Clamp(val.r1c3, min.r1c3, max.r1c3), Mathf.Clamp(val.r2c3, min.r2c3, max.r2c3),
|
||||
new(Mathf.Clamp(val.r1c1, min.r1c1, max.r1c1), Mathf.Clamp(val.r1c2, min.r1c2, max.r1c2),
|
||||
Mathf.Clamp(val.r1c3, min.r1c3, max.r1c3), Mathf.Clamp(val.r2c1, min.r2c1, max.r2c1),
|
||||
Mathf.Clamp(val.r2c2, min.r2c2, max.r2c2), Mathf.Clamp(val.r2c3, min.r2c3, max.r2c3),
|
||||
Mathf.Clamp(val.r3c1, min.r3c1, max.r3c1), Mathf.Clamp(val.r3c2, min.r3c2, max.r3c2),
|
||||
Mathf.Clamp(val.r3c3, min.r3c3, max.r3c3));
|
||||
public static Matrix3x3 Divide(Matrix3x3 num, params Matrix3x3[] vals)
|
||||
{
|
||||
@ -202,14 +202,14 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
return num;
|
||||
}
|
||||
public static Matrix3x3 Floor(Matrix3x3 val) =>
|
||||
new(Mathf.Floor(val.r1c1), Mathf.Floor(val.r2c1), Mathf.Floor(val.r3c1),
|
||||
Mathf.Floor(val.r1c2), Mathf.Floor(val.r2c2), Mathf.Floor(val.r3c2),
|
||||
Mathf.Floor(val.r1c3), Mathf.Floor(val.r2c3), Mathf.Floor(val.r3c3));
|
||||
new(Mathf.Floor(val.r1c1), Mathf.Floor(val.r1c2), Mathf.Floor(val.r1c3),
|
||||
Mathf.Floor(val.r2c1), Mathf.Floor(val.r2c2), Mathf.Floor(val.r2c3),
|
||||
Mathf.Floor(val.r3c1), Mathf.Floor(val.r3c2), Mathf.Floor(val.r3c3));
|
||||
public static Matrix3x3 Lerp(Matrix3x3 a, Matrix3x3 b, float t, bool clamp = true) =>
|
||||
new(Mathf.Lerp(a.r1c1, b.r1c1, t, clamp), Mathf.Lerp(a.r2c1, b.r2c1, t, clamp),
|
||||
Mathf.Lerp(a.r3c1, b.r3c1, t, clamp), Mathf.Lerp(a.r1c2, b.r1c2, t, clamp),
|
||||
Mathf.Lerp(a.r2c2, b.r2c2, t, clamp), Mathf.Lerp(a.r3c2, b.r3c2, t, clamp),
|
||||
Mathf.Lerp(a.r1c3, b.r1c3, t, clamp), Mathf.Lerp(a.r2c3, b.r2c3, t, clamp),
|
||||
new(Mathf.Lerp(a.r1c1, b.r1c1, t, clamp), Mathf.Lerp(a.r1c2, b.r1c2, t, clamp),
|
||||
Mathf.Lerp(a.r1c3, b.r1c3, t, clamp), Mathf.Lerp(a.r2c1, b.r2c1, t, clamp),
|
||||
Mathf.Lerp(a.r2c2, b.r2c2, t, clamp), Mathf.Lerp(a.r2c3, b.r2c3, t, clamp),
|
||||
Mathf.Lerp(a.r3c1, b.r3c1, t, clamp), Mathf.Lerp(a.r3c2, b.r3c2, t, clamp),
|
||||
Mathf.Lerp(a.r3c3, b.r3c3, t, clamp));
|
||||
public static Matrix3x3 Median(params Matrix3x3[] vals)
|
||||
{
|
||||
@ -225,9 +225,9 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
return val;
|
||||
}
|
||||
public static Matrix3x3 Round(Matrix3x3 val) =>
|
||||
new(Mathf.Round(val.r1c1), Mathf.Round(val.r2c1), Mathf.Round(val.r3c1),
|
||||
Mathf.Round(val.r1c2), Mathf.Round(val.r2c2), Mathf.Round(val.r3c2),
|
||||
Mathf.Round(val.r1c3), Mathf.Round(val.r2c3), Mathf.Round(val.r3c3));
|
||||
new(Mathf.Round(val.r1c1), Mathf.Round(val.r1c2), Mathf.Round(val.r1c3),
|
||||
Mathf.Round(val.r2c1), Mathf.Round(val.r2c2), Mathf.Round(val.r2c3),
|
||||
Mathf.Round(val.r3c1), Mathf.Round(val.r3c2), Mathf.Round(val.r3c3));
|
||||
public static Matrix3x3 Subtract(Matrix3x3 num, params Matrix3x3[] vals)
|
||||
{
|
||||
foreach (Matrix3x3 m in vals) num -= m;
|
||||
@ -240,28 +240,29 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
return val;
|
||||
}
|
||||
|
||||
public static (float[] r1c1s, float[] r2c1s, float[] r3c1s, float[] r1c2s, float[] r2c2s,
|
||||
float[] r3c2s, float[] r1c3s, float[] r2c3s, float[] r3c3s) SplitArray(params Matrix3x3[] vals)
|
||||
public static (float[] r1c1s, float[] r1c2s, float[] r1c3s, float[] r2c1s, float[] r2c2s,
|
||||
float[] r2c3s, float[] r3c1s, float[] r3c2s, float[] r3c3s) SplitArray(params Matrix3x3[] vals)
|
||||
{
|
||||
float[] r1c1s = new float[vals.Length], r2c1s = new float[vals.Length], r3c1s = new float[vals.Length],
|
||||
r1c2s = new float[vals.Length], r2c2s = new float[vals.Length], r3c2s = new float[vals.Length],
|
||||
r1c3s = new float[vals.Length], r2c3s = new float[vals.Length], r3c3s = new float[vals.Length];
|
||||
float[] r1c1s = new float[vals.Length], r1c2s = new float[vals.Length], r1c3s = new float[vals.Length],
|
||||
r2c1s = new float[vals.Length], r2c2s = new float[vals.Length], r2c3s = new float[vals.Length],
|
||||
r3c1s = new float[vals.Length], r3c2s = new float[vals.Length], r3c3s = new float[vals.Length];
|
||||
for (int i = 0; i < vals.Length; i++)
|
||||
{
|
||||
r1c1s[i] = vals[i].r1c1;
|
||||
r2c1s[i] = vals[i].r2c1;
|
||||
r3c1s[i] = vals[i].r3c1;
|
||||
r1c2s[i] = vals[i].r1c2;
|
||||
r2c2s[i] = vals[i].r2c2;
|
||||
r3c2s[i] = vals[i].r3c2;
|
||||
r1c3s[i] = vals[i].r1c3;
|
||||
r2c1s[i] = vals[i].r2c1;
|
||||
r2c2s[i] = vals[i].r2c2;
|
||||
r2c3s[i] = vals[i].r2c3;
|
||||
r3c1s[i] = vals[i].r3c1;
|
||||
r3c2s[i] = vals[i].r3c2;
|
||||
r3c3s[i] = vals[i].r3c3;
|
||||
}
|
||||
return (r1c1s, r2c1s, r3c1s, r1c2s, r2c2s, r3c2s, r1c3s, r2c3s, r3c3s);
|
||||
return (r1c1s, r1c2s, r1c3s, r2c1s, r2c2s, r2c3s, r3c1s, r3c2s, r3c3s);
|
||||
}
|
||||
|
||||
public Matrix3x3 Adjugate()
|
||||
public Matrix3x3 Adjugate() => Cofactor().Transpose();
|
||||
public Matrix3x3 Cofactor()
|
||||
{
|
||||
Matrix3x3 dets = new();
|
||||
Matrix2x2[,] minors = Minors();
|
||||
@ -271,20 +272,20 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
public float Determinant()
|
||||
{
|
||||
Matrix2x2[,] minors = Minors();
|
||||
return (r1c1 * minors[0, 0].Determinant()) - (r1c2 * minors[1, 0].Determinant())
|
||||
+ (r1c3 * minors[2, 0].Determinant());
|
||||
return (r1c1 * minors[0, 0].Determinant()) - (r1c2 * minors[0, 1].Determinant())
|
||||
+ (r1c3 * minors[0, 2].Determinant());
|
||||
}
|
||||
public Matrix3x3 Inverse()
|
||||
{
|
||||
float d = Determinant();
|
||||
if (d == 0) throw new NoInverseException();
|
||||
return Transpose().Adjugate() / d;
|
||||
return Adjugate() / d;
|
||||
}
|
||||
public Matrix2x2[,] Minors() => new Matrix2x2[,]
|
||||
{
|
||||
{ new(r2c2, r3c2, r2c3, r3c3), new(r2c1, r3c1, r2c3, r3c3), new(r2c1, r3c1, r2c2, r3c2) },
|
||||
{ new(r1c2, r3c2, r1c3, r3c3), new(r1c1, r3c1, r1c3, r3c3), new(r1c1, r3c1, r1c2, r3c2) },
|
||||
{ new(r1c2, r2c2, r1c3, r2c3), new(r1c1, r2c1, r1c3, r2c3), new(r1c1, r2c1, r1c2, r2c2) }
|
||||
{ new(r2c2, r2c3, r3c2, r3c3), new(r2c1, r2c3, r3c1, r3c3), new(r2c1, r2c2, r3c1, r3c2) },
|
||||
{ new(r1c2, r1c3, r3c2, r3c3), new(r1c1, r1c3, r3c1, r3c3), new(r1c1, r1c2, r3c1, r3c2) },
|
||||
{ new(r1c2, r1c3, r2c2, r2c3), new(r1c1, r1c3, r2c1, r2c3), new(r1c1, r1c2, r2c1, r2c2) }
|
||||
};
|
||||
public Matrix3x3 Transpose() => new(new[,]
|
||||
{
|
||||
@ -299,13 +300,13 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
return Equals((Matrix3x3)obj);
|
||||
}
|
||||
public bool Equals(Matrix3x3 other) =>
|
||||
r1c1 == other.r1c1 && r2c1 == other.r2c1 && r3c1 == other.r3c1 &&
|
||||
r1c2 == other.r1c2 && r2c2 == other.r2c2 && r3c2 == other.r3c2 &&
|
||||
r1c3 == other.r1c3 && r2c3 == other.r2c3 && r3c3 == other.r3c3;
|
||||
r1c1 == other.r1c1 && r1c2 == other.r1c2 && r1c3 == other.r1c3 &&
|
||||
r2c1 == other.r2c1 && r2c2 == other.r2c2 && r2c3 == other.r2c3 &&
|
||||
r3c1 == other.r3c1 && r3c2 == other.r3c2 && r3c3 == other.r3c3;
|
||||
public override int GetHashCode() =>
|
||||
r1c1.GetHashCode() ^ r2c1.GetHashCode() ^ r3c1.GetHashCode() ^
|
||||
r1c2.GetHashCode() ^ r2c2.GetHashCode() ^ r3c2.GetHashCode() ^
|
||||
r1c3.GetHashCode() ^ r2c3.GetHashCode() ^ r3c3.GetHashCode();
|
||||
r1c1.GetHashCode() ^ r1c2.GetHashCode() ^ r1c3.GetHashCode() ^
|
||||
r2c1.GetHashCode() ^ r2c2.GetHashCode() ^ r2c3.GetHashCode() ^
|
||||
r3c1.GetHashCode() ^ r3c2.GetHashCode() ^ r3c3.GetHashCode();
|
||||
public override string ToString() => ToString((string?)null);
|
||||
public string ToString(string? provider) =>
|
||||
r1c1.ToString(provider) + " " + r1c2.ToString(provider) + " " + r1c3.ToString(provider) + "\n" +
|
||||
@ -322,66 +323,61 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
public IEnumerator<float> GetEnumerator()
|
||||
{
|
||||
yield return r1c1;
|
||||
yield return r2c1;
|
||||
yield return r3c1;
|
||||
yield return r1c2;
|
||||
yield return r2c2;
|
||||
yield return r3c2;
|
||||
yield return r1c3;
|
||||
yield return r2c1;
|
||||
yield return r2c2;
|
||||
yield return r2c3;
|
||||
yield return r3c1;
|
||||
yield return r3c2;
|
||||
yield return r3c3;
|
||||
}
|
||||
|
||||
public float[] ToArray() => new[] { r1c1, r2c1, r3c1, r1c2, r2c2, r3c2, r1c3, r2c3, r3c3 };
|
||||
public float[] ToArray() => new[] { r1c1, r1c2, r1c3, r2c1, r2c2, r2c3, r3c1, r3c2, r3c3 };
|
||||
public float[,] ToArray2D() => new[,]
|
||||
{
|
||||
{ r1c1, r1c2, r1c3 },
|
||||
{ r2c1, r2c2, r2c3 },
|
||||
{ r3c1, r3c2, r3c3 }
|
||||
};
|
||||
public Dictionary<Int2, float> ToDictionary()
|
||||
{
|
||||
Dictionary<Int2, float> dict = new();
|
||||
float[] arr = ToArray();
|
||||
for (int i = 0; i < arr.Length; i++) dict.Add(new(i % 3, i / 3), arr[i]);
|
||||
return dict;
|
||||
}
|
||||
public Fill<float> ToFill() => ToFillExtension.ToFill(this);
|
||||
public Fill2D<float> ToFill2D()
|
||||
{
|
||||
Matrix3x3 @this = this;
|
||||
return (x, y) => @this[x, y];
|
||||
}
|
||||
public List<float> ToList() => new() { r1c1, r2c1, r3c1, r1c2, r2c2, r3c2, r1c3, r2c3, r3c3 };
|
||||
public List<float> ToList() => new() { r1c1, r1c2, r1c3, r2c1, r2c2, r2c3, r3c1, r3c2, r3c3 };
|
||||
|
||||
public static Matrix3x3 operator +(Matrix3x3 a, Matrix3x3 b) =>
|
||||
new(a.r1c1 + b.r1c1, a.r2c1 + b.r2c1, a.r3c1 + b.r3c1,
|
||||
a.r1c2 + b.r1c2, a.r2c2 + b.r2c2, a.r3c2 + b.r3c2,
|
||||
a.r1c3 + b.r1c3, a.r2c3 + b.r2c3, a.r3c3 + b.r3c3);
|
||||
new(a.r1c1 + b.r1c1, a.r1c2 + b.r1c2, a.r1c3 + b.r1c3,
|
||||
a.r2c1 + b.r2c1, a.r2c2 + b.r2c2, a.r2c3 + b.r2c3,
|
||||
a.r3c1 + b.r3c1, a.r3c2 + b.r3c2, a.r3c3 + b.r3c3);
|
||||
public static Matrix3x3 operator -(Matrix3x3 m) => m.Inverse();
|
||||
public static Matrix3x3 operator -(Matrix3x3 a, Matrix3x3 b) =>
|
||||
new(a.r1c1 - b.r1c1, a.r2c1 - b.r2c1, a.r3c1 - b.r3c1,
|
||||
a.r1c2 - b.r1c2, a.r2c2 - b.r2c2, a.r3c2 - b.r3c2,
|
||||
a.r1c3 - b.r1c3, a.r2c3 - b.r2c3, a.r3c3 - b.r3c3);
|
||||
new(a.r1c1 - b.r1c1, a.r1c2 - b.r1c2, a.r1c3 - b.r1c3,
|
||||
a.r2c1 - b.r2c1, a.r2c2 - b.r2c2, a.r2c3 - b.r2c3,
|
||||
a.r3c1 - b.r3c1, a.r3c2 - b.r3c2, a.r3c3 - b.r3c3);
|
||||
public static Matrix3x3 operator *(Matrix3x3 a, float b) =>
|
||||
new(a.r1c1 * b, a.r2c1 * b, a.r3c1 * b,
|
||||
a.r1c2 * b, a.r2c2 * b, a.r3c2 * b,
|
||||
a.r1c3 * b, a.r2c3 * b, a.r3c3 * b);
|
||||
new(a.r1c1 * b, a.r1c2 * b, a.r1c3 * b,
|
||||
a.r2c1 * b, a.r2c2 * b, a.r2c3 * b,
|
||||
a.r3c1 * b, a.r3c2 * b, a.r3c3 * b);
|
||||
public static Matrix3x3 operator *(Matrix3x3 a, Matrix3x3 b) => new(new[,]
|
||||
{
|
||||
{ Float3.Dot(a.Row1, b.Column1), Float3.Dot(a.Row1, b.Column2), Float3.Dot(a.Row1, b.Column3) },
|
||||
{ Float3.Dot(a.Row2, b.Column1), Float3.Dot(a.Row2, b.Column2), Float3.Dot(a.Row2, b.Column3) },
|
||||
{ Float3.Dot(a.Row3, b.Column1), Float3.Dot(a.Row3, b.Column2), Float3.Dot(a.Row3, b.Column3) },
|
||||
});
|
||||
public static Float3 operator *(Matrix3x3 a, Float3 b) => (Matrix)a * b;
|
||||
public static Matrix3x3 operator /(Matrix3x3 a, float b) =>
|
||||
new(a.r1c1 / b, a.r2c1 / b, a.r3c1 / b,
|
||||
a.r1c2 / b, a.r2c2 / b, a.r3c2 / b,
|
||||
a.r1c3 / b, a.r2c3 / b, a.r3c3 / b);
|
||||
new(a.r1c1 / b, a.r1c2 / b, a.r1c3 / b,
|
||||
a.r2c1 / b, a.r2c2 / b, a.r2c3 / b,
|
||||
a.r3c1 / b, a.r3c2 / b, a.r3c3 / b);
|
||||
public static Matrix3x3 operator /(Matrix3x3 a, Matrix3x3 b) => a * b.Inverse();
|
||||
public static Float3 operator /(Matrix3x3 a, Float3 b) => (Matrix)a / b;
|
||||
public static Matrix3x3 operator ^(Matrix3x3 a, Matrix3x3 b) => // Single number multiplication
|
||||
new(a.r1c1 * b.r1c1, a.r2c1 * b.r2c1, a.r3c1 * b.r3c1,
|
||||
a.r1c2 * b.r1c2, a.r2c2 * b.r2c2, a.r3c2 * b.r3c2,
|
||||
a.r1c3 * b.r1c3, a.r2c3 * b.r2c3, a.r3c3 * b.r3c3);
|
||||
new(a.r1c1 * b.r1c1, a.r1c2 * b.r1c2, a.r1c3 * b.r1c3,
|
||||
a.r2c1 * b.r2c1, a.r2c2 * b.r2c2, a.r2c3 * b.r2c3,
|
||||
a.r3c1 * b.r3c1, a.r3c2 * b.r3c2, a.r3c3 * b.r3c3);
|
||||
public static bool operator ==(Matrix3x3 a, Matrix3x3 b) => a.Equals(b);
|
||||
public static bool operator !=(Matrix3x3 a, Matrix3x3 b) => !a.Equals(b);
|
||||
|
||||
@ -389,7 +385,7 @@ public struct Matrix3x3 : IMatrix<Matrix3x3, Matrix2x2>
|
||||
{
|
||||
Matrix3x3 res = Zero, identity = Identity;
|
||||
for (int r = 0; r < 3; r++) for (int c = 0; c < 3; c++)
|
||||
res[c, r] = m.Size.x < c && m.Size.y < r ? m[r, c] : identity[r, c];
|
||||
res[c, r] = m.Size.x > r && m.Size.y > c ? m[r, c] : identity[r, c];
|
||||
return res;
|
||||
}
|
||||
public static implicit operator Matrix3x3(Matrix2x2 m)
|
||||
|
||||
@ -65,7 +65,7 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
}
|
||||
public Float4 Row1
|
||||
{
|
||||
get => new(r1c1, r1c2, r1c3, r1c3);
|
||||
get => new(r1c1, r1c2, r1c3, r1c4);
|
||||
set
|
||||
{
|
||||
r1c1 = value.x;
|
||||
@ -76,7 +76,7 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
}
|
||||
public Float4 Row2
|
||||
{
|
||||
get => new(r2c1, r2c2, r2c3, r2c3);
|
||||
get => new(r2c1, r2c2, r2c3, r2c4);
|
||||
set
|
||||
{
|
||||
r2c1 = value.x;
|
||||
@ -87,7 +87,7 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
}
|
||||
public Float4 Row3
|
||||
{
|
||||
get => new(r3c1, r3c2, r3c3, r3c3);
|
||||
get => new(r3c1, r3c2, r3c3, r3c4);
|
||||
set
|
||||
{
|
||||
r3c1 = value.x;
|
||||
@ -98,7 +98,7 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
}
|
||||
public Float4 Row4
|
||||
{
|
||||
get => new(r4c1, r4c2, r4c3, r4c3);
|
||||
get => new(r4c1, r4c2, r4c3, r4c4);
|
||||
set
|
||||
{
|
||||
r4c1 = value.x;
|
||||
@ -112,8 +112,8 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
|
||||
public Matrix4x4(float all) : this(all, all, all, all, all,
|
||||
all, all, all, all, all, all, all, all, all, all, all) { }
|
||||
public Matrix4x4(float r1c1, float r2c1, float r3c1, float r4c1, float r1c2, float r2c2, float r3c2,
|
||||
float r4c2, float r1c3, float r2c3, float r3c3, float r4c3, float r1c4, float r2c4, float r3c4, float r4c4)
|
||||
public Matrix4x4(float r1c1, float r1c2, float r1c3, float r1c4, float r2c1, float r2c2, float r2c3,
|
||||
float r2c4, float r3c1, float r3c2, float r3c3, float r3c4, float r4c1, float r4c2, float r4c3, float r4c4)
|
||||
{
|
||||
this.r1c1 = r1c1;
|
||||
this.r2c1 = r2c1;
|
||||
@ -152,22 +152,22 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
public Matrix4x4(Fill2D<int> fill) : this(fill(0, 0), fill(0, 1), fill(0, 2), fill(0, 3), fill(1, 0),
|
||||
fill(1, 1), fill(1, 2), fill(1, 3), fill(2, 0), fill(2, 1), fill(2, 2), fill(2, 3), fill(3, 0),
|
||||
fill(3, 1), fill(3, 2), fill(3, 3)) { }
|
||||
public Matrix4x4(Float4 c1, Float4 c2, Float4 c3, Float4 c4) : this(c1.x, c1.y, c1.z,
|
||||
c1.w, c2.x, c2.y, c2.z, c2.w, c3.x, c3.y, c3.z, c3.w, c4.x, c4.y, c4.z, c4.w) { }
|
||||
public Matrix4x4(Float4 r1, Float4 r2, Float4 r3, Float4 r4) : this(r1.x, r1.y, r1.z,
|
||||
r1.w, r2.x, r2.y, r2.z, r2.w, r3.x, r3.y, r3.z, r3.w, r4.x, r4.y, r4.z, r4.w) { }
|
||||
public Matrix4x4(Fill<Float4> fill) : this(fill(0), fill(1), fill(2), fill(3)) { }
|
||||
public Matrix4x4(Fill<Int4> fill) : this((IEnumerable<int>)fill(0), fill(1), fill(2), fill(3)) { }
|
||||
public Matrix4x4(IEnumerable<float> c1, IEnumerable<float> c2, IEnumerable<float> c3, IEnumerable<float> c4)
|
||||
: this(c1.ToFill(), c2.ToFill(), c3.ToFill(), c4.ToFill()) { }
|
||||
public Matrix4x4(IEnumerable<int> c1, IEnumerable<int> c2, IEnumerable<int> c3, IEnumerable<int> c4)
|
||||
: this(c1.ToFill(), c2.ToFill(), c3.ToFill(), c4.ToFill()) { }
|
||||
public Matrix4x4(Fill<float> c1, Fill<float> c2, Fill<float> c3, Fill<float> c4) : this(c1(0), c1(1),
|
||||
c1(2), c1(3), c2(0), c2(1), c2(2), c2(3), c3(0), c3(1), c3(2), c3(3), c4(0), c4(1), c4(2), c4(3)) { }
|
||||
public Matrix4x4(Fill<int> c1, Fill<int> c2, Fill<int> c3, Fill<int> c4) : this(c1(0), c1(1),
|
||||
c1(2), c1(3), c2(0), c2(1), c2(2), c2(3), c3(0), c3(1), c3(2), c3(3), c4(0), c4(1), c4(2), c4(3)) { }
|
||||
public Matrix4x4(IEnumerable<float> r1, IEnumerable<float> r2, IEnumerable<float> r3, IEnumerable<float> r4)
|
||||
: this(r1.ToFill(), r2.ToFill(), r3.ToFill(), r4.ToFill()) { }
|
||||
public Matrix4x4(IEnumerable<int> r1, IEnumerable<int> r2, IEnumerable<int> r3, IEnumerable<int> r4)
|
||||
: this(r1.ToFill(), r2.ToFill(), r3.ToFill(), r4.ToFill()) { }
|
||||
public Matrix4x4(Fill<float> r1, Fill<float> r2, Fill<float> r3, Fill<float> r4) : this(r1(0), r1(1),
|
||||
r1(2), r1(3), r2(0), r2(1), r2(2), r2(3), r3(0), r3(1), r3(2), r3(3), r4(0), r4(1), r4(2), r4(3)) { }
|
||||
public Matrix4x4(Fill<int> r1, Fill<int> r2, Fill<int> r3, Fill<int> r4) : this(r1(0), r1(1),
|
||||
r1(2), r1(3), r2(0), r2(1), r2(2), r2(3), r3(0), r3(1), r3(2), r3(3), r4(0), r4(1), r4(2), r4(3)) { }
|
||||
|
||||
public float this[int r, int c]
|
||||
{
|
||||
get => ToArray2D()[c, r];
|
||||
get => ToArray2D()[r, c];
|
||||
set
|
||||
{
|
||||
// Maybe this could be improved?
|
||||
@ -253,44 +253,44 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
}
|
||||
|
||||
public static Matrix4x4 Absolute(Matrix4x4 val) =>
|
||||
new(Mathf.Absolute(val.r1c1), Mathf.Absolute(val.r2c1), Mathf.Absolute(val.r3c1), Mathf.Absolute(val.r4c1),
|
||||
Mathf.Absolute(val.r1c2), Mathf.Absolute(val.r2c2), Mathf.Absolute(val.r3c2), Mathf.Absolute(val.r4c2),
|
||||
Mathf.Absolute(val.r1c3), Mathf.Absolute(val.r2c3), Mathf.Absolute(val.r3c3), Mathf.Absolute(val.r4c2),
|
||||
Mathf.Absolute(val.r1c4), Mathf.Absolute(val.r2c4), Mathf.Absolute(val.r3c4), Mathf.Absolute(val.r4c4));
|
||||
new(Mathf.Absolute(val.r1c1), Mathf.Absolute(val.r1c2), Mathf.Absolute(val.r1c3), Mathf.Absolute(val.r1c4),
|
||||
Mathf.Absolute(val.r2c1), Mathf.Absolute(val.r2c2), Mathf.Absolute(val.r2c3), Mathf.Absolute(val.r2c4),
|
||||
Mathf.Absolute(val.r3c1), Mathf.Absolute(val.r3c2), Mathf.Absolute(val.r3c3), Mathf.Absolute(val.r3c4),
|
||||
Mathf.Absolute(val.r4c1), Mathf.Absolute(val.r4c2), Mathf.Absolute(val.r4c3), Mathf.Absolute(val.r4c4));
|
||||
public static Matrix4x4 Average(params Matrix4x4[] vals) => Sum(vals) / vals.Length;
|
||||
public static Matrix4x4 Ceiling(Matrix4x4 val) =>
|
||||
new(Mathf.Ceiling(val.r1c1), Mathf.Ceiling(val.r2c1), Mathf.Ceiling(val.r3c1), Mathf.Ceiling(val.r4c1),
|
||||
Mathf.Ceiling(val.r1c2), Mathf.Ceiling(val.r2c2), Mathf.Ceiling(val.r3c2), Mathf.Ceiling(val.r4c2),
|
||||
Mathf.Ceiling(val.r1c3), Mathf.Ceiling(val.r2c3), Mathf.Ceiling(val.r3c3), Mathf.Ceiling(val.r4c2),
|
||||
Mathf.Ceiling(val.r1c4), Mathf.Ceiling(val.r2c4), Mathf.Ceiling(val.r3c4), Mathf.Ceiling(val.r4c4));
|
||||
new(Mathf.Ceiling(val.r1c1), Mathf.Ceiling(val.r1c2), Mathf.Ceiling(val.r1c3), Mathf.Ceiling(val.r1c4),
|
||||
Mathf.Ceiling(val.r2c1), Mathf.Ceiling(val.r2c2), Mathf.Ceiling(val.r2c3), Mathf.Ceiling(val.r2c4),
|
||||
Mathf.Ceiling(val.r3c1), Mathf.Ceiling(val.r3c2), Mathf.Ceiling(val.r3c3), Mathf.Ceiling(val.r3c4),
|
||||
Mathf.Ceiling(val.r4c1), Mathf.Ceiling(val.r4c2), Mathf.Ceiling(val.r4c3), Mathf.Ceiling(val.r4c4));
|
||||
public static Matrix4x4 Clamp(Matrix4x4 val, Matrix4x4 min, Matrix4x4 max) =>
|
||||
new(Mathf.Clamp(val.r1c1, min.r1c1, max.r1c1), Mathf.Clamp(val.r2c1, min.r2c1, max.r2c1),
|
||||
Mathf.Clamp(val.r3c1, min.r3c1, max.r3c1), Mathf.Clamp(val.r4c1, min.r4c1, max.r4c1),
|
||||
Mathf.Clamp(val.r1c2, min.r1c2, max.r1c2), Mathf.Clamp(val.r2c2, min.r2c2, max.r2c2),
|
||||
Mathf.Clamp(val.r3c2, min.r3c2, max.r3c2), Mathf.Clamp(val.r4c2, min.r4c2, max.r4c2),
|
||||
Mathf.Clamp(val.r1c3, min.r1c3, max.r1c3), Mathf.Clamp(val.r2c3, min.r2c3, max.r2c3),
|
||||
Mathf.Clamp(val.r3c3, min.r3c3, max.r3c3), Mathf.Clamp(val.r4c3, min.r4c3, max.r4c3),
|
||||
Mathf.Clamp(val.r1c4, min.r1c4, max.r1c4), Mathf.Clamp(val.r2c4, min.r2c4, max.r2c4),
|
||||
Mathf.Clamp(val.r3c4, min.r3c4, max.r3c4), Mathf.Clamp(val.r4c4, min.r4c4, max.r4c4));
|
||||
new(Mathf.Clamp(val.r1c1, min.r1c1, max.r1c1), Mathf.Clamp(val.r1c2, min.r1c2, max.r1c2),
|
||||
Mathf.Clamp(val.r1c3, min.r1c3, max.r1c3), Mathf.Clamp(val.r1c4, min.r1c4, max.r1c4),
|
||||
Mathf.Clamp(val.r2c1, min.r2c1, max.r2c1), Mathf.Clamp(val.r2c2, min.r2c2, max.r2c2),
|
||||
Mathf.Clamp(val.r2c3, min.r2c3, max.r2c3), Mathf.Clamp(val.r2c4, min.r2c4, max.r2c4),
|
||||
Mathf.Clamp(val.r3c1, min.r3c1, max.r3c1), Mathf.Clamp(val.r3c2, min.r3c2, max.r3c2),
|
||||
Mathf.Clamp(val.r3c3, min.r3c3, max.r3c3), Mathf.Clamp(val.r3c4, min.r3c4, max.r3c4),
|
||||
Mathf.Clamp(val.r4c1, min.r4c1, max.r4c1), Mathf.Clamp(val.r4c2, min.r4c2, max.r4c2),
|
||||
Mathf.Clamp(val.r4c3, min.r4c3, max.r4c3), Mathf.Clamp(val.r4c4, min.r4c4, max.r4c4));
|
||||
public static Matrix4x4 Divide(Matrix4x4 num, params Matrix4x4[] vals)
|
||||
{
|
||||
foreach (Matrix4x4 m in vals) num /= m;
|
||||
return num;
|
||||
}
|
||||
public static Matrix4x4 Floor(Matrix4x4 val) =>
|
||||
new(Mathf.Floor(val.r1c1), Mathf.Floor(val.r2c1), Mathf.Floor(val.r3c1), Mathf.Floor(val.r4c1),
|
||||
Mathf.Floor(val.r1c2), Mathf.Floor(val.r2c2), Mathf.Floor(val.r3c2), Mathf.Floor(val.r4c2),
|
||||
Mathf.Floor(val.r1c3), Mathf.Floor(val.r2c3), Mathf.Floor(val.r3c3), Mathf.Floor(val.r4c2),
|
||||
Mathf.Floor(val.r1c4), Mathf.Floor(val.r2c4), Mathf.Floor(val.r3c4), Mathf.Floor(val.r4c4));
|
||||
new(Mathf.Floor(val.r1c1), Mathf.Floor(val.r1c2), Mathf.Floor(val.r1c3), Mathf.Floor(val.r1c4),
|
||||
Mathf.Floor(val.r2c1), Mathf.Floor(val.r2c2), Mathf.Floor(val.r2c3), Mathf.Floor(val.r2c4),
|
||||
Mathf.Floor(val.r3c1), Mathf.Floor(val.r3c2), Mathf.Floor(val.r3c3), Mathf.Floor(val.r3c4),
|
||||
Mathf.Floor(val.r4c1), Mathf.Floor(val.r4c2), Mathf.Floor(val.r4c3), Mathf.Floor(val.r4c4));
|
||||
public static Matrix4x4 Lerp(Matrix4x4 a, Matrix4x4 b, float t, bool clamp = true) =>
|
||||
new(Mathf.Lerp(a.r1c1, b.r1c1, t, clamp), Mathf.Lerp(a.r2c1, b.r2c1, t, clamp),
|
||||
Mathf.Lerp(a.r3c1, b.r3c1, t, clamp), Mathf.Lerp(a.r4c1, b.r4c1, t, clamp),
|
||||
Mathf.Lerp(a.r1c2, b.r1c2, t, clamp), Mathf.Lerp(a.r2c2, b.r2c2, t, clamp),
|
||||
Mathf.Lerp(a.r3c2, b.r3c2, t, clamp), Mathf.Lerp(a.r4c2, b.r4c2, t, clamp),
|
||||
Mathf.Lerp(a.r1c3, b.r1c3, t, clamp), Mathf.Lerp(a.r2c3, b.r2c3, t, clamp),
|
||||
Mathf.Lerp(a.r3c3, b.r3c3, t, clamp), Mathf.Lerp(a.r4c3, b.r4c3, t, clamp),
|
||||
Mathf.Lerp(a.r1c4, b.r1c4, t, clamp), Mathf.Lerp(a.r2c4, b.r2c4, t, clamp),
|
||||
Mathf.Lerp(a.r3c4, b.r3c4, t, clamp), Mathf.Lerp(a.r4c4, b.r4c4, t, clamp));
|
||||
new(Mathf.Lerp(a.r1c1, b.r1c1, t, clamp), Mathf.Lerp(a.r1c2, b.r1c2, t, clamp),
|
||||
Mathf.Lerp(a.r1c3, b.r1c3, t, clamp), Mathf.Lerp(a.r1c4, b.r1c4, t, clamp),
|
||||
Mathf.Lerp(a.r2c1, b.r2c1, t, clamp), Mathf.Lerp(a.r2c2, b.r2c2, t, clamp),
|
||||
Mathf.Lerp(a.r2c3, b.r2c3, t, clamp), Mathf.Lerp(a.r2c4, b.r2c4, t, clamp),
|
||||
Mathf.Lerp(a.r3c1, b.r3c1, t, clamp), Mathf.Lerp(a.r3c2, b.r3c2, t, clamp),
|
||||
Mathf.Lerp(a.r3c3, b.r3c3, t, clamp), Mathf.Lerp(a.r3c4, b.r3c4, t, clamp),
|
||||
Mathf.Lerp(a.r4c1, b.r4c1, t, clamp), Mathf.Lerp(a.r4c2, b.r4c2, t, clamp),
|
||||
Mathf.Lerp(a.r4c3, b.r4c3, t, clamp), Mathf.Lerp(a.r4c4, b.r4c4, t, clamp));
|
||||
public static Matrix4x4 Median(params Matrix4x4[] vals)
|
||||
{
|
||||
float index = Mathf.Average(0, vals.Length - 1);
|
||||
@ -305,10 +305,10 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
return val;
|
||||
}
|
||||
public static Matrix4x4 Round(Matrix4x4 val) =>
|
||||
new(Mathf.Round(val.r1c1), Mathf.Round(val.r2c1), Mathf.Round(val.r3c1), Mathf.Round(val.r4c1),
|
||||
Mathf.Round(val.r1c2), Mathf.Round(val.r2c2), Mathf.Round(val.r3c2), Mathf.Round(val.r4c2),
|
||||
Mathf.Round(val.r1c3), Mathf.Round(val.r2c3), Mathf.Round(val.r3c3), Mathf.Round(val.r4c2),
|
||||
Mathf.Round(val.r1c4), Mathf.Round(val.r2c4), Mathf.Round(val.r3c4), Mathf.Round(val.r4c4));
|
||||
new(Mathf.Round(val.r1c1), Mathf.Round(val.r1c2), Mathf.Round(val.r1c3), Mathf.Round(val.r1c4),
|
||||
Mathf.Round(val.r2c1), Mathf.Round(val.r2c2), Mathf.Round(val.r2c3), Mathf.Round(val.r2c4),
|
||||
Mathf.Round(val.r3c1), Mathf.Round(val.r3c2), Mathf.Round(val.r3c3), Mathf.Round(val.r3c4),
|
||||
Mathf.Round(val.r4c1), Mathf.Round(val.r4c2), Mathf.Round(val.r4c3), Mathf.Round(val.r4c4));
|
||||
public static Matrix4x4 Subtract(Matrix4x4 num, params Matrix4x4[] vals)
|
||||
{
|
||||
foreach (Matrix4x4 m in vals) num -= m;
|
||||
@ -321,37 +321,41 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
return val;
|
||||
}
|
||||
|
||||
public static (float[] r1c1s, float[] r2c1s, float[] r3c1s, float[] r4c1s, float[] r1c2s, float[] r2c2s,
|
||||
float[] r3c2s, float[] r4c2s, float[] r1c3s, float[] r2c3s, float[] r3c3s, float[] r4c3s, float[] r1c4s,
|
||||
float[] r2c4s, float[] r3c4s, float[] r4c4s) SplitArray(params Matrix4x4[] vals)
|
||||
public static (float[] r1c1s, float[] r1c2, float[] r1c3, float[] r1c4, float[] r2c1, float[] r2c2s,
|
||||
float[] r2c3, float[] r2c4, float[] r3c1, float[] r3c2, float[] r3c3s, float[] r3c4, float[] r4c1,
|
||||
float[] r4c2, float[] r4c3, float[] r4c4s) SplitArray(params Matrix4x4[] vals)
|
||||
{
|
||||
float[] r1c1s = new float[vals.Length], r2c1s = new float[vals.Length], r3c1s = new float[vals.Length],
|
||||
r4c1s = new float[vals.Length], r1c2s = new float[vals.Length], r2c2s = new float[vals.Length],
|
||||
r3c2s = new float[vals.Length], r4c2s = new float[vals.Length], r1c3s = new float[vals.Length],
|
||||
r2c3s = new float[vals.Length], r3c3s = new float[vals.Length], r4c3s = new float[vals.Length],
|
||||
r1c4s = new float[vals.Length], r2c4s = new float[vals.Length], r3c4s = new float[vals.Length],
|
||||
float[] r1c1s = new float[vals.Length], r1c2s = new float[vals.Length], r1c3s = new float[vals.Length],
|
||||
r1c4s = new float[vals.Length], r2c1s = new float[vals.Length], r2c2s = new float[vals.Length],
|
||||
r2c3s = new float[vals.Length], r2c4s = new float[vals.Length], r3c1s = new float[vals.Length],
|
||||
r3c2s = new float[vals.Length], r3c3s = new float[vals.Length], r3c4s = new float[vals.Length],
|
||||
r4c1s = new float[vals.Length], r4c2s = new float[vals.Length], r4c3s = new float[vals.Length],
|
||||
r4c4s = new float[vals.Length];
|
||||
for (int i = 0; i < vals.Length; i++)
|
||||
{
|
||||
r1c1s[i] = vals[i].r1c1;
|
||||
r2c1s[i] = vals[i].r2c1;
|
||||
r3c1s[i] = vals[i].r3c1;
|
||||
r4c1s[i] = vals[i].r4c1;
|
||||
r1c2s[i] = vals[i].r1c2;
|
||||
r2c2s[i] = vals[i].r2c2;
|
||||
r3c2s[i] = vals[i].r3c2;
|
||||
r4c2s[i] = vals[i].r4c2;
|
||||
r1c3s[i] = vals[i].r1c3;
|
||||
r1c4s[i] = vals[i].r1c4;
|
||||
r2c1s[i] = vals[i].r2c1;
|
||||
r2c2s[i] = vals[i].r2c2;
|
||||
r2c3s[i] = vals[i].r2c3;
|
||||
r2c4s[i] = vals[i].r2c4;
|
||||
r3c1s[i] = vals[i].r3c1;
|
||||
r3c2s[i] = vals[i].r3c2;
|
||||
r3c3s[i] = vals[i].r3c3;
|
||||
r3c4s[i] = vals[i].r3c4;
|
||||
r4c1s[i] = vals[i].r4c1;
|
||||
r4c2s[i] = vals[i].r4c2;
|
||||
r4c3s[i] = vals[i].r4c3;
|
||||
r4c4s[i] = vals[i].r4c4;
|
||||
}
|
||||
return (r1c1s, r2c1s, r3c1s, r4c1s, r1c2s, r2c2s, r3c2s, r4c2s,
|
||||
r1c3s, r2c3s, r3c3s, r4c3s, r1c4s, r2c4s, r3c4s, r4c4s);
|
||||
return (r1c1s, r1c2s, r1c3s, r1c4s, r2c1s, r2c2s, r2c3s, r2c4s,
|
||||
r3c1s, r3c2s, r3c3s, r3c4s, r4c1s, r4c2s, r4c3s, r4c4s);
|
||||
}
|
||||
|
||||
public Matrix4x4 Adjugate()
|
||||
public Matrix4x4 Adjugate() => Cofactor().Transpose();
|
||||
public Matrix4x4 Cofactor()
|
||||
{
|
||||
Matrix4x4 dets = new();
|
||||
Matrix3x3[,] minors = Minors();
|
||||
@ -361,40 +365,40 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
public float Determinant()
|
||||
{
|
||||
Matrix3x3[,] minors = Minors();
|
||||
return (r1c1 * minors[0, 0].Determinant()) - (r1c2 * minors[1, 0].Determinant()) +
|
||||
(r1c3 * minors[2, 0].Determinant()) - (r1c4 * minors[3, 0].Determinant());
|
||||
return (r1c1 * minors[0, 0].Determinant()) - (r1c2 * minors[0, 1].Determinant()) +
|
||||
(r1c3 * minors[0, 2].Determinant()) - (r1c4 * minors[0, 3].Determinant());
|
||||
}
|
||||
public Matrix4x4 Inverse()
|
||||
{
|
||||
float d = Determinant();
|
||||
if (d == 0) throw new NoInverseException();
|
||||
return Transpose().Adjugate() / d;
|
||||
return Adjugate() / d;
|
||||
}
|
||||
public Matrix3x3[,] Minors() => new Matrix3x3[,]
|
||||
{
|
||||
{
|
||||
new(r2c2, r3c2, r4c2, r2c3, r3c3, r4c3, r2c4, r3c4, r4c4),
|
||||
new(r2c1, r3c1, r4c1, r2c3, r3c3, r4c3, r2c4, r3c4, r4c4),
|
||||
new(r2c1, r3c1, r4c1, r2c2, r3c2, r4c2, r2c4, r3c4, r4c4),
|
||||
new(r2c1, r3c1, r4c1, r2c2, r3c2, r4c2, r2c3, r3c3, r4c3)
|
||||
new(r2c2, r2c3, r2c4, r3c2, r3c3, r3c4, r4c2, r4c3, r4c4),
|
||||
new(r2c1, r2c3, r2c4, r3c1, r3c3, r3c4, r4c1, r4c3, r4c4),
|
||||
new(r2c1, r2c2, r2c4, r3c1, r3c2, r3c4, r4c1, r4c2, r4c4),
|
||||
new(r2c1, r2c2, r2c3, r3c1, r3c2, r3c3, r4c1, r4c2, r4c3)
|
||||
},
|
||||
{
|
||||
new(r1c2, r3c2, r4c2, r1c3, r3c3, r4c3, r1c4, r3c4, r4c4),
|
||||
new(r1c1, r3c1, r4c1, r1c3, r3c3, r4c3, r1c4, r3c4, r4c4),
|
||||
new(r1c1, r3c1, r4c1, r1c2, r3c2, r4c2, r1c4, r3c4, r4c4),
|
||||
new(r1c1, r3c1, r4c1, r1c2, r3c2, r4c2, r1c3, r3c3, r4c3)
|
||||
new(r1c2, r1c3, r1c4, r3c2, r3c3, r3c4, r4c2, r4c3, r4c4),
|
||||
new(r1c1, r1c3, r1c4, r3c1, r3c3, r3c4, r4c1, r4c3, r4c4),
|
||||
new(r1c1, r1c2, r1c4, r3c1, r3c2, r3c4, r4c1, r4c2, r4c4),
|
||||
new(r1c1, r1c2, r1c3, r3c1, r3c2, r3c3, r4c1, r4c2, r4c3)
|
||||
},
|
||||
{
|
||||
new(r1c2, r2c2, r4c2, r1c3, r2c3, r4c3, r1c4, r2c4, r4c4),
|
||||
new(r1c1, r2c1, r4c1, r1c3, r2c3, r4c3, r1c4, r2c4, r4c4),
|
||||
new(r1c1, r2c1, r4c1, r1c2, r2c2, r4c2, r1c4, r2c4, r4c4),
|
||||
new(r1c1, r2c1, r4c1, r1c2, r2c2, r4c2, r1c3, r2c3, r4c3)
|
||||
new(r1c2, r1c3, r1c4, r2c2, r2c3, r2c4, r4c2, r4c3, r4c4),
|
||||
new(r1c1, r1c3, r1c4, r2c1, r2c3, r2c4, r4c1, r4c3, r4c4),
|
||||
new(r1c1, r1c2, r1c4, r2c1, r2c2, r2c4, r4c1, r4c2, r4c4),
|
||||
new(r1c1, r1c2, r1c3, r2c1, r2c2, r2c3, r4c1, r4c2, r4c3)
|
||||
},
|
||||
{
|
||||
new(r1c2, r2c2, r3c2, r1c3, r2c3, r3c3, r1c4, r2c4, r3c4),
|
||||
new(r1c1, r2c1, r3c1, r1c3, r2c3, r3c3, r1c4, r2c4, r3c4),
|
||||
new(r1c1, r2c1, r3c1, r1c2, r2c2, r3c2, r1c4, r2c4, r3c4),
|
||||
new(r1c1, r2c1, r3c1, r1c2, r2c2, r3c2, r1c3, r2c3, r3c3)
|
||||
new(r1c2, r1c3, r1c4, r2c2, r2c3, r2c4, r3c2, r3c3, r3c4),
|
||||
new(r1c1, r1c3, r1c4, r2c1, r2c3, r2c4, r3c1, r3c3, r3c4),
|
||||
new(r1c1, r1c2, r1c4, r2c1, r2c2, r2c4, r3c1, r3c2, r3c4),
|
||||
new(r1c1, r1c2, r1c3, r2c1, r2c2, r2c3, r3c1, r3c2, r3c3)
|
||||
}
|
||||
};
|
||||
public Matrix4x4 Transpose() => new(new[,]
|
||||
@ -411,15 +415,16 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
return Equals((Matrix4x4)obj);
|
||||
}
|
||||
public bool Equals(Matrix4x4 other) =>
|
||||
r1c1 == other.r1c1 && r2c1 == other.r2c1 && r3c1 == other.r3c1 && r4c1 == other.r4c1 &&
|
||||
r1c2 == other.r1c2 && r2c2 == other.r2c2 && r3c2 == other.r3c2 && r4c2 == other.r4c2 &&
|
||||
r1c3 == other.r1c3 && r2c3 == other.r2c3 && r3c3 == other.r3c3 && r4c3 == other.r4c3 &&
|
||||
r1c4 == other.r1c4 && r2c3 == other.r2c4 && r3c4 == other.r3c4 && r4c4 == other.r4c4;
|
||||
r1c1 == other.r1c1 && r1c2 == other.r1c2 && r1c3 == other.r1c3 && r1c4 == other.r1c4 &&
|
||||
r2c1 == other.r2c1 && r2c2 == other.r2c2 && r2c3 == other.r2c3 && r2c4 == other.r2c4 &&
|
||||
r3c1 == other.r3c1 && r3c2 == other.r3c2 && r3c3 == other.r3c3 && r3c4 == other.r3c4 &&
|
||||
r4c1 == other.r4c1 && r4c2 == other.r4c2 && r4c3 == other.r4c3 && r4c4 == other.r4c4;
|
||||
public override int GetHashCode() =>
|
||||
r1c1.GetHashCode() ^ r2c1.GetHashCode() ^ r3c1.GetHashCode() ^ r4c1.GetHashCode() ^
|
||||
r1c2.GetHashCode() ^ r2c2.GetHashCode() ^ r3c2.GetHashCode() ^ r4c2.GetHashCode() ^
|
||||
r1c3.GetHashCode() ^ r2c3.GetHashCode() ^ r3c3.GetHashCode() ^ r4c3.GetHashCode() ^
|
||||
r1c4.GetHashCode() ^ r2c4.GetHashCode() ^ r3c4.GetHashCode() ^ r4c4.GetHashCode();
|
||||
r1c1.GetHashCode() ^ r1c2.GetHashCode() ^ r1c3.GetHashCode() ^ r1c4.GetHashCode() ^
|
||||
r2c1.GetHashCode() ^ r2c2.GetHashCode() ^ r2c3.GetHashCode() ^ r2c4.GetHashCode() ^
|
||||
r3c1.GetHashCode() ^ r3c2.GetHashCode() ^ r3c3.GetHashCode() ^ r3c4.GetHashCode() ^
|
||||
r4c1.GetHashCode() ^ r4c2.GetHashCode() ^ r4c3.GetHashCode() ^ r4c4.GetHashCode();
|
||||
public override string ToString() => ToString((string?)null);
|
||||
public string ToString(string? provider) =>
|
||||
r1c1.ToString(provider) + " " + r1c2.ToString(provider) + " " + r1c3.ToString(provider) + " " +
|
||||
r1c4.ToString(provider) + "\n" + r2c1.ToString(provider) + " " + r2c2.ToString(provider) + " " +
|
||||
@ -441,20 +446,20 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
public IEnumerator<float> GetEnumerator()
|
||||
{
|
||||
yield return r1c1;
|
||||
yield return r2c1;
|
||||
yield return r3c1;
|
||||
yield return r4c1;
|
||||
yield return r1c2;
|
||||
yield return r2c2;
|
||||
yield return r3c2;
|
||||
yield return r4c2;
|
||||
yield return r1c3;
|
||||
yield return r2c3;
|
||||
yield return r3c3;
|
||||
yield return r4c3;
|
||||
yield return r1c4;
|
||||
yield return r2c1;
|
||||
yield return r2c2;
|
||||
yield return r2c3;
|
||||
yield return r2c4;
|
||||
yield return r3c1;
|
||||
yield return r3c2;
|
||||
yield return r3c3;
|
||||
yield return r3c4;
|
||||
yield return r4c1;
|
||||
yield return r4c2;
|
||||
yield return r4c3;
|
||||
yield return r4c4;
|
||||
}
|
||||
|
||||
@ -472,13 +477,6 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
{ r3c1, r3c2, r3c3, r3c4 },
|
||||
{ r4c1, r4c2, r4c3, r4c4 }
|
||||
};
|
||||
public Dictionary<Int2, float> ToDictionary()
|
||||
{
|
||||
Dictionary<Int2, float> dict = new();
|
||||
float[] arr = ToArray();
|
||||
for (int i = 0; i < arr.Length; i++) dict.Add(new(i % 4, i / 4), arr[i]);
|
||||
return dict;
|
||||
}
|
||||
public Fill<float> ToFill() => ToFillExtension.ToFill(this);
|
||||
public Fill2D<float> ToFill2D()
|
||||
{
|
||||
@ -494,21 +492,21 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
};
|
||||
|
||||
public static Matrix4x4 operator +(Matrix4x4 a, Matrix4x4 b) =>
|
||||
new(a.r1c1 + b.r1c1, a.r2c1 + b.r2c1, a.r3c1 + b.r3c1, a.r4c1 + b.r4c1,
|
||||
a.r1c2 + b.r1c2, a.r2c2 + b.r2c2, a.r3c2 + b.r3c2, a.r4c2 + b.r4c2,
|
||||
a.r1c3 + b.r1c3, a.r2c3 + b.r2c3, a.r3c3 + b.r3c3, a.r4c3 + b.r4c3,
|
||||
a.r1c4 + b.r1c4, a.r2c4 + b.r2c4, a.r3c4 + b.r3c4, a.r4c4 + b.r4c4);
|
||||
new(a.r1c1 + b.r1c1, a.r1c2 + b.r1c2, a.r1c3 + b.r1c3, a.r1c4 + b.r1c4,
|
||||
a.r2c1 + b.r2c1, a.r2c2 + b.r2c2, a.r2c3 + b.r2c3, a.r2c4 + b.r2c4,
|
||||
a.r3c1 + b.r3c1, a.r3c2 + b.r3c2, a.r3c3 + b.r3c3, a.r3c4 + b.r3c4,
|
||||
a.r4c1 + b.r4c1, a.r4c2 + b.r4c2, a.r4c3 + b.r4c3, a.r4c4 + b.r4c4);
|
||||
public static Matrix4x4 operator -(Matrix4x4 m) => m.Inverse();
|
||||
public static Matrix4x4 operator -(Matrix4x4 a, Matrix4x4 b) =>
|
||||
new(a.r1c1 - b.r1c1, a.r2c1 - b.r2c1, a.r3c1 - b.r3c1, a.r4c1 - b.r4c1,
|
||||
a.r1c2 - b.r1c2, a.r2c2 - b.r2c2, a.r3c2 - b.r3c2, a.r4c2 - b.r4c2,
|
||||
a.r1c3 - b.r1c3, a.r2c3 - b.r2c3, a.r3c3 - b.r3c3, a.r4c3 - b.r4c3,
|
||||
a.r1c4 - b.r1c4, a.r2c4 - b.r2c4, a.r3c4 - b.r3c4, a.r4c4 - b.r4c4);
|
||||
new(a.r1c1 - b.r1c1, a.r1c2 - b.r1c2, a.r1c3 - b.r1c3, a.r1c4 - b.r1c4,
|
||||
a.r2c1 - b.r2c1, a.r2c2 - b.r2c2, a.r2c3 - b.r2c3, a.r2c4 - b.r2c4,
|
||||
a.r3c1 - b.r3c1, a.r3c2 - b.r3c2, a.r3c3 - b.r3c3, a.r3c4 - b.r3c4,
|
||||
a.r4c1 - b.r4c1, a.r4c2 - b.r4c2, a.r4c3 - b.r4c3, a.r4c4 - b.r4c4);
|
||||
public static Matrix4x4 operator *(Matrix4x4 a, float b) =>
|
||||
new(a.r1c1 * b, a.r2c1 * b, a.r3c1 * b, a.r4c1 * b,
|
||||
a.r1c2 * b, a.r2c2 * b, a.r3c2 * b, a.r4c2 * b,
|
||||
a.r1c3 * b, a.r2c3 * b, a.r3c3 * b, a.r4c3 * b,
|
||||
a.r1c4 * b, a.r2c4 * b, a.r3c4 * b, a.r4c4 * b);
|
||||
new(a.r1c1 * b, a.r1c2 * b, a.r1c3 * b, a.r1c4 * b,
|
||||
a.r2c1 * b, a.r2c2 * b, a.r2c3 * b, a.r2c4 * b,
|
||||
a.r3c1 * b, a.r3c2 * b, a.r3c3 * b, a.r3c4 * b,
|
||||
a.r4c1 * b, a.r4c2 * b, a.r4c3 * b, a.r4c4 * b);
|
||||
public static Matrix4x4 operator *(Matrix4x4 a, Matrix4x4 b) => new(new[,]
|
||||
{
|
||||
{ Float4.Dot(a.Row1, b.Column1), Float4.Dot(a.Row1, b.Column2),
|
||||
@ -520,17 +518,19 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
{ Float4.Dot(a.Row4, b.Column1), Float4.Dot(a.Row4, b.Column2),
|
||||
Float4.Dot(a.Row4, b.Column3), Float4.Dot(a.Row4, b.Column4) }
|
||||
});
|
||||
public static Float4 operator *(Matrix4x4 a, Float4 b) => (Matrix)a * b;
|
||||
public static Matrix4x4 operator /(Matrix4x4 a, float b) =>
|
||||
new(a.r1c1 / b, a.r2c1 / b, a.r3c1 / b, a.r4c1 / b,
|
||||
a.r1c2 / b, a.r2c2 / b, a.r3c2 / b, a.r4c2 / b,
|
||||
a.r1c3 / b, a.r2c3 / b, a.r3c3 / b, a.r4c3 / b,
|
||||
a.r1c4 / b, a.r2c4 / b, a.r3c4 / b, a.r4c4 / b);
|
||||
new(a.r1c1 / b, a.r1c2 / b, a.r1c3 / b, a.r1c4 / b,
|
||||
a.r2c1 / b, a.r2c2 / b, a.r2c3 / b, a.r2c4 / b,
|
||||
a.r3c1 / b, a.r3c2 / b, a.r3c3 / b, a.r3c4 / b,
|
||||
a.r4c1 / b, a.r4c2 / b, a.r4c3 / b, a.r4c4 / b);
|
||||
public static Matrix4x4 operator /(Matrix4x4 a, Matrix4x4 b) => a * b.Inverse();
|
||||
public static Float4 operator /(Matrix4x4 a, Float4 b) => (Matrix)a / b;
|
||||
public static Matrix4x4 operator ^(Matrix4x4 a, Matrix4x4 b) => // Single number multiplication
|
||||
new(a.r1c1 * b.r1c1, a.r2c1 * b.r2c1, a.r3c1 * b.r3c1, a.r4c1 * b.r4c1,
|
||||
a.r1c2 * b.r1c2, a.r2c2 * b.r2c2, a.r3c2 * b.r3c2, a.r4c2 * b.r4c2,
|
||||
a.r1c3 * b.r1c3, a.r2c3 * b.r2c3, a.r3c3 * b.r3c3, a.r4c3 * b.r4c3,
|
||||
a.r1c4 * b.r1c4, a.r2c4 * b.r2c4, a.r3c4 * b.r3c4, a.r4c4 * b.r4c4);
|
||||
new(a.r1c1 * b.r1c1, a.r1c2 * b.r1c2, a.r1c3 * b.r1c3, a.r1c4 * b.r1c4,
|
||||
a.r2c1 * b.r2c1, a.r2c2 * b.r2c2, a.r2c3 * b.r2c3, a.r2c4 * b.r2c4,
|
||||
a.r3c1 * b.r3c1, a.r3c2 * b.r3c2, a.r3c3 * b.r3c3, a.r3c4 * b.r3c4,
|
||||
a.r4c1 * b.r4c1, a.r4c2 * b.r4c2, a.r4c3 * b.r4c3, a.r4c4 * b.r4c4);
|
||||
public static bool operator ==(Matrix4x4 a, Matrix4x4 b) => a.Equals(b);
|
||||
public static bool operator !=(Matrix4x4 a, Matrix4x4 b) => !a.Equals(b);
|
||||
|
||||
@ -538,7 +538,7 @@ public struct Matrix4x4 : IMatrix<Matrix4x4, Matrix3x3>
|
||||
{
|
||||
Matrix4x4 res = Zero, identity = Identity;
|
||||
for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++)
|
||||
res[c, r] = m.Size.x < c && m.Size.y < r ? m[r, c] : identity[r, c];
|
||||
res[c, r] = m.Size.x > r && m.Size.y > c ? m[r, c] : identity[r, c];
|
||||
return res;
|
||||
}
|
||||
public static implicit operator Matrix4x4(Matrix2x2 m)
|
||||
|
||||
@ -5,14 +5,14 @@ public struct Float4 : ICloneable, IComparable<Float4>, IEquatable<Float4>, 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)]
|
||||
"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)]
|
||||
"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);
|
||||
|
||||
@ -24,7 +24,7 @@ public struct Box2D : ICloneable, IContainer<Vert>, IEquatable<Box2D>
|
||||
}
|
||||
|
||||
public float Area => size.x * size.y;
|
||||
public float Perimeter => size.x * 2 + size.y * 2;
|
||||
public float Perimeter => 2 * (size.x + size.y);
|
||||
|
||||
public Vert center;
|
||||
public Float2 size;
|
||||
|
||||
@ -23,8 +23,9 @@ public struct Box3D : ICloneable, IContainer<Vert>, IEquatable<Box3D>
|
||||
}
|
||||
}
|
||||
|
||||
public float Area => size.x * size.y * size.z;
|
||||
public float Perimeter => size.x * 2 + size.y * 2 + size.z * 2;
|
||||
public float Perimeter => 2 * (size.x + size.y + size.z);
|
||||
public float SurfaceArea => 2 * (size.x * size.y + size.y * size.z + size.x * size.z);
|
||||
public float Volume => size.x * size.y * size.z;
|
||||
|
||||
public Vert center;
|
||||
public Float3 size;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
namespace Nerd_STF.Mathematics.Geometry;
|
||||
|
||||
[Obsolete("This struct is a garbage fire. This will be completely redesigned in v2.4.0")]
|
||||
public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdividable<Polygon>, ITriangulatable
|
||||
{
|
||||
public Line[] Lines
|
||||
@ -379,8 +380,10 @@ public struct Polygon : ICloneable, IEquatable<Polygon>, IGroup<Vert>, ISubdivid
|
||||
if (closest.Value.posB > closest.Value.posA)
|
||||
closest = (closest.Value.posB, closest.Value.posA, closest.Value.line);
|
||||
|
||||
List<Line> partA = new(Lines[closest.Value.posA..(closest.Value.posB - 1)]);
|
||||
partA.Add(closest.Value.line);
|
||||
List<Line> partA = new(Lines[closest.Value.posA..(closest.Value.posB - 1)])
|
||||
{
|
||||
closest.Value.line
|
||||
};
|
||||
|
||||
Polygon pA = new(partA.ToArray());
|
||||
|
||||
|
||||
@ -94,6 +94,7 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
|
||||
private Vert p_a, p_b, p_c, p_d;
|
||||
private Line p_ab, p_bc, p_cd, p_da;
|
||||
|
||||
[Obsolete("This field doesn't account for the Z-axis. This will be fixed in v2.4.0")]
|
||||
public float Area
|
||||
{
|
||||
get
|
||||
@ -332,6 +333,4 @@ public struct Quadrilateral : ICloneable, IEquatable<Quadrilateral>, IGroup<Vert
|
||||
public static implicit operator Quadrilateral(Fill<Line> fill) => new(fill);
|
||||
public static implicit operator Quadrilateral(Fill<float> fill) => new(fill);
|
||||
public static implicit operator Quadrilateral(Fill<int> fill) => new(fill);
|
||||
public static explicit operator Quadrilateral(Polygon poly) => new(poly.Lines[0], poly.Lines[1],
|
||||
poly.Lines[2], poly.Lines[3]);
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ public struct Sphere : ICloneable, IClosest<Vert>, IComparable<Sphere>, ICompara
|
||||
|
||||
public bool Contains(Vert vert) => (center - vert).Magnitude <= radius;
|
||||
|
||||
public Vert ClosestTo(Vert vert) => Contains(vert) ? vert : ((vert - center).Normalized * radius) + vert;
|
||||
public Vert ClosestTo(Vert vert) => Contains(vert) ? vert : ((vert - center).Normalized * radius) + center;
|
||||
|
||||
public static Sphere operator +(Sphere a, Sphere b) => new(a.center + b.center, a.radius + b.radius);
|
||||
public static Sphere operator +(Sphere a, Vert b) => new(a.center + b, a.radius);
|
||||
|
||||
@ -72,6 +72,7 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
|
||||
private Vert p_a, p_b, p_c;
|
||||
private Line p_ab, p_bc, p_ca;
|
||||
|
||||
[Obsolete("This field doesn't account for the Z-axis. This will be fixed in v2.4.0")]
|
||||
public float Area => (float)Mathf.Absolute((A.position.x * B.position.y) + (B.position.x * C.position.y) +
|
||||
(C.position.x * A.position.y) - ((B.position.x * A.position.y) + (C.position.x * B.position.y) +
|
||||
(A.position.x * C.position.y))) * 0.5f;
|
||||
@ -273,5 +274,4 @@ public struct Triangle : ICloneable, IEquatable<Triangle>, IGroup<Vert>
|
||||
public static implicit operator Triangle(Fill<Line> fill) => new(fill);
|
||||
public static implicit operator Triangle(Fill<float> fill) => new(fill);
|
||||
public static implicit operator Triangle(Fill<int> fill) => new(fill);
|
||||
public static explicit operator Triangle(Polygon poly) => new(poly.Lines[0], poly.Lines[1], poly.Lines[2]);
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ public struct Vert : ICloneable, IEquatable<Vert>, IGroup<float>
|
||||
public static Vert Zero => new(0, 0, 0);
|
||||
|
||||
public float Magnitude => position.Magnitude;
|
||||
public Vert Normalized => new(this / Magnitude);
|
||||
public Vert Normalized => this / Magnitude;
|
||||
|
||||
public Float3 position;
|
||||
|
||||
|
||||
@ -12,16 +12,40 @@
|
||||
<Copyright>Copyright (c) 2022 That_One_Nerd</Copyright>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryUrl>https://github.com/That-One-Nerd/Nerd_STF</RepositoryUrl>
|
||||
<AssemblyVersion>2.3.1.52</AssemblyVersion>
|
||||
<AssemblyVersion>2.3.1</AssemblyVersion>
|
||||
<PackageTags>c#;csharp;c sharp;math;mathematics;mathametics;maths;color;rgb;rgba;cmyk;cmyka;hsv;hsva;calculus;linear algebra;linalg;linearalgebra;matrix;matrix2x2;matrix 2x2;matrix3x3;matrix 3x3;matrix4x4;matrix 4x4;matrix multiplication;vector;vector2d;vector3d;vector2;vector3;float2;float3;float4;int2;int3;int4;angle;geometry;vert;line;polygon;triangle;quadrilateral;sphere;circle;number system;numbersystem;complex numbers;complex;2d numbers;2dnumbers;quaternions;4d numbers;4dnumbers</PackageTags>
|
||||
<Version>2.3.1.52-alpha</Version>
|
||||
<Version>2.3.1</Version>
|
||||
<Product>Nerd_STF</Product>
|
||||
<PackageId>Nerd_STF</PackageId>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageIcon>Logo Square.png</PackageIcon>
|
||||
<PackageReleaseNotes>The `v2.3.1.x` updates go through every single field and method in Nerd_STF to make sure it works correctly.</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>
|
||||
# Nerd_STF v2.3.1
|
||||
|
||||
***Everything has been tested and most things work!***
|
||||
|
||||
**WARNING:**
|
||||
All of the matrix classes have had all of their constructors' row and column variables swapped. You'll have to switch all your variables around.
|
||||
Sorry for the inconvenience :(.
|
||||
|
||||
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).
|
||||
|
||||
Hi everyone! Everything has been checked now and most stuff works! Not everything, like the triangle and quadrilateral area stuff, but for the most part, it's all cool and good.
|
||||
|
||||
I've just now remembered how bad the Polygon struct was. It's getting remade. The v2.4.0 update will be mostly geometry focused, so that'll be the best time to figure out how to fix this stuff. The new Polygon struct will be much better, trust me.
|
||||
|
||||
But all the matrix structs work like charm now! I'm honestly suprised they worked as well as they did before (especially the dynamic matrix). They can now be relied on.
|
||||
|
||||
Next up is the documentation update. Stay tuned!
|
||||
(This may be another update with beta parts, but I'm not sure yet. We'll see).
|
||||
|
||||
*P.S. (NuGet only message): I didn't know I had the room to put the whole changelog here. I'll do that from now on.*
|
||||
</PackageReleaseNotes>
|
||||
<PackageProjectUrl>https://github.com/That-One-Nerd/Nerd_STF</PackageProjectUrl>
|
||||
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||
<SignAssembly>False</SignAssembly>
|
||||
<PackAsTool>False</PackAsTool>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user