Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal - 3.0 Additional types for Silk.NET.Maths #1806

Merged
merged 26 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b817d31
start of additional math api proposal
dfkeenan Nov 19, 2023
4062407
Create proposal with summary.
dfkeenan Nov 19, 2023
30c708c
Reference decisions from 3.0 math proposal.
dfkeenan Nov 23, 2023
f68e2bc
Add headings for types under consideration.
dfkeenan Nov 23, 2023
b2734fe
Add rough cut of Angle struct
dfkeenan Nov 25, 2023
c030275
add parsable interfaces to Angle
dfkeenan Nov 25, 2023
d4c84a4
Add more angle methods.
dfkeenan Nov 25, 2023
4b4798a
add more angle helper methods.
dfkeenan Nov 25, 2023
9f65f5b
Split proposal into 3
dfkeenan Nov 26, 2023
b5013c0
Tweak angles
dfkeenan Nov 26, 2023
de5f43c
More collisions
dfkeenan Nov 26, 2023
2765624
Angle - rename T to TScalar
dfkeenan Nov 26, 2023
a675423
More angles
dfkeenan Dec 2, 2023
ad2a860
Add some collision shape interfaces.
dfkeenan Dec 9, 2023
3fccc87
Angel changes
dfkeenan Mar 30, 2024
bca07ec
More collision updates.
dfkeenan Mar 31, 2024
49ef276
Merge branch 'main' into more-math
dfkeenan May 4, 2024
272a2bf
Make Angle constructor internal
dfkeenan May 4, 2024
b655ee7
Add some Frustum details
dfkeenan May 4, 2024
2b448ae
Add meeting agenda/notes sections
dfkeenan May 4, 2024
6ed4e0b
Add discussion notes to angle
dfkeenan May 4, 2024
302c108
Add Empty to IColliderShape
dfkeenan May 4, 2024
c8ef63d
Make a start on color types. (Copying Stride 3D.)
dfkeenan May 4, 2024
3403494
propsal - angle: change: add "in" modifier to some methods.
dfkeenan Nov 30, 2024
103d95b
proposal - collision: add more details for BoxExtentF and OrientedBoxF
dfkeenan Nov 30, 2024
ed05289
Rename additional math type proposals to WIP
dfkeenan Nov 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Summary
Proposal API for additional math types to bring it up to feature parity with other popular math libraries i.e. `SlimDX`, `SharpDX`, or `Stride3D`. Leveraging modern .NET features such as `INumber<T>` and vectorization.

# Contributors
- Daniel Keenan (dfkeenan)

# Current Status
- [x] Proposed
- [ ] Discussed with API Review Board (ARB)
- [ ] Approved
- [ ] Implemented

# Design Decisions
- This proposal should compliment/augment the proposed 3.0 implementation of `Silk.Net.Maths`, matching `System.Numerics` where possible, with concessions for design oversights in that api.
- This proposal assumes no knowledge of the 2.x Math library.
- Text herein marked **INFORMATIVE** does not form a normative part of this proposal, and is for background only.
- Within this proposal, the key words **must**, **required**, **shall**, **should**, **recommended**, **may**, **could**, and **optional** are to be interpreted as described in [RFC 2119 - Key words for use in RFCs to Indicate Requirement Levels](https://www.ietf.org/rfc/rfc2119.txt). The additional key word **optionally** is an alternate form of **optional**, for use where grammatically appropriate. These key words are highlighted in the proposal for clarity.



# Proposed API

## Angle

* `IParsable<TSelf>`, `ISpanParsable<TSelf>`, `IUtf8SpanParsable<TSelf>`
* must parse angle in degrees using `IParsable<TScalar>`, `ISpanParsable<TScalar>`, `IUtf8SpanParsable<TSelf>`
* optional handle `°` character

* `IFormattable`, `IUtf8SpanFormattable`
* must produce text in degrees with default format of 2 decimal places. i.e. format string `0.##`
* optional include `°` character. i.e. format string `0.##°`

Interface implementations not included for brevity.

```csharp
/// <summary>
/// Represents a unit independant angle using a floating-point
/// internal representation.
/// </summary>
public readonly struct Angle<TScalar>
: IEquatable<Angle<TScalar>>
, IEqualityOperators<Angle<TScalar>,Angle<TScalar>, bool>
, IComparable<Angle<TScalar>>
, IComparisonOperators<Angle<TScalar>,Angle<TScalar>, bool>
, IAdditionOperators<Angle<TScalar>,Angle<TScalar>,Angle<TScalar>>
, IDivisionOperators<Angle<TScalar>, TScalar, Angle<TScalar>>
, IDivisionOperators<TScalar, Angle<TScalar>, Angle<TScalar>>
, IMultiplyOperators<Angle<TScalar>, TScalar, Angle<TScalar>>
, IMultiplyOperators<TScalar, Angle<TScalar>, Angle<TScalar>>
, IModulusOperators<Angle<TScalar>, Angle<TScalar>, Angle<TScalar>>
, ISubtractionOperators<Angle<TScalar>,Angle<TScalar>,Angle<TScalar>>
, IParsable<Angle<TScalar>>
, ISpanParsable<Angle<TScalar>>
, IUtf8SpanParsable<Angle<TScalar>>
, IFormattable
, IUtf8SpanFormattable
where TScalar : IFloatingPointIeee754<TScalar>
{
internal Angle(TScalar radians) { }

/// <summary>Angle in degrees in the range [0, 360]. Without fractional component.</summary>
public TScalar Degrees { get; }

/// <summary>Angle in degrees in the range [0, 360]. With fractional component.</summary>
public TScalar TotalDegrees { get; }

/// <summary>Angle in radians in range [π, -π].</summary>
public TScalar Radians { get; }

/// <summary>Angle in radians in range [0, 2π].</summary>
public TScalar PositiveRadians { get; }

/// <summary>Gets or sets the minutes component of the degrees this Silk.NET.Maths.Angle<TScalar> represents.</summary>
public TScalar Minutes { get; }

/// <summary>Gets or sets the seconds of the degrees this Silk.NET.Maths.Angle<TScalar> represents.</summary>
public TScalar Seconds { get; }


/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is a right angle (i.e. 90° or π/2).
/// </summary>
public bool IsRight { get; }

/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is a straight angle (i.e. 180° or π).
/// </summary>
public bool IsStraight { get; }

/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is a full rotation angle (i.e. 360° or 2π).
/// </summary>
public bool IsFullRotation { get; }

/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is an oblique angle (i.e. is not 90° or a multiple of 90°).
/// </summary>
public bool IsOblique { get; }

/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is an acute angle (i.e. less than 90° but greater than 0°).
/// </summary>
public bool IsAcute { get; }

/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is an obtuse angle (i.e. greater than 90° but less than 180°).
/// </summary>
public bool IsObtuse { get; }

/// <summary>
/// Gets a System.Boolean that determines whether this Silk.NET.Maths.Angle<TScalar>
/// is a reflex angle (i.e. greater than 180° but less than 360°).
/// </summary>
public bool IsReflex { get; }

/// <summary>
/// Gets a Silk.NET.Maths.Angle<TScalar> instance that complements this angle (i.e. the two angles add to 90°).
/// </summary>
public Angle<TScalar> Complement { get; }

/// <summary>
/// Gets a Silk.NET.Maths.Angle<TScalar> instance that supplements this angle (i.e. the two angles add to 180°).
/// </summary>
public Angle<TScalar> Supplement { get; }

/// <summary>Implicit cast in radians</summary>
public static implicit operator TScalar(Angle<TScalar> angle) => default;
}

```



```csharp

public static class Angle
{
public static Angle<TScalar> FromRadians<TScalar>(TScalar radians)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> FromDegrees<TScalar>(TScalar degrees)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> FromDegrees<TScalar>(TScalar degrees, TScalar minutes, TScalar seconds)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Min<TScalar>(Angle<TScalar> left, Angle<TScalar> right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Max<TScalar>(Angle<TScalar> left, Angle<TScalar> right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Add<TScalar>(Angle<TScalar> left, Angle<TScalar> right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Subtract<TScalar>(Angle<TScalar> left, Angle<TScalar> right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Multiply<TScalar>(Angle<TScalar> left, TScalar right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Divide<TScalar>(Angle<TScalar> left, TScalar right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Clamp<TScalar>(Angle<TScalar> value, Angle<TScalar> min, Angle<TScalar> max)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Atan2<TScalar>(TScalar y, TScalar x)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> ArcTan<TScalar>(TScalar y, TScalar x)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> ArcSin<TScalar>(TScalar sin)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> ArcCos<TScalar>(TScalar cos)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Between<TScalar>(in Vector2F<TScalar> left, in Vector2F<TScalar> right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> Between<TScalar>(in Vector3F<TScalar> left, in Vector3F<TScalar> right)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> ZeroAngle<TScalar>()
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> RightAngle<TScalar>()
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> StraightAngle<TScalar>()
where TScalar : IFloatingPointIeee754<TScalar>
=> default;

public static Angle<TScalar> FullRotationAngle<TScalar>()
where TScalar : IFloatingPointIeee754<TScalar>
=> default;
}
```

# Meeting Agenda/Notes
## TDB
* Degrees, minutes and seconds are not fractional. Should they be changed to an integer type (`int`)?
* ```csharp
public int Degrees { get; }
public int Minutes { get; }
public int Seconds { get; }

public static Angle<TScalar> FromDegrees<TScalar>(int degrees, int minutes, int seconds)
where TScalar : IFloatingPointIeee754<TScalar>
=> default;
```
Loading
Loading