Skip to content

Commit

Permalink
Use coordinate system as a generics parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmada committed Oct 26, 2023
1 parent 0e66e8e commit e3db11d
Show file tree
Hide file tree
Showing 14 changed files with 55 additions and 66 deletions.
19 changes: 12 additions & 7 deletions src/NetFabric.Numerics/IGeometricBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
/// <summary>
/// Represents a geometric type.
/// </summary>
/// <typeparam name="TSelf">The type that implements the interface.</typeparam>
public interface IGeometricBase<TSelf>
/// <typeparam name="TSelf">The type implementing the interface.</typeparam>
/// <typeparam name="TCoordinateSystem">The type representing the coordinate system.</typeparam>
public interface IGeometricBase<TSelf, TCoordinateSystem>
: IEquatable<TSelf>,
IEqualityOperators<TSelf, TSelf, bool>
where TSelf : struct, IGeometricBase<TSelf>?
where TSelf : struct, IGeometricBase<TSelf, TCoordinateSystem>?
where TCoordinateSystem : ICoordinateSystem
{
/// <summary>
/// Gets a coordinate system of the point.
/// Gets the coordinate system of the point.
/// </summary>
/// <value>The coordinate system of the point.</value>
ICoordinateSystem CoordinateSystem { get; }
TCoordinateSystem CoordinateSystem { get; }

/// <summary>
/// Gets the value for a given coordinate of the point.
Expand All @@ -30,15 +32,18 @@ public interface IGeometricBase<TSelf>
/// </remarks>
object this[int index] { get; }

/// <summary>Gets the value <c>0</c> for the type.</summary>
/// <summary>
/// Gets the zero value for the type.
/// </summary>
static abstract TSelf Zero { get; }

/// <summary>
/// Determines whether <paramref name="value"/> is zero.
/// Determines whether a value is zero.
/// </summary>
/// <param name="value">The value to check.</param>
/// <returns><c>true</c> if the value is a zero vector; otherwise, <c>false</c>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsZero(TSelf value)
=> value.Equals(TSelf.Zero);
}

3 changes: 1 addition & 2 deletions src/NetFabric.Numerics/IMatrix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
/// <typeparam name="TSelf">The type that implements the interface.</typeparam>
/// <typeparam name="T">The type of the matrix elements.</typeparam>
public interface IMatrix<TSelf, T>
: IGeometricBase<TSelf>,
IAdditiveIdentity<TSelf, TSelf>,
: IAdditiveIdentity<TSelf, TSelf>,
IUnaryPlusOperators<TSelf, TSelf>,
IAdditionOperators<TSelf, TSelf, TSelf>,
IUnaryNegationOperators<TSelf, TSelf>,
Expand Down
9 changes: 6 additions & 3 deletions src/NetFabric.Numerics/IPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ namespace NetFabric.Numerics;
/// <summary>
/// Represents a point in a coordinate system.
/// </summary>
public interface IPoint<TSelf>
: IGeometricBase<TSelf>,
/// <typeparam name="TSelf">The type implementing the interface.</typeparam>
/// <typeparam name="TCoordinateSystem">The type representing the coordinate system.</typeparam>
public interface IPoint<TSelf, TCoordinateSystem>
: IGeometricBase<TSelf, TCoordinateSystem>,
IMinMaxValue<TSelf>
where TSelf : struct, IPoint<TSelf>?
where TSelf : struct, IPoint<TSelf, TCoordinateSystem>?
where TCoordinateSystem : ICoordinateSystem
{
}
10 changes: 6 additions & 4 deletions src/NetFabric.Numerics/IVector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ namespace NetFabric.Numerics;
/// <summary>
/// Represents a vector in a coordinate system.
/// </summary>
/// <typeparam name="TSelf">The type that implements the interface.</typeparam>
/// <typeparam name="TSelf">The type implementing the interface.</typeparam>
/// <typeparam name="TCoordinateSystem">The type representing the coordinate system.</typeparam>
/// <typeparam name="T">The type of the vector coordinates.</typeparam>
public interface IVector<TSelf, T>
: IGeometricBase<TSelf>,
public interface IVector<TSelf, TCoordinateSystem, T>
: IGeometricBase<TSelf, TCoordinateSystem>,
IComparable,
IComparable<TSelf>,
IComparisonOperators<TSelf, TSelf, bool>,
Expand All @@ -18,7 +19,8 @@ public interface IVector<TSelf, T>
IMultiplyOperators<TSelf, T, TSelf>,
IDivisionOperators<TSelf, T, TSelf>,
IMinMaxValue<TSelf>
where TSelf : struct, IVector<TSelf, T>?
where TSelf : struct, IVector<TSelf, TCoordinateSystem, T>?
where TCoordinateSystem : ICoordinateSystem
where T : struct, INumber<T>, IMinMaxValue<T>
{
}
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Polar/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace NetFabric.Numerics.Polar;
[System.Diagnostics.DebuggerDisplay("Radius = {Radius}, Azimuth = {Azimuth}")]
[SkipLocalsInit]
public readonly struct Point<TAngleUnits, T>
: IPoint<Point<TAngleUnits, T>>
: IPoint<Point<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>
where TAngleUnits : struct, IAngleUnits<TAngleUnits>
where T : struct, IFloatingPoint<T>, IMinMaxValue<T>
{
Expand Down Expand Up @@ -54,7 +54,7 @@ public Point(T radius, Angle<TAngleUnits, T> azimuth)
/// </summary>
public static readonly PointReduced<TAngleUnits, T> Zero = new(T.Zero, Angle<TAngleUnits, T>.Zero);

static Point<TAngleUnits, T> IGeometricBase<Point<TAngleUnits, T>>.Zero
static Point<TAngleUnits, T> IGeometricBase<Point<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.Zero
=> Zero;

/// <summary>
Expand All @@ -79,8 +79,6 @@ static Point<TAngleUnits, T> IMinMaxValue<Point<TAngleUnits, T>>.MaxValue
/// </summary>
public CoordinateSystem<TAngleUnits, T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Point<TAngleUnits, T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -127,7 +125,7 @@ public static Point<TAngleUnits, T> CreateTruncating<TOther>(in Point<TAngleUnit
T.CreateTruncating(point.Radius),
Angle<TAngleUnits, T>.CreateTruncating(point.Azimuth));

object IGeometricBase<Point<TAngleUnits, T>>.this[int index]
object IGeometricBase<Point<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.this[int index]
=> index switch
{
0 => Radius,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Polar/PointReduced.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace NetFabric.Numerics.Polar;
[System.Diagnostics.DebuggerDisplay("Radius = {Radius}, Azimuth = {Azimuth}")]
[SkipLocalsInit]
public readonly record struct PointReduced<TAngleUnits, T>(T Radius, AngleReduced<TAngleUnits, T> Azimuth)
: IPoint<PointReduced<TAngleUnits, T>>
: IPoint<PointReduced<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>
where TAngleUnits : struct, IAngleUnits<TAngleUnits>
where T : struct, IFloatingPoint<T>, IMinMaxValue<T>
{
Expand All @@ -26,7 +26,7 @@ public readonly record struct PointReduced<TAngleUnits, T>(T Radius, AngleReduce
/// </summary>
public static readonly PointReduced<TAngleUnits, T> Zero = new(T.Zero, Angle<TAngleUnits, T>.Zero);

static PointReduced<TAngleUnits, T> IGeometricBase<PointReduced<TAngleUnits, T>>.Zero
static PointReduced<TAngleUnits, T> IGeometricBase<PointReduced<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.Zero
=> Zero;

/// <summary>
Expand All @@ -51,8 +51,6 @@ static PointReduced<TAngleUnits, T> IMinMaxValue<PointReduced<TAngleUnits, T>>.M
/// </summary>
public CoordinateSystem<TAngleUnits, T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<PointReduced<TAngleUnits, T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -107,7 +105,7 @@ public static PointReduced<TAngleUnits, T> CreateTruncating<TOther>(in PointRedu
public static implicit operator Point<TAngleUnits, T>(PointReduced<TAngleUnits, T> angle)
=> new(angle.Radius, angle.Azimuth);

object IGeometricBase<PointReduced<TAngleUnits, T>>.this[int index]
object IGeometricBase<PointReduced<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.this[int index]
=> index switch
{
0 => Radius,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Polar/Vector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace NetFabric.Numerics.Polar;
[System.Diagnostics.DebuggerDisplay("Radius = {Radius}, Azimuth = {Azimuth}")]
[SkipLocalsInit]
public readonly record struct Vector<TAngleUnits, T>(T Radius, Angle<TAngleUnits, T> Azimuth)
: IVector<Vector<TAngleUnits, T>, T>
: IVector<Vector<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>, T>
where TAngleUnits : struct, IAngleUnits<TAngleUnits>
where T : struct, IFloatingPoint<T>, IMinMaxValue<T>
{
Expand All @@ -30,7 +30,7 @@ public readonly record struct Vector<TAngleUnits, T>(T Radius, Angle<TAngleUnits
/// </summary>
public static readonly Vector<TAngleUnits, T> Zero = new(T.Zero, Angle<TAngleUnits, T>.Zero);

static Vector<TAngleUnits, T> IGeometricBase<Vector<TAngleUnits, T>>.Zero
static Vector<TAngleUnits, T> IGeometricBase<Vector<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.Zero
=> Zero;

static Vector<TAngleUnits, T> IAdditiveIdentity<Vector<TAngleUnits, T>, Vector<TAngleUnits, T>>.AdditiveIdentity
Expand Down Expand Up @@ -58,8 +58,6 @@ static Vector<TAngleUnits, T> IMinMaxValue<Vector<TAngleUnits, T>>.MaxValue
/// </summary>
public CoordinateSystem<TAngleUnits, T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Vector<TAngleUnits, T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -106,7 +104,7 @@ public static Vector<TAngleUnits, T> CreateTruncating<TOther>(in Vector<TAngleUn
T.CreateTruncating(vector.Radius),
Angle<TAngleUnits, T>.CreateTruncating(vector.Azimuth));

object IGeometricBase<Vector<TAngleUnits, T>>.this[int index]
object IGeometricBase<Vector<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.this[int index]
=> index switch
{
0 => Radius,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Rectangular2D/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ namespace NetFabric.Numerics.Rectangular2D;
[System.Diagnostics.DebuggerDisplay("X = {X}, Y = {Y}")]
[SkipLocalsInit]
public readonly record struct Point<T>(T X, T Y)
: IPoint<Point<T>>
: IPoint<Point<T>, CoordinateSystem<T>>
where T: struct, INumber<T>, IMinMaxValue<T>
{
#region constants

public static readonly Point<T> Zero = new(T.Zero, T.Zero);

static Point<T> IGeometricBase<Point<T>>.Zero
static Point<T> IGeometricBase<Point<T>, CoordinateSystem<T>>.Zero
=> Zero;

/// <summary>
Expand All @@ -45,8 +45,6 @@ static Point<T> IMinMaxValue<Point<T>>.MaxValue
/// </summary>
public CoordinateSystem<T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Point<T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -116,7 +114,7 @@ public static Point<T> CreateTruncating<TOther>(in Point<TOther> point)

#endregion

object IGeometricBase<Point<T>>.this[int index]
object IGeometricBase<Point<T>, CoordinateSystem<T>>.this[int index]
=> index switch
{
0 => X,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Rectangular2D/Vector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace NetFabric.Numerics.Rectangular2D;
[System.Diagnostics.DebuggerDisplay("X = {X}, Y = {Y}")]
[SkipLocalsInit]
public readonly record struct Vector<T>(T X, T Y)
: IVector<Vector<T>, T>
: IVector<Vector<T>, CoordinateSystem<T>, T>
where T : struct, INumber<T>, IMinMaxValue<T>
{

Expand All @@ -28,7 +28,7 @@ public readonly record struct Vector<T>(T X, T Y)
/// </summary>
public static readonly Vector<T> Zero = new(T.Zero, T.Zero);

static Vector<T> IGeometricBase<Vector<T>>.Zero
static Vector<T> IGeometricBase<Vector<T>, CoordinateSystem<T>>.Zero
=> Zero;

static Vector<T> IAdditiveIdentity<Vector<T>, Vector<T>>.AdditiveIdentity
Expand Down Expand Up @@ -66,8 +66,6 @@ static Vector<T> IMinMaxValue<Vector<T>>.MaxValue
/// </summary>
public CoordinateSystem<T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Vector<T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -117,7 +115,7 @@ public static Vector<T> CreateTruncating<TOther>(in Vector<TOther> vector)
T.CreateTruncating(vector.Y)
);

object IGeometricBase<Vector<T>>.this[int index]
object IGeometricBase<Vector<T>, CoordinateSystem<T>>.this[int index]
=> index switch
{
0 => X,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Rectangular3D/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ namespace NetFabric.Numerics.Rectangular3D;
[System.Diagnostics.DebuggerDisplay("X = {X}, Y = {Y}, Z = {Z}")]
[SkipLocalsInit]
public readonly record struct Point<T>(T X, T Y, T Z)
: IPoint<Point<T>>
: IPoint<Point<T>, CoordinateSystem<T>>
where T: struct, INumber<T>, IMinMaxValue<T>
{
#region constants

public static readonly Point<T> Zero = new(T.Zero, T.Zero, T.Zero);

static Point<T> IGeometricBase<Point<T>>.Zero
static Point<T> IGeometricBase<Point<T>, CoordinateSystem<T>>.Zero
=> Zero;

/// <summary>
Expand All @@ -47,8 +47,6 @@ static Point<T> IMinMaxValue<Point<T>>.MaxValue
/// </summary>
public CoordinateSystem<T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Point<T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -121,7 +119,7 @@ public static Point<T> CreateTruncating<TOther>(in Point<TOther> point)

#endregion

object IGeometricBase<Point<T>>.this[int index]
object IGeometricBase<Point<T>, CoordinateSystem<T>>.this[int index]
=> index switch
{
0 => X,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Rectangular3D/Vector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace NetFabric.Numerics.Rectangular3D;
[System.Diagnostics.DebuggerDisplay("X = {X}, Y = {Y}, Z = {Z}")]
[SkipLocalsInit]
public readonly record struct Vector<T>(T X, T Y, T Z)
: IVector<Vector<T>, T>
: IVector<Vector<T>, CoordinateSystem<T>, T>
where T : struct, INumber<T>, IMinMaxValue<T>
{

Expand All @@ -29,7 +29,7 @@ public readonly record struct Vector<T>(T X, T Y, T Z)
/// </summary>
public static readonly Vector<T> Zero = new(T.Zero, T.Zero, T.Zero);

static Vector<T> IGeometricBase<Vector<T>>.Zero
static Vector<T> IGeometricBase<Vector<T>, CoordinateSystem<T>>.Zero
=> Zero;

static Vector<T> IAdditiveIdentity<Vector<T>, Vector<T>>.AdditiveIdentity
Expand Down Expand Up @@ -72,8 +72,6 @@ static Vector<T> IMinMaxValue<Vector<T>>.MaxValue
/// </summary>
public CoordinateSystem<T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Vector<T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -126,7 +124,7 @@ public static Vector<T> CreateTruncating<TOther>(in Vector<TOther> vector)
T.CreateTruncating(vector.Z)
);

object IGeometricBase<Vector<T>>.this[int index]
object IGeometricBase<Vector<T>, CoordinateSystem<T>>.this[int index]
=> index switch
{
0 => X,
Expand Down
8 changes: 3 additions & 5 deletions src/NetFabric.Numerics/Spherical/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace NetFabric.Numerics.Spherical;
[System.Diagnostics.DebuggerDisplay("Radius = {Radius}, Azimuth = {Azimuth}, Polar = {Polar}")]
[SkipLocalsInit]
public readonly struct Point<TAngleUnits, T>
: IPoint<Point<TAngleUnits, T>>
: IPoint<Point<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>
where TAngleUnits : struct, IAngleUnits<TAngleUnits>
where T : struct, IFloatingPoint<T>, IMinMaxValue<T>
{
Expand Down Expand Up @@ -62,7 +62,7 @@ public Point(T radius, Angle<TAngleUnits, T> azimuth, Angle<TAngleUnits, T> pola

public static readonly PointReduced<TAngleUnits, T> Zero = new(T.Zero, Angle<TAngleUnits, T>.Zero, Angle<TAngleUnits, T>.Zero);

static Point<TAngleUnits, T> IGeometricBase<Point<TAngleUnits, T>>.Zero
static Point<TAngleUnits, T> IGeometricBase<Point<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.Zero
=> Zero;

/// <summary>
Expand All @@ -87,8 +87,6 @@ static Point<TAngleUnits, T> IMinMaxValue<Point<TAngleUnits, T>>.MaxValue
/// </summary>
public CoordinateSystem<TAngleUnits, T> CoordinateSystem
=> new();
ICoordinateSystem IGeometricBase<Point<TAngleUnits, T>>.CoordinateSystem
=> CoordinateSystem;

/// <summary>
/// Creates an instance of the current type from a value,
Expand Down Expand Up @@ -138,7 +136,7 @@ public static Point<TAngleUnits, T> CreateTruncating<TOther>(in Point<TAngleUnit
Angle<TAngleUnits, T>.CreateTruncating(point.Azimuth),
Angle<TAngleUnits, T>.CreateTruncating(point.Polar));

object IGeometricBase<Point<TAngleUnits, T>>.this[int index]
object IGeometricBase<Point<TAngleUnits, T>, CoordinateSystem<TAngleUnits, T>>.this[int index]
=> index switch
{
0 => Radius,
Expand Down
Loading

0 comments on commit e3db11d

Please sign in to comment.