Partial commit: Some projection matrix stuff.
This commit is contained in:
parent
d58ad7c94f
commit
8b4e61ce82
8
Nerd_STF/CrossSection2d.cs
Normal file
8
Nerd_STF/CrossSection2d.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Nerd_STF;
|
||||
|
||||
public enum CrossSection2d
|
||||
{
|
||||
XY,
|
||||
YZ,
|
||||
ZX
|
||||
}
|
||||
16
Nerd_STF/Exceptions/InvalidProjectionMatrixException.cs
Normal file
16
Nerd_STF/Exceptions/InvalidProjectionMatrixException.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Nerd_STF.Exceptions;
|
||||
|
||||
[Serializable]
|
||||
public class InvalidProjectionMatrixException : Nerd_STFException
|
||||
{
|
||||
public Matrix? Matrix;
|
||||
|
||||
public InvalidProjectionMatrixException() : base("This is not a projection matrix.") { }
|
||||
public InvalidProjectionMatrixException(string message) : base(message) { }
|
||||
public InvalidProjectionMatrixException(string message, Exception inner) : base(message, inner) { }
|
||||
public InvalidProjectionMatrixException(Matrix? matrix) : this() => Matrix = matrix;
|
||||
public InvalidProjectionMatrixException(Matrix? matrix, string message) : this(message) => Matrix = matrix;
|
||||
public InvalidProjectionMatrixException(Matrix? matrix, string message, Exception inner) : this(message, inner) =>
|
||||
Matrix = matrix;
|
||||
protected InvalidProjectionMatrixException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
@ -157,6 +157,11 @@ public class Matrix : IMatrix<Matrix, Matrix>
|
||||
}
|
||||
}
|
||||
|
||||
public static Matrix Get2dRotationMatrix(Angle rot) =>
|
||||
Matrix2x2.GenerateRotationMatrix(rot);
|
||||
public static Matrix Get3dRotationMatrix(Angle yaw, Angle pitch, Angle roll) =>
|
||||
Matrix3x3.GenerateRotationMatrix(yaw, pitch, roll);
|
||||
|
||||
public static Matrix Absolute(Matrix val) => new(val.Size, (r, c) => Mathf.Absolute(val[r, c]));
|
||||
public static Matrix Ceiling(Matrix val) => new(val.Size, (r, c) => Mathf.Ceiling(val[r, c]));
|
||||
public static Matrix Clamp(Matrix val, Matrix min, Matrix max) =>
|
||||
|
||||
@ -161,6 +161,12 @@ public record class Matrix2x2 : IStaticMatrix<Matrix2x2>
|
||||
}
|
||||
}
|
||||
|
||||
public static Matrix2x2 GenerateRotationMatrix(Angle rot) => new(new[,]
|
||||
{
|
||||
{ Mathf.Cos(rot), -Mathf.Sin(rot) },
|
||||
{ Mathf.Sin(rot), Mathf.Cos(rot) }
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
@ -225,6 +225,34 @@ public record class Matrix3x3 : IStaticMatrix<Matrix3x3>
|
||||
}
|
||||
}
|
||||
|
||||
public static Matrix3x3 GenerateRotationMatrix(Angle yaw, Angle pitch, Angle roll)
|
||||
{
|
||||
// Could be optimized by merging all of the matrices by hand
|
||||
// but that's a huge matrix and, as said before like a gajillion
|
||||
// times, this ain't the optimization update.
|
||||
|
||||
Matrix3x3 yawMatrix = new(new[,]
|
||||
{
|
||||
{ Mathf.Cos(yaw), -Mathf.Sin(yaw), 0 },
|
||||
{ Mathf.Sin(yaw), Mathf.Cos(yaw), 0 },
|
||||
{ 0, 0, 1 }
|
||||
});
|
||||
Matrix3x3 pitchMatrix = new(new[,]
|
||||
{
|
||||
{ Mathf.Cos(pitch), 0, Mathf.Sin(pitch) },
|
||||
{ 0, 1, 0 },
|
||||
{ -Mathf.Sin(pitch), 0, Mathf.Cos(pitch) }
|
||||
});
|
||||
Matrix3x3 rollMatrix = new(new[,]
|
||||
{
|
||||
{ 1, 0, 0 },
|
||||
{ 0, Mathf.Cos(roll), -Mathf.Sin(roll) },
|
||||
{ 0, Mathf.Sin(roll), Mathf.Cos(roll) }
|
||||
});
|
||||
|
||||
return yawMatrix * pitchMatrix * rollMatrix;
|
||||
}
|
||||
|
||||
public static Matrix3x3 Absolute(Matrix3x3 val) =>
|
||||
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),
|
||||
|
||||
74
Nerd_STF/Mathematics/Algebra/ProjectionMatrix.cs
Normal file
74
Nerd_STF/Mathematics/Algebra/ProjectionMatrix.cs
Normal file
@ -0,0 +1,74 @@
|
||||
namespace Nerd_STF.Mathematics.Algebra;
|
||||
|
||||
public record class ProjectionMatrix : Matrix3x3
|
||||
{
|
||||
// TODO: i need to remove the record check from everything, add new equals comparitors
|
||||
// and re-implement IsValidProjectionMatrix
|
||||
|
||||
public ProjectionMatrix(float all) : this(all, all, all, all, all, all, all, all, all) { }
|
||||
public ProjectionMatrix(float r1c1, float r1c2, float r1c3, float r2c1,
|
||||
float r2c2, float r2c3, float r3c1, float r3c2, float r3c3) :
|
||||
base(r1c1, r1c2, r1c3, r2c1, r2c2, r2c3, r3c1, r3c2, r3c3)
|
||||
{
|
||||
//if (!IsValidProjectionMatrix) throw new InvalidProjectionMatrixException(this);
|
||||
}
|
||||
public ProjectionMatrix(float[] nums) : this(nums[0], nums[1], nums[2],
|
||||
nums[3], nums[4], nums[5], nums[6], nums[7], nums[8]) { }
|
||||
public ProjectionMatrix(int[] nums) : this(nums[0], nums[1], nums[2],
|
||||
nums[3], nums[4], nums[5], nums[6], nums[7], nums[8]) { }
|
||||
public ProjectionMatrix(Fill<float> fill) : this(fill(0), fill(1), fill(2),
|
||||
fill(3), fill(4), fill(5), fill(6), fill(7), fill(8)) { }
|
||||
public ProjectionMatrix(Fill<int> fill) : this(fill(0), fill(1), fill(2),
|
||||
fill(3), fill(4), fill(5), fill(6), fill(7), fill(8)) { }
|
||||
public ProjectionMatrix(float[,] nums) : this(nums[0, 0], nums[0, 1], nums[0, 2],
|
||||
nums[1, 0], nums[1, 1], nums[1, 2], nums[2, 0], nums[2, 1], nums[2, 2]) { }
|
||||
public ProjectionMatrix(int[,] nums) : this(nums[0, 0], nums[0, 1], nums[0, 2],
|
||||
nums[1, 0], nums[1, 1], nums[1, 2], nums[2, 0], nums[2, 1], nums[2, 2]) { }
|
||||
public ProjectionMatrix(Fill2d<float> 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 ProjectionMatrix(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 ProjectionMatrix(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 ProjectionMatrix(Fill<Float3> fill) : this(fill(0), fill(1), fill(2)) { }
|
||||
public ProjectionMatrix(Fill<Int3> fill) : this((IEnumerable<int>)fill(0), fill(1), fill(2)) { }
|
||||
public ProjectionMatrix(IEnumerable<float> r1, IEnumerable<float> r2, IEnumerable<float> r3)
|
||||
: this(r1.ToFill(), r2.ToFill(), r3.ToFill()) { }
|
||||
public ProjectionMatrix(IEnumerable<int> r1, IEnumerable<int> r2, IEnumerable<int> r3)
|
||||
: this(r1.ToFill(), r2.ToFill(), r3.ToFill()) { }
|
||||
public ProjectionMatrix(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 ProjectionMatrix(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 static ProjectionMatrix SingleViewProjection(CrossSection2d section) => new(new[,]
|
||||
{
|
||||
{ section == CrossSection2d.XY || section == CrossSection2d.ZX ? 1 : 0, 0, 0 },
|
||||
{ 0, section == CrossSection2d.XY || section == CrossSection2d.YZ ? 1 : 0, 0 },
|
||||
{ 0, 0, section == CrossSection2d.YZ || section == CrossSection2d.ZX ? 1 : 0 }
|
||||
});
|
||||
public static ProjectionMatrix IsometricProjection(Angle alpha, Angle beta)
|
||||
{
|
||||
Matrix3x3 alphaMat = new(new[,]
|
||||
{
|
||||
{ 1, 0, 0 },
|
||||
{ 0, Mathf.Cos(alpha), Mathf.Sin(alpha) },
|
||||
{ 0, -Mathf.Sin(alpha), Mathf.Cos(alpha) }
|
||||
});
|
||||
Matrix3x3 betaMat = new(new[,]
|
||||
{
|
||||
{ Mathf.Cos(beta), 0, -Mathf.Sin(beta) },
|
||||
{ 0, 1, 0 },
|
||||
{ Mathf.Sin(beta), 0, Mathf.Cos(beta) }
|
||||
});
|
||||
Matrix3x3 flatten = new(new[,]
|
||||
{
|
||||
{ 1, 0, 0 },
|
||||
{ 0, 1, 0 },
|
||||
{ 0, 0, 0 }
|
||||
});
|
||||
Matrix3x3 result = alphaMat * betaMat * flatten;
|
||||
return new(result.ToFill2D());
|
||||
}
|
||||
|
||||
public Fill<Float3> Project(Fill<Float3> toProject) => i => this * toProject(i);
|
||||
}
|
||||
@ -50,7 +50,7 @@ public record struct Vector2d : IAbsolute<Vector2d>, IAverage<Vector2d>,
|
||||
return new(val.theta, mag);
|
||||
}
|
||||
public static Vector3d Cross(Vector2d a, Vector2d b, bool normalized = false) =>
|
||||
Float2.Cross(a.ToXYZ(), b.ToXYZ(), normalized).ToVector();
|
||||
new Float3(0, 0, Float2.Cross(a.ToXYZ(), b.ToXYZ(), normalized)).ToVector();
|
||||
public static float Dot(Vector2d a, Vector2d b) => Float2.Dot(a.ToXYZ(), b.ToXYZ());
|
||||
public static float Dot(params Vector2d[] vals)
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
public record struct Float2 : IAbsolute<Float2>, IAverage<Float2>, ICeiling<Float2, Int2>,
|
||||
IClamp<Float2>, IClampMagnitude<Float2, float>, IComparable<Float2>,
|
||||
ICross<Float2, Float3>, IDivide<Float2>, IDot<Float2, float>, IEquatable<Float2>,
|
||||
ICross<Float2, float>, IDivide<Float2>, IDot<Float2, float>, IEquatable<Float2>,
|
||||
IFloor<Float2, Int2>, IFromTuple<Float2, (float x, float y)>, IGroup<float>,
|
||||
ILerp<Float2, float>, IMathOperators<Float2>, IMax<Float2>, IMedian<Float2>, IMin<Float2>,
|
||||
IIndexAll<float>, IIndexRangeAll<float>, IPresets2d<Float2>, IProduct<Float2>, IRound<Float2, Int2>,
|
||||
@ -96,8 +96,8 @@ public record struct Float2 : IAbsolute<Float2>, IAverage<Float2>, ICeiling<Floa
|
||||
else if (mag > maxMag) val *= maxMag;
|
||||
return val;
|
||||
}
|
||||
public static Float3 Cross(Float2 a, Float2 b, bool normalized = false) =>
|
||||
Float3.Cross(a, b, normalized);
|
||||
public static float Cross(Float2 a, Float2 b, bool normalized = false) =>
|
||||
Float3.Cross(a, b, normalized).z;
|
||||
public static Float2 Divide(Float2 num, params Float2[] vals) => num / Product(vals);
|
||||
public static float Dot(Float2 a, Float2 b) => a.x * b.x + a.y * b.y;
|
||||
public static float Dot(params Float2[] vals)
|
||||
|
||||
@ -208,18 +208,21 @@ public class Triangle : IClosestTo<Float3>, IContains<Float3>, IContainsPartial<
|
||||
}
|
||||
public override int GetHashCode() => base.GetHashCode();
|
||||
|
||||
public bool Contains(Float3 point)
|
||||
public bool Contains(Float3 point) => Contains(point, 0.05f);
|
||||
public bool Contains(Float3 point, float tolerance)
|
||||
{
|
||||
Triangle pab = (point, a, b),
|
||||
pbc = (point, b, c),
|
||||
pca = (point, c, a);
|
||||
return Mathf.Absolute(Area - (pab.Area + pbc.Area + pca.Area)) < 0.05f;
|
||||
return Mathf.Absolute(Area - (pab.Area + pbc.Area + pca.Area)) < tolerance;
|
||||
}
|
||||
public bool Contains(Line line) =>
|
||||
Contains(line.a) && Contains(line.b);
|
||||
public bool Contains(Line line) => Contains(line, 0.05f);
|
||||
public bool Contains(Line line, float tolerance) =>
|
||||
Contains(line.a, tolerance) && Contains(line.b, tolerance);
|
||||
|
||||
public bool ContainsPartially(Line line) =>
|
||||
Contains(line.a) || Contains(line.b);
|
||||
public bool ContainsPartially(Line line) => ContainsPartially(line, 0.05f);
|
||||
public bool ContainsPartially(Line line, float tolerance) =>
|
||||
Contains(line.a, tolerance) || Contains(line.b, tolerance);
|
||||
|
||||
public Float3[] GetAllVerts() => new[] { a, b, c };
|
||||
|
||||
|
||||
@ -66,4 +66,9 @@ Anyway, that's everything in this update. Again, pretty small, but meaningful no
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Emgu.CV" Version="4.7.0.5276" />
|
||||
<PackageReference Include="Emgu.CV.runtime.windows" Version="4.7.0.5276" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user