Added fill support. Also reworked the matrix constructors to make more sense.

This commit is contained in:
That-One-Nerd 2024-11-26 08:30:40 -05:00
parent e59f253cc8
commit 938c95fa18
17 changed files with 243 additions and 35 deletions

5
Nerd_STF/Fill.cs Normal file
View File

@ -0,0 +1,5 @@
namespace Nerd_STF
{
public delegate T Fill<T>(int index);
public delegate T Fill2d<T>(int x, int y);
}

View File

@ -16,12 +16,12 @@ namespace Nerd_STF.Helpers
int y = 0; int y = 0;
foreach (double v in part) foreach (double v in part)
{ {
matrix[byRows ? (x, y) : (y, x)] = v; matrix[byRows ? (y, x) : (x, y)] = v;
y++; y++;
if (byRows ? y >= size.x : y >= size.y) break; if (byRows ? y >= size.y : y >= size.x) break;
} }
x++; x++;
if (byRows ? x >= size.y : x >= size.x) break; if (byRows ? x >= size.x : x >= size.y) break;
} }
} }
public static void SetMatrixValues<TMat>(TMat matrix, IEnumerable<ListTuple<double>> vals, bool byRows) public static void SetMatrixValues<TMat>(TMat matrix, IEnumerable<ListTuple<double>> vals, bool byRows)
@ -35,17 +35,17 @@ namespace Nerd_STF.Helpers
int y = 0; int y = 0;
foreach (double v in part) foreach (double v in part)
{ {
matrix[byRows ? (x, y) : (y, x)] = v; matrix[byRows ? (y, x) : (x, y)] = v;
y++; y++;
if (byRows ? y >= size.x : y >= size.y) break; if (byRows ? y >= size.y : y >= size.x) break;
} }
x++; x++;
if (byRows ? x >= size.y : x >= size.x) break; if (byRows ? x >= size.x : x >= size.y) break;
} }
} }
public static void SetRow<TMat>(TMat matrix, int row, IEnumerable<double> vals) public static void SetRow<TMat>(TMat matrix, int row, IEnumerable<double> vals)
where TMat: IMatrix<TMat> where TMat : IMatrix<TMat>
{ {
int col = 0; int col = 0;
int max = matrix.Size.y; int max = matrix.Size.y;

View File

@ -25,6 +25,11 @@ namespace Nerd_STF
{ {
this.items = items; this.items = items;
} }
public ListTuple(Fill<T> items, int length)
{
this.items = new T[length];
for (int i = 0; i < length; i++) this.items[i] = items(i);
}
public T this[int index] public T this[int index]
{ {

View File

@ -11,6 +11,7 @@ namespace Nerd_STF.Mathematics.Algebra
static abstract TSelf operator *(TSelf a, double b); static abstract TSelf operator *(TSelf a, double b);
static abstract TSelf operator /(TSelf a, double b); static abstract TSelf operator /(TSelf a, double b);
static abstract TSelf operator ^(TSelf a, TSelf b);
static abstract TSelf? operator ~(TSelf m); static abstract TSelf? operator ~(TSelf m);
} }
} }

View File

@ -46,29 +46,57 @@ namespace Nerd_STF.Mathematics.Algebra
this.r1c1 = r1c1; this.r1c1 = r1c1;
} }
/// <param name="byRows"><see langword="true"/> if the array is of the form [c, r], <see langword="false"/> if the array is of the form [r, c].</param> /// <param name="byRows"><see langword="true"/> if the array is of the form [c, r], <see langword="false"/> if the array is of the form [r, c].</param>
public Matrix2x2(double[,] vals, bool byRows = true) public Matrix2x2(double[,] vals, bool byRows = false)
{ {
if (byRows) // Collection of rows ([c, r]) if (byRows) // Collection of rows ([c, r])
{
r0c0 = vals[0, 0]; r0c1 = vals[0, 1];
r1c0 = vals[1, 0]; r1c1 = vals[1, 1];
}
else // Collection of columns ([r, c])
{ {
r0c0 = vals[0, 0]; r0c1 = vals[1, 0]; r0c0 = vals[0, 0]; r0c1 = vals[1, 0];
r1c0 = vals[0, 1]; r1c1 = vals[1, 1]; r1c0 = vals[0, 1]; r1c1 = vals[1, 1];
} }
else // Collection of columns ([r, c])
{
r0c0 = vals[0, 0]; r0c1 = vals[0, 1];
r1c0 = vals[1, 0]; r1c1 = vals[1, 1];
}
} }
/// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param> /// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param>
public Matrix2x2(IEnumerable<IEnumerable<double>> vals, bool byRows = true) public Matrix2x2(IEnumerable<IEnumerable<double>> vals, bool byRows = false)
{ {
MatrixHelper.SetMatrixValues(this, vals, byRows); MatrixHelper.SetMatrixValues(this, vals, byRows);
} }
/// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param> /// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param>
public Matrix2x2(IEnumerable<ListTuple<double>> vals, bool byRows = true) public Matrix2x2(IEnumerable<ListTuple<double>> vals, bool byRows = false)
{ {
MatrixHelper.SetMatrixValues(this, vals, byRows); MatrixHelper.SetMatrixValues(this, vals, byRows);
} }
/// <param name="byRows"><see langword="true"/> if the fill goes through columns for each row, <see langword="false"/> if the fill goes through rows for each column.</param>
public Matrix2x2(Fill<double> fill, bool byRows = false)
{
if (byRows)
{
r0c0 = fill(0); r0c1 = fill(2);
r1c0 = fill(1); r1c1 = fill(3);
}
else
{
r0c0 = fill(0); r0c1 = fill(1);
r1c0 = fill(2); r1c1 = fill(3);
}
}
/// <param name="byRows"><see langword="true"/> if the fill is a collection of rows (form [c, r]), <see langword="false"/> if the fill is a collection of columns (form [r, c]).</param>
public Matrix2x2(Fill2d<double> fill, bool byRows = false)
{
if (byRows)
{
r0c0 = fill(0, 0); r0c1 = fill(1, 0);
r1c0 = fill(0, 1); r1c1 = fill(1, 1);
}
else
{
r0c0 = fill(0, 0); r0c1 = fill(0, 1);
r1c0 = fill(1, 0); r1c1 = fill(1, 1);
}
}
public double this[int r, int c] public double this[int r, int c]
{ {
@ -314,6 +342,9 @@ namespace Nerd_STF.Mathematics.Algebra
public static Matrix2x2 operator /(Matrix2x2 a, double b) => public static Matrix2x2 operator /(Matrix2x2 a, double b) =>
new Matrix2x2(a.r0c0 / b, a.r0c1 / b, new Matrix2x2(a.r0c0 / b, a.r0c1 / b,
a.r1c0 / b, a.r1c1 / b); a.r1c0 / b, a.r1c1 / b);
public static Matrix2x2 operator ^(Matrix2x2 a, Matrix2x2 b) =>
new Matrix2x2(a.r0c0 * b.r0c0, a.r0c1 * b.r0c1,
a.r1c0 * b.r1c0, a.r1c1 * b.r1c1);
public static Matrix2x2 operator ~(Matrix2x2 a) => a.Inverse(); public static Matrix2x2 operator ~(Matrix2x2 a) => a.Inverse();
public static bool operator ==(Matrix2x2 a, Matrix2x2 b) => a.Equals(b); public static bool operator ==(Matrix2x2 a, Matrix2x2 b) => a.Equals(b);
public static bool operator !=(Matrix2x2 a, Matrix2x2 b) => !a.Equals(b); public static bool operator !=(Matrix2x2 a, Matrix2x2 b) => !a.Equals(b);

View File

@ -51,31 +51,63 @@ namespace Nerd_STF.Mathematics.Algebra
this.r2c0 = r2c0; this.r2c1 = r2c1; this.r2c2 = r2c2; this.r2c0 = r2c0; this.r2c1 = r2c1; this.r2c2 = r2c2;
} }
/// <param name="byRows"><see langword="true"/> if the array is of the form [c, r], <see langword="false"/> if the array is of the form [r, c].</param> /// <param name="byRows"><see langword="true"/> if the array is of the form [c, r], <see langword="false"/> if the array is of the form [r, c].</param>
public Matrix3x3(double[,] vals, bool byRows = true) public Matrix3x3(double[,] vals, bool byRows = false)
{ {
if (byRows) // Collection of rows ([c, r]) if (byRows) // Collection of rows ([c, r])
{
r0c0 = vals[0, 0]; r0c1 = vals[0, 1]; r0c2 = vals[0, 2];
r1c0 = vals[1, 0]; r1c1 = vals[1, 1]; r1c2 = vals[1, 2];
r2c0 = vals[2, 0]; r2c1 = vals[2, 1]; r2c2 = vals[2, 2];
}
else // Collection of columns ([r, c])
{ {
r0c0 = vals[0, 0]; r0c1 = vals[1, 0]; r0c2 = vals[2, 0]; r0c0 = vals[0, 0]; r0c1 = vals[1, 0]; r0c2 = vals[2, 0];
r1c0 = vals[0, 1]; r1c1 = vals[1, 1]; r1c2 = vals[2, 1]; r1c0 = vals[0, 1]; r1c1 = vals[1, 1]; r1c2 = vals[2, 1];
r2c0 = vals[0, 2]; r2c1 = vals[1, 2]; r2c2 = vals[2, 2]; r2c0 = vals[0, 2]; r2c1 = vals[1, 2]; r2c2 = vals[2, 2];
} }
else // Collection of columns ([r, c])
{
r0c0 = vals[0, 0]; r0c1 = vals[0, 1]; r0c2 = vals[0, 2];
r1c0 = vals[1, 0]; r1c1 = vals[1, 1]; r1c2 = vals[1, 2];
r2c0 = vals[2, 0]; r2c1 = vals[2, 1]; r2c2 = vals[2, 2];
}
} }
/// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param> /// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param>
public Matrix3x3(IEnumerable<IEnumerable<double>> vals, bool byRows = true) public Matrix3x3(IEnumerable<IEnumerable<double>> vals, bool byRows = false)
{ {
MatrixHelper.SetMatrixValues(this, vals, byRows); MatrixHelper.SetMatrixValues(this, vals, byRows);
} }
/// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param> /// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param>
public Matrix3x3(IEnumerable<ListTuple<double>> vals, bool byRows = true) public Matrix3x3(IEnumerable<ListTuple<double>> vals, bool byRows = false)
{ {
MatrixHelper.SetMatrixValues(this, vals, byRows); MatrixHelper.SetMatrixValues(this, vals, byRows);
} }
/// <param name="byRows"><see langword="true"/> if the fill goes through columns for each row, <see langword="false"/> if the fill goes through rows for each column.</param>
public Matrix3x3(Fill<double> fill, bool byRows = false)
{
if (byRows)
{
r0c0 = fill(0); r0c1 = fill(3); r0c2 = fill(6);
r1c0 = fill(1); r1c1 = fill(4); r1c2 = fill(7);
r2c0 = fill(2); r2c1 = fill(5); r2c2 = fill(8);
}
else
{
r0c0 = fill(0); r0c1 = fill(1); r0c2 = fill(2);
r1c0 = fill(3); r1c1 = fill(4); r1c2 = fill(5);
r2c0 = fill(6); r2c1 = fill(7); r2c2 = fill(8);
}
}
/// <param name="byRows"><see langword="true"/> if the fill is a collection of rows (form [c, r]), <see langword="false"/> if the fill is a collection of columns (form [r, c]).</param>
public Matrix3x3(Fill2d<double> fill, bool byRows = false)
{
if (byRows)
{
r0c0 = fill(0, 0); r0c1 = fill(1, 0); r0c2 = fill(2, 0);
r1c0 = fill(0, 1); r1c1 = fill(1, 1); r1c2 = fill(2, 1);
r2c0 = fill(0, 2); r2c1 = fill(1, 2); r2c2 = fill(2, 2);
}
else
{
r0c0 = fill(0, 0); r0c1 = fill(0, 1); r0c2 = fill(0, 2);
r1c0 = fill(1, 0); r1c1 = fill(1, 1); r1c2 = fill(1, 2);
r2c0 = fill(2, 0); r2c1 = fill(2, 1); r2c2 = fill(2, 2);
}
}
public double this[int r, int c] public double this[int r, int c]
{ {
@ -402,6 +434,10 @@ namespace Nerd_STF.Mathematics.Algebra
new Matrix3x3(a.r0c0 / b, a.r0c1 / b, a.r0c2 / b, new Matrix3x3(a.r0c0 / b, a.r0c1 / b, a.r0c2 / b,
a.r1c0 / b, a.r1c1 / b, a.r1c2 / b, a.r1c0 / b, a.r1c1 / b, a.r1c2 / b,
a.r2c0 / b, a.r2c1 / b, a.r2c2 / b); a.r2c0 / b, a.r2c1 / b, a.r2c2 / b);
public static Matrix3x3 operator ^(Matrix3x3 a, Matrix3x3 b) =>
new Matrix3x3(a.r0c0 * b.r0c0, a.r0c1 * b.r0c1, a.r0c2 * b.r0c2,
a.r1c0 * b.r1c0, a.r1c1 * b.r1c1, a.r1c2 * b.r1c2,
a.r2c0 * b.r2c0, a.r2c1 * b.r2c1, a.r2c2 * b.r2c2);
public static Matrix3x3 operator ~(Matrix3x3 a) => a.Inverse(); public static Matrix3x3 operator ~(Matrix3x3 a) => a.Inverse();
public static bool operator ==(Matrix3x3 a, Matrix3x3 b) => a.Equals(b); public static bool operator ==(Matrix3x3 a, Matrix3x3 b) => a.Equals(b);
public static bool operator !=(Matrix3x3 a, Matrix3x3 b) => !a.Equals(b); public static bool operator !=(Matrix3x3 a, Matrix3x3 b) => !a.Equals(b);

View File

@ -57,33 +57,69 @@ namespace Nerd_STF.Mathematics.Algebra
this.r3c0 = r3c0; this.r3c1 = r3c1; this.r3c2 = r3c2; this.r3c3 = r3c3; this.r3c0 = r3c0; this.r3c1 = r3c1; this.r3c2 = r3c2; this.r3c3 = r3c3;
} }
/// <param name="byRows"><see langword="true"/> if the array is of the form [c, r], <see langword="false"/> if the array is of the form [r, c].</param> /// <param name="byRows"><see langword="true"/> if the array is of the form [c, r], <see langword="false"/> if the array is of the form [r, c].</param>
public Matrix4x4(double[,] vals, bool byRows = true) public Matrix4x4(double[,] vals, bool byRows = false)
{ {
if (byRows) // Collection of rows ([c, r]) if (byRows) // Collection of rows ([c, r])
{
r0c0 = vals[0, 0]; r0c1 = vals[0, 1]; r0c2 = vals[0, 2]; r0c3 = vals[0, 3];
r1c0 = vals[1, 0]; r1c1 = vals[1, 1]; r1c2 = vals[1, 2]; r1c3 = vals[1, 3];
r2c0 = vals[2, 0]; r2c1 = vals[2, 1]; r2c2 = vals[2, 2]; r2c3 = vals[2, 3];
r3c0 = vals[3, 0]; r3c1 = vals[3, 1]; r3c2 = vals[3, 2]; r3c3 = vals[3, 3];
}
else
{ {
r0c0 = vals[0, 0]; r0c1 = vals[1, 0]; r0c2 = vals[2, 0]; r0c3 = vals[3, 0]; r0c0 = vals[0, 0]; r0c1 = vals[1, 0]; r0c2 = vals[2, 0]; r0c3 = vals[3, 0];
r1c0 = vals[0, 1]; r1c1 = vals[1, 1]; r1c2 = vals[2, 1]; r1c3 = vals[3, 1]; r1c0 = vals[0, 1]; r1c1 = vals[1, 1]; r1c2 = vals[2, 1]; r1c3 = vals[3, 1];
r2c0 = vals[0, 2]; r2c1 = vals[1, 2]; r2c2 = vals[2, 2]; r2c3 = vals[3, 2]; r2c0 = vals[0, 2]; r2c1 = vals[1, 2]; r2c2 = vals[2, 2]; r2c3 = vals[3, 2];
r3c0 = vals[0, 3]; r3c1 = vals[1, 3]; r3c2 = vals[2, 3]; r3c3 = vals[3, 3]; r3c0 = vals[0, 3]; r3c1 = vals[1, 3]; r3c2 = vals[2, 3]; r3c3 = vals[3, 3];
} }
else
{
r0c0 = vals[0, 0]; r0c1 = vals[0, 1]; r0c2 = vals[0, 2]; r0c3 = vals[0, 3];
r1c0 = vals[1, 0]; r1c1 = vals[1, 1]; r1c2 = vals[1, 2]; r1c3 = vals[1, 3];
r2c0 = vals[2, 0]; r2c1 = vals[2, 1]; r2c2 = vals[2, 2]; r2c3 = vals[2, 3];
r3c0 = vals[3, 0]; r3c1 = vals[3, 1]; r3c2 = vals[3, 2]; r3c3 = vals[3, 3];
}
} }
/// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param> /// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param>
public Matrix4x4(IEnumerable<IEnumerable<double>> vals, bool byRows = true) public Matrix4x4(IEnumerable<IEnumerable<double>> vals, bool byRows = false)
{ {
MatrixHelper.SetMatrixValues(this, vals, byRows); MatrixHelper.SetMatrixValues(this, vals, byRows);
} }
/// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param> /// <param name="byRows"><see langword="true"/> if the enumerable is a collection of rows (form [c, r]), <see langword="false"/> if the enumerable is a collection of columns (form [r, c]).</param>
public Matrix4x4(IEnumerable<ListTuple<double>> vals, bool byRows = true) public Matrix4x4(IEnumerable<ListTuple<double>> vals, bool byRows = false)
{ {
MatrixHelper.SetMatrixValues(this, vals, byRows); MatrixHelper.SetMatrixValues(this, vals, byRows);
} }
/// <param name="byRows"><see langword="true"/> if the fill goes through columns for each row, <see langword="false"/> if the fill goes through rows for each column.</param>
public Matrix4x4(Fill<double> fill, bool byRows = false)
{
if (byRows)
{
r0c0 = fill(0); r0c1 = fill(4); r0c2 = fill( 8); r0c3 = fill(12);
r1c0 = fill(1); r1c1 = fill(5); r1c2 = fill( 9); r1c3 = fill(13);
r2c0 = fill(2); r2c1 = fill(6); r2c2 = fill(10); r2c3 = fill(14);
r3c0 = fill(3); r3c1 = fill(7); r3c2 = fill(11); r3c3 = fill(15);
}
else
{
r0c0 = fill( 0); r0c1 = fill( 1); r0c2 = fill( 2); r0c3 = fill( 3);
r1c0 = fill( 4); r1c1 = fill( 5); r1c2 = fill( 6); r1c3 = fill( 7);
r2c0 = fill( 8); r2c1 = fill( 9); r2c2 = fill(10); r2c3 = fill(11);
r3c0 = fill(12); r3c1 = fill(13); r3c2 = fill(14); r3c3 = fill(15);
}
}
/// <param name="byRows"><see langword="true"/> if the fill is a collection of rows (form [c, r]), <see langword="false"/> if the fill is a collection of columns (form [r, c]).</param>
public Matrix4x4(Fill2d<double> fill, bool byRows = false)
{
if (byRows)
{
r0c0 = fill(0, 0); r0c1 = fill(1, 0); r0c2 = fill(2, 0); r0c3 = fill(3, 0);
r1c0 = fill(0, 1); r1c1 = fill(1, 1); r1c2 = fill(2, 1); r1c3 = fill(3, 1);
r2c0 = fill(0, 2); r2c1 = fill(1, 2); r2c2 = fill(2, 2); r2c3 = fill(3, 2);
r3c0 = fill(0, 3); r3c1 = fill(1, 3); r3c2 = fill(2, 3); r3c3 = fill(3, 3);
}
else
{
r0c0 = fill(0, 0); r0c1 = fill(0, 1); r0c2 = fill(0, 2); r0c3 = fill(0, 3);
r1c0 = fill(1, 0); r1c1 = fill(1, 1); r1c2 = fill(1, 2); r1c3 = fill(1, 3);
r2c0 = fill(2, 0); r2c1 = fill(2, 1); r2c2 = fill(2, 2); r2c3 = fill(2, 3);
r3c0 = fill(3, 0); r3c1 = fill(3, 1); r3c2 = fill(3, 2); r3c3 = fill(3, 3);
}
}
public double this[int r, int c] public double this[int r, int c]
{ {
@ -544,6 +580,11 @@ namespace Nerd_STF.Mathematics.Algebra
a.r1c0 / b, a.r1c1 / b, a.r1c2 / b, a.r1c3 / b, a.r1c0 / b, a.r1c1 / b, a.r1c2 / b, a.r1c3 / b,
a.r2c0 / b, a.r2c1 / b, a.r2c2 / b, a.r2c3 / b, a.r2c0 / b, a.r2c1 / b, a.r2c2 / b, a.r2c3 / b,
a.r3c0 / b, a.r3c1 / b, a.r3c2 / b, a.r3c3 / b); a.r3c0 / b, a.r3c1 / b, a.r3c2 / b, a.r3c3 / b);
public static Matrix4x4 operator ^(Matrix4x4 a, Matrix4x4 b) =>
new Matrix4x4(a.r0c0 * b.r0c0, a.r0c1 * b.r0c1, a.r0c2 * b.r0c2, a.r0c3 * b.r0c3,
a.r1c0 * b.r1c0, a.r1c1 * b.r1c1, a.r1c2 * b.r1c2, a.r1c3 * b.r1c3,
a.r2c0 * b.r2c0, a.r2c1 * b.r2c1, a.r2c2 * b.r2c2, a.r2c3 * b.r2c3,
a.r3c0 * b.r3c0, a.r3c1 * b.r3c1, a.r3c2 * b.r3c2, a.r3c3 * b.r3c3);
public static Matrix4x4 operator ~(Matrix4x4 a) => a.Inverse(); public static Matrix4x4 operator ~(Matrix4x4 a) => a.Inverse();
public static bool operator ==(Matrix4x4 a, Matrix4x4 b) => a.Equals(b); public static bool operator ==(Matrix4x4 a, Matrix4x4 b) => a.Equals(b);
public static bool operator !=(Matrix4x4 a, Matrix4x4 b) => !a.Equals(b); public static bool operator !=(Matrix4x4 a, Matrix4x4 b) => !a.Equals(b);

View File

@ -21,6 +21,11 @@ namespace Nerd_STF.Mathematics.Equations
M = m; M = m;
B = b; B = b;
} }
public Linear(Fill<double> fill)
{
B = fill(0);
M = fill(1);
}
public double this[double x] => M * x + B; public double this[double x] => M * x + B;
public double Get(double x) => M * x + B; public double Get(double x) => M * x + B;

View File

@ -30,6 +30,16 @@ namespace Nerd_STF.Mathematics.Equations
if (reverse) this.terms = TrimExcessTerms(terms.Reverse().ToArray()); if (reverse) this.terms = TrimExcessTerms(terms.Reverse().ToArray());
else this.terms = TrimExcessTerms(terms.ToArray()); else this.terms = TrimExcessTerms(terms.ToArray());
} }
public Polynomial(bool reverse, Fill<double> terms, int length)
{
this.terms = new double[length];
for (int i = 0; i < length; i++)
{
if (reverse) this.terms[i] = terms(length - 1 - i);
else this.terms[i] = terms(i);
}
this.terms = TrimExcessTerms(this.terms);
}
private static double[] TrimExcessTerms(double[] terms) private static double[] TrimExcessTerms(double[] terms)
{ {
int newLength = terms.Length; int newLength = terms.Length;

View File

@ -42,6 +42,12 @@ namespace Nerd_STF.Mathematics.Equations
B = 0; B = 0;
C = c; C = c;
} }
public Quadratic(Fill<double> fill)
{
C = fill(0);
B = fill(1);
A = fill(2);
}
public double this[double x] => A * x * x + B * x + C; public double this[double x] => A * x * x + B * x + C;
public double Get(double x) => A * x * x + B * x + C; public double Get(double x) => A * x * x + B * x + C;

View File

@ -48,6 +48,11 @@ namespace Nerd_STF.Mathematics
if (index >= 2) break; if (index >= 2) break;
} }
} }
public Float2(Fill<double> fill)
{
x = fill(0);
y = fill(1);
}
public double this[int index] public double this[int index]
{ {

View File

@ -51,6 +51,12 @@ namespace Nerd_STF.Mathematics
if (index >= 2) break; if (index >= 2) break;
} }
} }
public Float3(Fill<double> fill)
{
x = fill(0);
y = fill(1);
z = fill(2);
}
public double this[int index] public double this[int index]
{ {

View File

@ -55,6 +55,13 @@ namespace Nerd_STF.Mathematics
if (index >= 2) break; if (index >= 2) break;
} }
} }
public Float4(Fill<double> fill)
{
w = fill(0);
x = fill(1);
y = fill(2);
z = fill(3);
}
public double this[int index] public double this[int index]
{ {

View File

@ -47,6 +47,11 @@ namespace Nerd_STF.Mathematics
if (index >= 2) break; if (index >= 2) break;
} }
} }
public Int2(Fill<int> fill)
{
x = fill(0);
y = fill(1);
}
public int this[int index] public int this[int index]
{ {

View File

@ -50,6 +50,12 @@ namespace Nerd_STF.Mathematics
if (index >= 2) break; if (index >= 2) break;
} }
} }
public Int3(Fill<int> fill)
{
x = fill(0);
y = fill(1);
z = fill(2);
}
public int this[int index] public int this[int index]
{ {

View File

@ -54,6 +54,13 @@ namespace Nerd_STF.Mathematics
if (index >= 2) break; if (index >= 2) break;
} }
} }
public Int4(Fill<int> fill)
{
w = fill(0);
x = fill(1);
y = fill(2);
z = fill(3);
}
public int this[int index] public int this[int index]
{ {

View File

@ -374,6 +374,24 @@ namespace Nerd_STF.Mathematics
} }
public static IEquation Lerp(IEquation a, IEquation b, double t, bool clamp = true) => public static IEquation Lerp(IEquation a, IEquation b, double t, bool clamp = true) =>
new Equation((double x) => Lerp(a.Get(x), b.Get(x), t, clamp)); new Equation((double x) => Lerp(a.Get(x), b.Get(x), t, clamp));
public static Fill<double> Lerp(Fill<double> a, Fill<double> b, double t, bool clamp = true)
{
if (clamp) Clamp(ref t, 0, 1);
return delegate (int index)
{
double aVal = a(index);
return aVal + t * (b(index) - aVal);
};
}
public static Fill<int> Lerp(Fill<int> a, Fill<int> b, double t, bool clamp = true)
{
if (clamp) Clamp(ref t, 0, 1);
return delegate (int index)
{
int aVal = a(index);
return (int)(aVal + t * (b(index) - aVal));
};
}
#if CS11_OR_GREATER #if CS11_OR_GREATER
public static T Lerp<T>(T a, T b, T t, bool clamp = true) public static T Lerp<T>(T a, T b, T t, bool clamp = true)
where T : INumber<T> where T : INumber<T>
@ -381,6 +399,20 @@ namespace Nerd_STF.Mathematics
if (clamp) Clamp(ref t, T.Zero, T.One); if (clamp) Clamp(ref t, T.Zero, T.One);
return a + t * (b - a); return a + t * (b - a);
} }
public static T Lerp<T>(T a, T b, double t, bool clamp = true)
where T : IInterpolable<T> => T.Lerp(a, b, t, clamp);
public static Fill<T> Lerp<T>(Fill<T> a, Fill<T> b, T t, bool clamp = true)
where T : INumber<T>
{
if (clamp) Clamp(ref t, T.Zero, T.One);
return delegate (int index)
{
T aVal = a(index);
return aVal + t * (b(index) - aVal);
};
}
public static Fill<T> Lerp<T>(Fill<T> a, Fill<T> b, double t, bool clamp = true)
where T : IInterpolable<T> => (int index) => T.Lerp(a(index), b(index), t, clamp);
#endif #endif
public static int Max(int a, int b) => a > b ? a : b; public static int Max(int a, int b) => a > b ? a : b;