From dea59430fe85f181c32c9e802f41055c47c855d2 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 14:43:37 +0000 Subject: [PATCH] Answer vector magnitude and distance with the dimension, not a bare T [minor] CLAUDE.md states IVectorN.Magnitude() returns the corresponding IVector0, and the C++ projection does exactly that. The C# side honoured half of it: base vector forms had Magnitude(), overloads had none, and nothing had a typed distance -- so position.Length() and a.Distance(b) handed back a bare T and the caller re-wrapped the dimension by hand, which is the untyped step the library exists to remove. Both members are now emitted onto every vector form, overloads included, from one helper. They return the vector0 base rather than an overload of it, since the base is what every overload widens from. The return type is emitted fully qualified. Every vector form has a Length() method, so inside Displacement3D -- whose magnitude form is called Length -- an unqualified Length return type puts a method group and a generic type under one identifier. It parses, which is the problem: it compiles and then misleads whoever reads the generated source. No MagnitudeSquared(). The square of a dimension usually has no declared name, and where it has one it is not unique, so LengthSquared() keeps returning T. Magnitude() and DistanceTo() build with Create rather than a From{Unit} factory, bypassing Vector0Guards, which is correct for a value that came out of a square root and keeps the guard off a hot-loop call. Fixes #238 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01HLTGLrPaSc3E9APdgUq6wn --- CLAUDE.md | 19 +- .../Acceleration2D.g.cs | 8 +- .../Acceleration3D.g.cs | 8 +- .../Acceleration4D.g.cs | 8 +- .../AngularAcceleration3D.g.cs | 8 +- .../AngularDisplacement3D.g.cs | 8 +- .../AngularJerk3D.g.cs | 8 +- .../AngularMomentum3D.g.cs | 8 +- .../AngularVelocity3D.g.cs | 8 +- .../Current3D.g.cs | 8 +- .../Displacement2D.g.cs | 8 +- .../Displacement3D.g.cs | 8 +- .../Displacement4D.g.cs | 8 +- .../ElectricField2D.g.cs | 8 +- .../ElectricField3D.g.cs | 8 +- .../Force2D.g.cs | 8 +- .../Force3D.g.cs | 8 +- .../Force4D.g.cs | 8 +- .../GravitationalField3D.g.cs | 7 + .../Jerk2D.g.cs | 8 +- .../Jerk3D.g.cs | 8 +- .../Jerk4D.g.cs | 8 +- .../MagneticFluxDensity3D.g.cs | 8 +- .../Momentum2D.g.cs | 8 +- .../Momentum3D.g.cs | 8 +- .../Momentum4D.g.cs | 8 +- .../Position3D.g.cs | 7 + .../Snap2D.g.cs | 8 +- .../Snap3D.g.cs | 8 +- .../Snap4D.g.cs | 8 +- .../ThrustVector.g.cs | 7 + .../Torque3D.g.cs | 8 +- .../Translation3D.g.cs | 7 + .../Velocity2D.g.cs | 8 +- .../Velocity3D.g.cs | 8 +- .../Velocity4D.g.cs | 8 +- .../WeightVector.g.cs | 7 + .../WindVelocity3D.g.cs | 7 + .../Generators/QuantitiesGenerator.cs | 51 ++++- .../Quantities/VectorMagnitudeTests.cs | 193 ++++++++++++++++++ 40 files changed, 486 insertions(+), 67 deletions(-) create mode 100644 Semantics.Test/Quantities/VectorMagnitudeTests.cs diff --git a/CLAUDE.md b/CLAUDE.md index 00df749..ba9246b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,7 +66,24 @@ Every quantity is a vector. Dimensionality of the *direction space* is part of t | `IVector3` | 3D directional | Per-component | `Velocity3D`, `Force3D`, `Position3D` | | `IVector4` | 4D directional | Per-component | (reserved for relativistic / spacetime) | -`IVectorN.Magnitude()` (for N >= 1) returns the corresponding `IVector0`. +`IVectorN.Magnitude()` (for N >= 1) returns the corresponding `IVector0`, and `DistanceTo(other)` +answers with the same type. Both are emitted onto every vector form, overloads included, and both +return the `vector0` **base** rather than one of its overloads — `Velocity3D.Magnitude()` is a +`Speed`, `Position3D.Magnitude()` is a `Length` and not a `Distance` — because the base is what +every overload widens from. A caller who wants the overload narrows explicitly. + +The return type is written fully qualified in the generated source, which looks like noise and is +not: every vector form has a `Length()` method, so inside `Displacement3D`, whose magnitude form is +*called* `Length`, an unqualified `Length` return type puts a method group and a generic type +under one identifier. It parses, because the type argument list disambiguates it — which is the +problem, since it compiles and then misleads the next reader. + +`Length()` and `LengthSquared()` keep answering with a bare `T`, and the squared one has no typed +counterpart on purpose: the square of a dimension usually has no declared name, and where it has one +it is not unique, so there would be nothing to return. `Magnitude()` and `DistanceTo()` build with +`Create` rather than a `From{Unit}` factory, bypassing `Vector0Guards` — correct, because a value +that came out of a square root is non-negative by construction, and it keeps the guard off a call +that belongs in a hot loop. All generated types are generic over a numeric storage type: `where T : struct, INumber`. diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration2D.g.cs index 8e49004..f178fde 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Acceleration2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public AccelerationMagnitude Magnitude() => AccelerationMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AccelerationMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(Acceleration2D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration3D.g.cs index fba75b8..d8cbd59 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Acceleration3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public AccelerationMagnitude Magnitude() => AccelerationMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AccelerationMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(Acceleration3D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration4D.g.cs index 16eec22..d8824d7 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Acceleration4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Acceleration4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public AccelerationMagnitude Magnitude() => AccelerationMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AccelerationMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(Acceleration4D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularAcceleration3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularAcceleration3D.g.cs index 64e3bf4..dbb6ab1 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularAcceleration3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularAcceleration3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static AngularAcceleration3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public AngularAccelerationMagnitude Magnitude() => AngularAccelerationMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AngularAccelerationMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AngularAccelerationMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AngularAccelerationMagnitude DistanceTo(AngularAcceleration3D other) => global::ktsu.Semantics.Quantities.AngularAccelerationMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularDisplacement3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularDisplacement3D.g.cs index 12e7acf..c610ec7 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularDisplacement3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularDisplacement3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static AngularDisplacement3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public Angle Magnitude() => Angle.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Angle Magnitude() => global::ktsu.Semantics.Quantities.Angle.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Angle DistanceTo(AngularDisplacement3D other) => global::ktsu.Semantics.Quantities.Angle.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularJerk3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularJerk3D.g.cs index 4ecd6d6..1cf08da 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularJerk3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularJerk3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static AngularJerk3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public AngularJerkMagnitude Magnitude() => AngularJerkMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AngularJerkMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AngularJerkMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AngularJerkMagnitude DistanceTo(AngularJerk3D other) => global::ktsu.Semantics.Quantities.AngularJerkMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularMomentum3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularMomentum3D.g.cs index b39ba02..ba85d06 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularMomentum3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularMomentum3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static AngularMomentum3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public AngularMomentumMagnitude Magnitude() => AngularMomentumMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AngularMomentumMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AngularMomentumMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AngularMomentumMagnitude DistanceTo(AngularMomentum3D other) => global::ktsu.Semantics.Quantities.AngularMomentumMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularVelocity3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularVelocity3D.g.cs index 51a6381..6c57142 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularVelocity3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/AngularVelocity3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static AngularVelocity3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public AngularSpeed Magnitude() => AngularSpeed.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AngularSpeed Magnitude() => global::ktsu.Semantics.Quantities.AngularSpeed.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AngularSpeed DistanceTo(AngularVelocity3D other) => global::ktsu.Semantics.Quantities.AngularSpeed.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Current3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Current3D.g.cs index ba4134a..bffb997 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Current3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Current3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Current3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public CurrentMagnitude Magnitude() => CurrentMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.CurrentMagnitude Magnitude() => global::ktsu.Semantics.Quantities.CurrentMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.CurrentMagnitude DistanceTo(Current3D other) => global::ktsu.Semantics.Quantities.CurrentMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement2D.g.cs index 8287e98..61d43dc 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Displacement2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public Length Magnitude() => Length.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Length Magnitude() => global::ktsu.Semantics.Quantities.Length.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Length DistanceTo(Displacement2D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement3D.g.cs index d15dadb..ca81f97 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Displacement3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public Length Magnitude() => Length.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Length Magnitude() => global::ktsu.Semantics.Quantities.Length.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Length DistanceTo(Displacement3D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement4D.g.cs index e4d46e6..a65d7b1 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Displacement4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Displacement4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public Length Magnitude() => Length.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Length Magnitude() => global::ktsu.Semantics.Quantities.Length.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Length DistanceTo(Displacement4D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField2D.g.cs index 56853c8..7ff6541 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static ElectricField2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public ElectricFieldMagnitude Magnitude() => ElectricFieldMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ElectricFieldMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ElectricFieldMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ElectricFieldMagnitude DistanceTo(ElectricField2D other) => global::ktsu.Semantics.Quantities.ElectricFieldMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField3D.g.cs index c5917fc..5990ee0 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ElectricField3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static ElectricField3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public ElectricFieldMagnitude Magnitude() => ElectricFieldMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ElectricFieldMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ElectricFieldMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ElectricFieldMagnitude DistanceTo(ElectricField3D other) => global::ktsu.Semantics.Quantities.ElectricFieldMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force2D.g.cs index be8dd64..01150a3 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Force2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public ForceMagnitude Magnitude() => ForceMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ForceMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(Force2D other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force3D.g.cs index c237666..bbf01a0 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Force3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public ForceMagnitude Magnitude() => ForceMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ForceMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(Force3D other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force4D.g.cs index d28325d..94dbfd7 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Force4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Force4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public ForceMagnitude Magnitude() => ForceMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ForceMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(Force4D other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/GravitationalField3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/GravitationalField3D.g.cs index c75574a..49faa20 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/GravitationalField3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/GravitationalField3D.g.cs @@ -40,6 +40,13 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static GravitationalField3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.AccelerationMagnitude Magnitude() => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(GravitationalField3D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk2D.g.cs index af1c480..864fc4a 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Jerk2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public JerkMagnitude Magnitude() => JerkMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.JerkMagnitude Magnitude() => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.JerkMagnitude DistanceTo(Jerk2D other) => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk3D.g.cs index 05e6672..b5b0796 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Jerk3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public JerkMagnitude Magnitude() => JerkMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.JerkMagnitude Magnitude() => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.JerkMagnitude DistanceTo(Jerk3D other) => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk4D.g.cs index 0c8ebc6..593e8b0 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Jerk4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Jerk4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public JerkMagnitude Magnitude() => JerkMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.JerkMagnitude Magnitude() => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.JerkMagnitude DistanceTo(Jerk4D other) => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/MagneticFluxDensity3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/MagneticFluxDensity3D.g.cs index 21dd5ee..bcdb287 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/MagneticFluxDensity3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/MagneticFluxDensity3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static MagneticFluxDensity3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public MagneticFluxDensityMagnitude Magnitude() => MagneticFluxDensityMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.MagneticFluxDensityMagnitude Magnitude() => global::ktsu.Semantics.Quantities.MagneticFluxDensityMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.MagneticFluxDensityMagnitude DistanceTo(MagneticFluxDensity3D other) => global::ktsu.Semantics.Quantities.MagneticFluxDensityMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum2D.g.cs index f213d65..e02a940 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Momentum2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public MomentumMagnitude Magnitude() => MomentumMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.MomentumMagnitude Magnitude() => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.MomentumMagnitude DistanceTo(Momentum2D other) => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum3D.g.cs index 61bdd25..79fbe6f 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Momentum3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public MomentumMagnitude Magnitude() => MomentumMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.MomentumMagnitude Magnitude() => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.MomentumMagnitude DistanceTo(Momentum3D other) => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum4D.g.cs index ef4cbe8..d3c2c5d 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Momentum4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Momentum4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public MomentumMagnitude Magnitude() => MomentumMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.MomentumMagnitude Magnitude() => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.MomentumMagnitude DistanceTo(Momentum4D other) => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Position3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Position3D.g.cs index 2ed2716..4d2ccc4 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Position3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Position3D.g.cs @@ -40,6 +40,13 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Position3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Length Magnitude() => global::ktsu.Semantics.Quantities.Length.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Length DistanceTo(Position3D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap2D.g.cs index a4862f2..a5ca5bb 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Snap2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public SnapMagnitude Magnitude() => SnapMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.SnapMagnitude Magnitude() => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.SnapMagnitude DistanceTo(Snap2D other) => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap3D.g.cs index 478f4d8..af6deee 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Snap3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public SnapMagnitude Magnitude() => SnapMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.SnapMagnitude Magnitude() => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.SnapMagnitude DistanceTo(Snap3D other) => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap4D.g.cs index a26006c..a42f879 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Snap4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Snap4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public SnapMagnitude Magnitude() => SnapMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.SnapMagnitude Magnitude() => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.SnapMagnitude DistanceTo(Snap4D other) => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThrustVector.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThrustVector.g.cs index 5a2bfc1..8277cd4 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThrustVector.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/ThrustVector.g.cs @@ -40,6 +40,13 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static ThrustVector UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ForceMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(ThrustVector other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Torque3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Torque3D.g.cs index 0a31627..f8c7178 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Torque3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Torque3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Torque3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public TorqueMagnitude Magnitude() => TorqueMagnitude.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.TorqueMagnitude Magnitude() => global::ktsu.Semantics.Quantities.TorqueMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.TorqueMagnitude DistanceTo(Torque3D other) => global::ktsu.Semantics.Quantities.TorqueMagnitude.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Translation3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Translation3D.g.cs index 1404c2c..4327a1b 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Translation3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Translation3D.g.cs @@ -40,6 +40,13 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Translation3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Length Magnitude() => global::ktsu.Semantics.Quantities.Length.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Length DistanceTo(Translation3D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity2D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity2D.g.cs index 56715ad..acb71be 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity2D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity2D.g.cs @@ -34,8 +34,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Y-axis. public static Velocity2D UnitY => new() { X = T.Zero, Y = T.One }; - /// Gets the magnitude as a . - public Speed Magnitude() => Speed.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Speed Magnitude() => global::ktsu.Semantics.Quantities.Speed.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Speed DistanceTo(Velocity2D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity3D.g.cs index f113969..16bcfd7 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity3D.g.cs @@ -40,8 +40,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static Velocity3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; - /// Gets the magnitude as a . - public Speed Magnitude() => Speed.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Speed Magnitude() => global::ktsu.Semantics.Quantities.Speed.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Speed DistanceTo(Velocity3D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity4D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity4D.g.cs index 662ff63..7035ea8 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity4D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/Velocity4D.g.cs @@ -46,8 +46,12 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the W-axis. public static Velocity4D UnitW => new() { X = T.Zero, Y = T.Zero, Z = T.Zero, W = T.One }; - /// Gets the magnitude as a . - public Speed Magnitude() => Speed.Create(Length()); + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Speed Magnitude() => global::ktsu.Semantics.Quantities.Speed.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Speed DistanceTo(Velocity4D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); /// Calculates the length of the vector. public T Length() diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WeightVector.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WeightVector.g.cs index 3e45863..dfb5edd 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WeightVector.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WeightVector.g.cs @@ -40,6 +40,13 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static WeightVector UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.ForceMagnitude Magnitude() => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(WeightVector other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WindVelocity3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WindVelocity3D.g.cs index d57e9b8..b8d989f 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WindVelocity3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/WindVelocity3D.g.cs @@ -40,6 +40,13 @@ namespace ktsu.Semantics.Quantities; /// Gets the unit vector for the Z-axis. public static WindVelocity3D UnitZ => new() { X = T.Zero, Y = T.Zero, Z = T.One }; + /// Gets the magnitude of this vector as a . + public global::ktsu.Semantics.Quantities.Speed Magnitude() => global::ktsu.Semantics.Quantities.Speed.Create(Length()); + + /// Gets the distance to another vector as a . + /// The vector to measure the distance to. + public global::ktsu.Semantics.Quantities.Speed DistanceTo(WindVelocity3D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs b/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs index 525134b..01a726a 100644 --- a/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs +++ b/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs @@ -1141,10 +1141,7 @@ private static void EmitVectorType( WriteVectorComponentProperties(cb, components); WriteVectorStaticProperties(cb, fullType, components); - // Typed Magnitude() method returning V0 base - cb.WriteLine($"/// Gets the magnitude as a ."); - cb.WriteLine($"public {v0TypeName} Magnitude() => {v0TypeName}.Create(Length());"); - cb.NewLine(); + WriteVectorMagnitudeMembers(cb, fullType, v0TypeName); WriteVectorMethods(cb, fullType, components, dims); WriteVectorOperators(cb, fullType, components); @@ -1385,6 +1382,7 @@ private static void EmitVectorOverloadType(SourceProductionContext context, Quan { WriteVectorComponentProperties(cb, components); WriteVectorStaticProperties(cb, fullType, components); + WriteVectorMagnitudeMembers(cb, fullType, type.MagnitudeType); WriteVectorMethods(cb, fullType, components, dims); WriteVectorOperators(cb, fullType, components); @@ -1601,6 +1599,51 @@ private static void WriteVectorStaticProperties(CodeBlocker cb, string fullType, } } + /// + /// Writes the two members that answer with the dimension's magnitude form rather than with a + /// bare T: Magnitude() and DistanceTo(). Issue #238. + /// + /// + /// + /// The return type is written fully qualified, and that is not decoration. Every vector form + /// already has a Length() method, so inside Displacement3D — whose magnitude form + /// is called Length — an unqualified Length<T> return type puts a method + /// group and a generic type under one identifier. It parses, because the type argument list + /// disambiguates it, which is exactly the problem: it compiles and then misleads whoever reads + /// the generated source. + /// + /// + /// Both use Create rather than a From{Unit} factory, so they bypass + /// . That is correct rather than an oversight — a length and a + /// distance are non-negative by construction, having come out of a square root — and it keeps + /// the guard off a call that belongs in a hot loop. + /// + /// + /// There is deliberately no MagnitudeSquared(). The square of a dimension usually has no + /// declared name, and where it has one it is not unique, so there is nothing to return. + /// LengthSquared() keeps answering with T, which is the honest answer. + /// + /// + /// The code blocker to write to. + /// The vector type being written, including its type argument. + /// + /// The name of the dimension's magnitude form — the vector0 base, never one of its + /// overloads, since the base is what every overload widens from. + /// + private static void WriteVectorMagnitudeMembers(CodeBlocker cb, string fullType, string v0TypeName) + { + string v0 = $"global::ktsu.Semantics.Quantities.{v0TypeName}"; + + cb.WriteLine($"/// Gets the magnitude of this vector as a ."); + cb.WriteLine($"public {v0} Magnitude() => {v0}.Create(Length());"); + cb.NewLine(); + + cb.WriteLine($"/// Gets the distance to another vector as a ."); + cb.WriteLine("/// The vector to measure the distance to."); + cb.WriteLine($"public {v0} DistanceTo({fullType} other) => {v0}.Create(Distance(other));"); + cb.NewLine(); + } + private static void WriteVectorMethods(CodeBlocker cb, string fullType, string[] components, int dims) { string sumOfSquares = string.Join(" + ", components.Select(c => $"({c} * {c})")); diff --git a/Semantics.Test/Quantities/VectorMagnitudeTests.cs b/Semantics.Test/Quantities/VectorMagnitudeTests.cs new file mode 100644 index 0000000..ce3d687 --- /dev/null +++ b/Semantics.Test/Quantities/VectorMagnitudeTests.cs @@ -0,0 +1,193 @@ +// Copyright (c) 2023-2026 ktsu-dev contributors + +namespace ktsu.Semantics.Test.Quantities; + +using ktsu.Semantics.Quantities; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Covers the two vector members that answer with the dimension's magnitude form rather than with +/// a bare T — Magnitude() and DistanceTo(). Issue #238. +/// +/// +/// +/// Every assertion here is written through an explicitly typed local rather than +/// var. That is the point of most of these tests: the interesting claim is the static return +/// type, so the compiler checks it and the runtime assertion is the lesser half. A regression that +/// changed Velocity3D.Magnitude() back to T, or to the wrong V0, would stop this file +/// compiling rather than failing an assertion. +/// +/// +/// LengthSquared() and Length() deliberately still return T and are not +/// retested here; they are unchanged, and the squared one has no dimension to answer with. +/// +/// +[TestClass] +public sealed class VectorMagnitudeTests +{ + private const double Tolerance = 1e-10; + + // ---------------------------------------- Magnitude returns the V0 base + + /// + /// The case a naive generator rule would break on: the V0 base of Velocity is called + /// Speed, not Velocity, so a rule reading the dimension name rather than + /// quantities.vector0.base would emit a type that does not exist. + /// + [TestMethod] + public void Velocity3D_Magnitude_Is_Speed_Not_A_Bare_Storage_Value() + { + Velocity3D v = new() { X = 3.0, Y = 4.0, Z = 0.0 }; + + Speed speed = v.Magnitude(); + + Assert.AreEqual(5.0, speed.Value, Tolerance); + } + + /// + /// The second name-differs case, and a different shape of name: Acceleration's V0 base + /// is AccelerationMagnitude. + /// + [TestMethod] + public void Acceleration3D_Magnitude_Is_AccelerationMagnitude() + { + Acceleration3D a = new() { X = 0.0, Y = 6.0, Z = 8.0 }; + + AccelerationMagnitude magnitude = a.Magnitude(); + + Assert.AreEqual(10.0, magnitude.Value, Tolerance); + } + + /// + /// Displacement3D is the name-collision case. Its magnitude form is called + /// Length, and the vector already has a Length() method, so the generated return + /// type has to be fully qualified. This test is what proves the two are distinguishable from a + /// caller's side: one answers T, the other answers Length<T>. + /// + [TestMethod] + public void Displacement3D_Length_And_Magnitude_Agree_But_Differ_In_Type() + { + Displacement3D d = new() { X = 1.0, Y = 2.0, Z = 2.0 }; + + double bare = d.Length(); + Length typed = d.Magnitude(); + + Assert.AreEqual(3.0, bare, Tolerance); + Assert.AreEqual(bare, typed.Value, Tolerance); + } + + /// + /// A vector overload gets the members too, and answers with the V0 base rather than + /// with an overload of it — Length, not Distance — because the base is what every + /// overload widens from. A caller who wants Distance narrows explicitly. + /// + [TestMethod] + public void Position3D_Magnitude_Answers_With_The_V0_Base() + { + Position3D p = new() { X = 0.0, Y = 3.0, Z = 4.0 }; + + Length magnitude = p.Magnitude(); + + Assert.AreEqual(5.0, magnitude.Value, Tolerance); + } + + /// Two and four components get the same treatment as three. + [TestMethod] + public void Vector2_And_Vector4_Also_Answer_With_Their_V0_Base() + { + Velocity2D v2 = new() { X = 3.0, Y = 4.0 }; + Velocity4D v4 = new() { X = 1.0, Y = 1.0, Z = 1.0, W = 1.0 }; + + Speed fromTwo = v2.Magnitude(); + Speed fromFour = v4.Magnitude(); + + Assert.AreEqual(5.0, fromTwo.Value, Tolerance); + Assert.AreEqual(2.0, fromFour.Value, Tolerance); + } + + // -------------------------------------------------- Agreement and zero + + /// + /// Magnitude() is the V0 constructed from Length(), and nothing more. + /// + [TestMethod] + public void Magnitude_Equals_The_V0_Constructed_From_Length() + { + Velocity3D v = new() { X = -2.0, Y = 5.0, Z = 14.0 }; + + Speed magnitude = v.Magnitude(); + + Assert.AreEqual(Speed.Create(v.Length()).Value, magnitude.Value, Tolerance); + } + + /// The magnitude of a zero vector is the V0's zero. + [TestMethod] + public void Magnitude_Of_A_Zero_Vector_Is_The_V0_Zero() + { + Speed magnitude = Velocity3D.Zero.Magnitude(); + + Assert.AreEqual(Speed.Zero.Value, magnitude.Value, Tolerance); + } + + /// + /// Magnitude() uses Create rather than a From{Unit} factory, so it does + /// not run Vector0Guards. Negative components must therefore still produce a + /// non-negative magnitude by arithmetic alone, rather than by a guard throwing. + /// + [TestMethod] + public void Magnitude_Of_All_Negative_Components_Is_Non_Negative_Without_A_Guard() + { + Velocity3D v = new() { X = -3.0, Y = -4.0, Z = 0.0 }; + + Speed magnitude = v.Magnitude(); + + Assert.AreEqual(5.0, magnitude.Value, Tolerance); + } + + // ------------------------------------------------------------ DistanceTo + + /// + /// DistanceTo is Distance with its dimension kept, so it agrees with the bare + /// member exactly. + /// + [TestMethod] + public void DistanceTo_Agrees_With_Distance_But_Keeps_The_Dimension() + { + Displacement3D a = new() { X = 1.0, Y = 2.0, Z = 3.0 }; + Displacement3D b = new() { X = 4.0, Y = 6.0, Z = 3.0 }; + + double bare = a.Distance(b); + Length typed = a.DistanceTo(b); + + Assert.AreEqual(5.0, bare, Tolerance); + Assert.AreEqual(bare, typed.Value, Tolerance); + } + + /// + /// For a signed form, where subtraction is defined, the distance between two vectors is the + /// magnitude of their difference. This is the invariant that would catch a + /// DistanceTo wired to the wrong helper. + /// + [TestMethod] + public void DistanceTo_Is_The_Magnitude_Of_The_Difference() + { + Displacement3D a = new() { X = 1.0, Y = 2.0, Z = 3.0 }; + Displacement3D b = new() { X = 4.0, Y = 6.0, Z = 3.0 }; + + Length distance = a.DistanceTo(b); + Length ofDifference = (a - b).Magnitude(); + + Assert.AreEqual(ofDifference.Value, distance.Value, Tolerance); + } + + /// The distance from a vector to itself is zero. + [TestMethod] + public void DistanceTo_Self_Is_Zero() + { + Velocity3D v = new() { X = 7.0, Y = -1.0, Z = 4.0 }; + + Speed distance = v.DistanceTo(v); + + Assert.AreEqual(0.0, distance.Value, Tolerance); + } +}