diff --git a/CLAUDE.md b/CLAUDE.md index 8cce61c..aa5172b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -85,6 +85,21 @@ it is not unique, so there would be nothing to return. `Magnitude()` and `Distan 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. +Every vector form also gets the per-unit surface the scalars have: one `From{Unit}(T x, T y, T z)` +factory per entry in the dimension's `availableUnits`, named by the unit's singular lemma exactly as +the scalar factories are, and an `In(unit)` reader. A vector form reaches its units through the +dimension, so an overload gets them too — `Position3D.FromKilometer(6778, 0, 0)` is the call that +used to be a hand-written ×1000 at every construction site. The factories convert each component +through the same `Values` holder the scalar ones read, so a `decimal` or `PreciseNumber` vector +converts at its own precision rather than through `double`. + +Two things the vector surface does differently, both deliberate. It carries **no `Vector0Guards`**: +components are signed by construction, a position with a negative X is ordinary, and the V0 +non-negativity rule must not leak into the vectors. And `In(unit)` returns a **tuple of components**, +`(T X, T Y, T Z)`, not the vector type — it cannot return the vector type, because the result is no +longer in base units and a `Position3D` that is not in base units would be a lie in the type system. +A dimension with an offset unit gets no vector unit surface at all; see SEM010. + All generated types are generic over a numeric storage type: `where T : struct, INumber`. ### Resolved design decisions @@ -483,6 +498,7 @@ var converted = sourceString.As(); - **SEM007** — a metadata file could not be parsed. Replaces the base generator's `CONV001` in category `SourceGenerator`, and covers the path that used to swallow the exception, where a malformed `units.json` silently produced factories with no scale factor. - **SEM008** — a relationship's declared result does not follow from the dimensions of its operands, or its value is signed and the declared result is a magnitude. The check comes from `Semantics.Vocabulary`, shared with the C++ projection; before that this side checked the names (SEM001) and the forms (SEM003) and then emitted the operator, so `Sensitivity * Pressure -> ElectricPotential` shipped as a working C# operator computing the wrong physics — which is what found that bug, and it is now fixed. **No operator is generated** for a refused relationship, in any of the directions C# spells a product in — that followed from making the vocabulary drive emission rather than only check it, and the removal is documented in `docs/migration-guide-5.0.md`. Suppressed in `Semantics.Quantities.csproj` because ktsu.Sdk builds warnings as errors and the four below are outstanding; `UnkeepableRelationshipTests` pins the set, and asserts that none of them is in the compiled surface, so a fifth fails there rather than disappearing into the suppression. - **SEM009**: a factor's `value` in `conversions.json` is neither a decimal literal nor a fraction of two with a non-zero denominator, or a `double` cannot hold it (a literal, operand, or quotient beyond its range, or a non-zero value that rounds to zero). An error, and no constant is generated for it, because every unit using the factor would otherwise fail to compile far from the metadata line that caused it, or convert with a wrong factor. + - **SEM010**: a dimension declares both a vector form and a unit converting with an additive offset. Adding 273.15 to each component of a displacement is not a unit change, so the whole per-unit surface — every `From{Unit}` factory and the `In(unit)` reader — is withheld from that dimension's vector types rather than emitted quietly wrong. Withheld as a whole rather than per-unit, because `In` takes the dimension's `I{Dimension}Unit` and would accept the offset unit at runtime even if only its factory were skipped. The scalar forms are unaffected: the offset is correct for a V0 or V1. Defensive — no dimension declaring a vector form has an offset unit today, and `TheRealMetadataReportsNothingUnexpected` is what keeps that true. - Descriptors are allocated from `SemanticsDiagnostics`, which is the one place to add a new one. `AnalyzerReleaseTrackingTests` fails if the identifier is missing from `AnalyzerReleases.Unshipped.md`, so RS2008 no longer surfaces only after a push. - See `docs/physics-generator.md` for the full schema and an end-to-end "add a dimension" walk-through. 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 f178fde..e995629 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 @@ -41,6 +41,24 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(Acceleration2D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondSquared. + /// The X component, in MeterPerSecondSquared. + /// The Y component, in MeterPerSecondSquared. + /// A new storing the SI-base equivalent. + public static Acceleration2D FromMeterPerSecondSquared(T x, T y) => new() { X = x, Y = y }; + + /// Creates a from components in StandardGravity. + /// The X component, in StandardGravity. + /// The Y component, in StandardGravity. + /// A new storing the SI-base equivalent. + public static Acceleration2D FromStandardGravity(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Y = (y * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.IAccelerationUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 d8cbd59..2d564c7 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 @@ -47,6 +47,26 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(Acceleration3D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondSquared. + /// The X component, in MeterPerSecondSquared. + /// The Y component, in MeterPerSecondSquared. + /// The Z component, in MeterPerSecondSquared. + /// A new storing the SI-base equivalent. + public static Acceleration3D FromMeterPerSecondSquared(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in StandardGravity. + /// The X component, in StandardGravity. + /// The Y component, in StandardGravity. + /// The Z component, in StandardGravity. + /// A new storing the SI-base equivalent. + public static Acceleration3D FromStandardGravity(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Y = (y * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Z = (z * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAccelerationUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 d8824d7..bb5c16e 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 @@ -53,6 +53,28 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(Acceleration4D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondSquared. + /// The X component, in MeterPerSecondSquared. + /// The Y component, in MeterPerSecondSquared. + /// The Z component, in MeterPerSecondSquared. + /// The W component, in MeterPerSecondSquared. + /// A new storing the SI-base equivalent. + public static Acceleration4D FromMeterPerSecondSquared(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Creates a from components in StandardGravity. + /// The X component, in StandardGravity. + /// The Y component, in StandardGravity. + /// The Z component, in StandardGravity. + /// The W component, in StandardGravity. + /// A new storing the SI-base equivalent. + public static Acceleration4D FromStandardGravity(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Y = (y * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Z = (z * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), W = (w * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.IAccelerationUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// 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 dbb6ab1..852fd43 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AngularAccelerationMagnitude DistanceTo(AngularAcceleration3D other) => global::ktsu.Semantics.Quantities.AngularAccelerationMagnitude.Create(Distance(other)); + /// Creates a from components in RadianPerSecondSquared. + /// The X component, in RadianPerSecondSquared. + /// The Y component, in RadianPerSecondSquared. + /// The Z component, in RadianPerSecondSquared. + /// A new storing the SI-base equivalent. + public static AngularAcceleration3D FromRadianPerSecondSquared(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAngularAccelerationUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 c610ec7..15e834f 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 @@ -47,6 +47,47 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Angle DistanceTo(AngularDisplacement3D other) => global::ktsu.Semantics.Quantities.Angle.Create(Distance(other)); + /// Creates a from components in Radian. + /// The X component, in Radian. + /// The Y component, in Radian. + /// The Z component, in Radian. + /// A new storing the SI-base equivalent. + public static AngularDisplacement3D FromRadian(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Degree. + /// The X component, in Degree. + /// The Y component, in Degree. + /// The Z component, in Degree. + /// A new storing the SI-base equivalent. + public static AngularDisplacement3D FromDegree(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.DegreeToRadians), Y = (y * Units.ConversionConstants.Values.DegreeToRadians), Z = (z * Units.ConversionConstants.Values.DegreeToRadians) }; + + /// Creates a from components in Gradian. + /// The X component, in Gradian. + /// The Y component, in Gradian. + /// The Z component, in Gradian. + /// A new storing the SI-base equivalent. + public static AngularDisplacement3D FromGradian(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.GradianToRadians), Y = (y * Units.ConversionConstants.Values.GradianToRadians), Z = (z * Units.ConversionConstants.Values.GradianToRadians) }; + + /// Creates a from components in Revolution. + /// The X component, in Revolution. + /// The Y component, in Revolution. + /// The Z component, in Revolution. + /// A new storing the SI-base equivalent. + public static AngularDisplacement3D FromRevolution(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.RevolutionToRadians), Y = (y * Units.ConversionConstants.Values.RevolutionToRadians), Z = (z * Units.ConversionConstants.Values.RevolutionToRadians) }; + + /// Creates a from components in Milliradian. + /// The X component, in Milliradian. + /// The Y component, in Milliradian. + /// The Z component, in Milliradian. + /// A new storing the SI-base equivalent. + public static AngularDisplacement3D FromMilliradian(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli), Z = (z * MetricMagnitudes.Values.Milli) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAngularDisplacementUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 1cf08da..71aba58 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AngularJerkMagnitude DistanceTo(AngularJerk3D other) => global::ktsu.Semantics.Quantities.AngularJerkMagnitude.Create(Distance(other)); + /// Creates a from components in RadianPerSecondCubed. + /// The X component, in RadianPerSecondCubed. + /// The Y component, in RadianPerSecondCubed. + /// The Z component, in RadianPerSecondCubed. + /// A new storing the SI-base equivalent. + public static AngularJerk3D FromRadianPerSecondCubed(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAngularJerkUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 ba85d06..3c22ee5 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AngularMomentumMagnitude DistanceTo(AngularMomentum3D other) => global::ktsu.Semantics.Quantities.AngularMomentumMagnitude.Create(Distance(other)); + /// Creates a from components in KilogramMeterSquaredPerSecond. + /// The X component, in KilogramMeterSquaredPerSecond. + /// The Y component, in KilogramMeterSquaredPerSecond. + /// The Z component, in KilogramMeterSquaredPerSecond. + /// A new storing the SI-base equivalent. + public static AngularMomentum3D FromKilogramMeterSquaredPerSecond(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAngularMomentumUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 6c57142..4bfb30b 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 @@ -47,6 +47,26 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AngularSpeed DistanceTo(AngularVelocity3D other) => global::ktsu.Semantics.Quantities.AngularSpeed.Create(Distance(other)); + /// Creates a from components in RadianPerSecond. + /// The X component, in RadianPerSecond. + /// The Y component, in RadianPerSecond. + /// The Z component, in RadianPerSecond. + /// A new storing the SI-base equivalent. + public static AngularVelocity3D FromRadianPerSecond(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in RevolutionPerMinute. + /// The X component, in RevolutionPerMinute. + /// The Y component, in RevolutionPerMinute. + /// The Z component, in RevolutionPerMinute. + /// A new storing the SI-base equivalent. + public static AngularVelocity3D FromRevolutionPerMinute(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.RevolutionPerMinuteToRadianPerSecond), Y = (y * Units.ConversionConstants.Values.RevolutionPerMinuteToRadianPerSecond), Z = (z * Units.ConversionConstants.Values.RevolutionPerMinuteToRadianPerSecond) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAngularVelocityUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 bffb997..97bde74 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 @@ -47,6 +47,33 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.CurrentMagnitude DistanceTo(Current3D other) => global::ktsu.Semantics.Quantities.CurrentMagnitude.Create(Distance(other)); + /// Creates a from components in Ampere. + /// The X component, in Ampere. + /// The Y component, in Ampere. + /// The Z component, in Ampere. + /// A new storing the SI-base equivalent. + public static Current3D FromAmpere(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Milliampere. + /// The X component, in Milliampere. + /// The Y component, in Milliampere. + /// The Z component, in Milliampere. + /// A new storing the SI-base equivalent. + public static Current3D FromMilliampere(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli), Z = (z * MetricMagnitudes.Values.Milli) }; + + /// Creates a from components in Kiloampere. + /// The X component, in Kiloampere. + /// The Y component, in Kiloampere. + /// The Z component, in Kiloampere. + /// A new storing the SI-base equivalent. + public static Current3D FromKiloampere(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IElectricCurrentUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 61d43dc..7022ee1 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 @@ -41,6 +41,84 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Length DistanceTo(Displacement2D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Creates a from components in Meter. + /// The X component, in Meter. + /// The Y component, in Meter. + /// A new storing the SI-base equivalent. + public static Displacement2D FromMeter(T x, T y) => new() { X = x, Y = y }; + + /// Creates a from components in Kilometer. + /// The X component, in Kilometer. + /// The Y component, in Kilometer. + /// A new storing the SI-base equivalent. + public static Displacement2D FromKilometer(T x, T y) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Centimeter. + /// The X component, in Centimeter. + /// The Y component, in Centimeter. + /// A new storing the SI-base equivalent. + public static Displacement2D FromCentimeter(T x, T y) => new() { X = (x * MetricMagnitudes.Values.Centi), Y = (y * MetricMagnitudes.Values.Centi) }; + + /// Creates a from components in Millimeter. + /// The X component, in Millimeter. + /// The Y component, in Millimeter. + /// A new storing the SI-base equivalent. + public static Displacement2D FromMillimeter(T x, T y) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli) }; + + /// Creates a from components in Micrometer. + /// The X component, in Micrometer. + /// The Y component, in Micrometer. + /// A new storing the SI-base equivalent. + public static Displacement2D FromMicrometer(T x, T y) => new() { X = (x * MetricMagnitudes.Values.Micro), Y = (y * MetricMagnitudes.Values.Micro) }; + + /// Creates a from components in Nanometer. + /// The X component, in Nanometer. + /// The Y component, in Nanometer. + /// A new storing the SI-base equivalent. + public static Displacement2D FromNanometer(T x, T y) => new() { X = (x * MetricMagnitudes.Values.Nano), Y = (y * MetricMagnitudes.Values.Nano) }; + + /// Creates a from components in Angstrom. + /// The X component, in Angstrom. + /// The Y component, in Angstrom. + /// A new storing the SI-base equivalent. + public static Displacement2D FromAngstrom(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.AngstromToMeters), Y = (y * Units.ConversionConstants.Values.AngstromToMeters) }; + + /// Creates a from components in Foot. + /// The X component, in Foot. + /// The Y component, in Foot. + /// A new storing the SI-base equivalent. + public static Displacement2D FromFoot(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.FeetToMeters), Y = (y * Units.ConversionConstants.Values.FeetToMeters) }; + + /// Creates a from components in Inch. + /// The X component, in Inch. + /// The Y component, in Inch. + /// A new storing the SI-base equivalent. + public static Displacement2D FromInch(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.InchesToMeters), Y = (y * Units.ConversionConstants.Values.InchesToMeters) }; + + /// Creates a from components in Yard. + /// The X component, in Yard. + /// The Y component, in Yard. + /// A new storing the SI-base equivalent. + public static Displacement2D FromYard(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.YardToMeters), Y = (y * Units.ConversionConstants.Values.YardToMeters) }; + + /// Creates a from components in Mile. + /// The X component, in Mile. + /// The Y component, in Mile. + /// A new storing the SI-base equivalent. + public static Displacement2D FromMile(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.MileToMeters), Y = (y * Units.ConversionConstants.Values.MileToMeters) }; + + /// Creates a from components in NauticalMile. + /// The X component, in NauticalMile. + /// The Y component, in NauticalMile. + /// A new storing the SI-base equivalent. + public static Displacement2D FromNauticalMile(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.NauticalMileToMeters), Y = (y * Units.ConversionConstants.Values.NauticalMileToMeters) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.ILengthUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 e2a2fb4..8d2a367 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 @@ -47,6 +47,96 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Length DistanceTo(Displacement3D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Creates a from components in Meter. + /// The X component, in Meter. + /// The Y component, in Meter. + /// The Z component, in Meter. + /// A new storing the SI-base equivalent. + public static Displacement3D FromMeter(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Kilometer. + /// The X component, in Kilometer. + /// The Y component, in Kilometer. + /// The Z component, in Kilometer. + /// A new storing the SI-base equivalent. + public static Displacement3D FromKilometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Centimeter. + /// The X component, in Centimeter. + /// The Y component, in Centimeter. + /// The Z component, in Centimeter. + /// A new storing the SI-base equivalent. + public static Displacement3D FromCentimeter(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Centi), Y = (y * MetricMagnitudes.Values.Centi), Z = (z * MetricMagnitudes.Values.Centi) }; + + /// Creates a from components in Millimeter. + /// The X component, in Millimeter. + /// The Y component, in Millimeter. + /// The Z component, in Millimeter. + /// A new storing the SI-base equivalent. + public static Displacement3D FromMillimeter(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli), Z = (z * MetricMagnitudes.Values.Milli) }; + + /// Creates a from components in Micrometer. + /// The X component, in Micrometer. + /// The Y component, in Micrometer. + /// The Z component, in Micrometer. + /// A new storing the SI-base equivalent. + public static Displacement3D FromMicrometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Micro), Y = (y * MetricMagnitudes.Values.Micro), Z = (z * MetricMagnitudes.Values.Micro) }; + + /// Creates a from components in Nanometer. + /// The X component, in Nanometer. + /// The Y component, in Nanometer. + /// The Z component, in Nanometer. + /// A new storing the SI-base equivalent. + public static Displacement3D FromNanometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Nano), Y = (y * MetricMagnitudes.Values.Nano), Z = (z * MetricMagnitudes.Values.Nano) }; + + /// Creates a from components in Angstrom. + /// The X component, in Angstrom. + /// The Y component, in Angstrom. + /// The Z component, in Angstrom. + /// A new storing the SI-base equivalent. + public static Displacement3D FromAngstrom(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.AngstromToMeters), Y = (y * Units.ConversionConstants.Values.AngstromToMeters), Z = (z * Units.ConversionConstants.Values.AngstromToMeters) }; + + /// Creates a from components in Foot. + /// The X component, in Foot. + /// The Y component, in Foot. + /// The Z component, in Foot. + /// A new storing the SI-base equivalent. + public static Displacement3D FromFoot(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.FeetToMeters), Y = (y * Units.ConversionConstants.Values.FeetToMeters), Z = (z * Units.ConversionConstants.Values.FeetToMeters) }; + + /// Creates a from components in Inch. + /// The X component, in Inch. + /// The Y component, in Inch. + /// The Z component, in Inch. + /// A new storing the SI-base equivalent. + public static Displacement3D FromInch(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.InchesToMeters), Y = (y * Units.ConversionConstants.Values.InchesToMeters), Z = (z * Units.ConversionConstants.Values.InchesToMeters) }; + + /// Creates a from components in Yard. + /// The X component, in Yard. + /// The Y component, in Yard. + /// The Z component, in Yard. + /// A new storing the SI-base equivalent. + public static Displacement3D FromYard(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.YardToMeters), Y = (y * Units.ConversionConstants.Values.YardToMeters), Z = (z * Units.ConversionConstants.Values.YardToMeters) }; + + /// Creates a from components in Mile. + /// The X component, in Mile. + /// The Y component, in Mile. + /// The Z component, in Mile. + /// A new storing the SI-base equivalent. + public static Displacement3D FromMile(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.MileToMeters), Y = (y * Units.ConversionConstants.Values.MileToMeters), Z = (z * Units.ConversionConstants.Values.MileToMeters) }; + + /// Creates a from components in NauticalMile. + /// The X component, in NauticalMile. + /// The Y component, in NauticalMile. + /// The Z component, in NauticalMile. + /// A new storing the SI-base equivalent. + public static Displacement3D FromNauticalMile(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.NauticalMileToMeters), Y = (y * Units.ConversionConstants.Values.NauticalMileToMeters), Z = (z * Units.ConversionConstants.Values.NauticalMileToMeters) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ILengthUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 a65d7b1..8677193 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 @@ -53,6 +53,108 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Length DistanceTo(Displacement4D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Creates a from components in Meter. + /// The X component, in Meter. + /// The Y component, in Meter. + /// The Z component, in Meter. + /// The W component, in Meter. + /// A new storing the SI-base equivalent. + public static Displacement4D FromMeter(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Creates a from components in Kilometer. + /// The X component, in Kilometer. + /// The Y component, in Kilometer. + /// The Z component, in Kilometer. + /// The W component, in Kilometer. + /// A new storing the SI-base equivalent. + public static Displacement4D FromKilometer(T x, T y, T z, T w) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo), W = (w * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Centimeter. + /// The X component, in Centimeter. + /// The Y component, in Centimeter. + /// The Z component, in Centimeter. + /// The W component, in Centimeter. + /// A new storing the SI-base equivalent. + public static Displacement4D FromCentimeter(T x, T y, T z, T w) => new() { X = (x * MetricMagnitudes.Values.Centi), Y = (y * MetricMagnitudes.Values.Centi), Z = (z * MetricMagnitudes.Values.Centi), W = (w * MetricMagnitudes.Values.Centi) }; + + /// Creates a from components in Millimeter. + /// The X component, in Millimeter. + /// The Y component, in Millimeter. + /// The Z component, in Millimeter. + /// The W component, in Millimeter. + /// A new storing the SI-base equivalent. + public static Displacement4D FromMillimeter(T x, T y, T z, T w) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli), Z = (z * MetricMagnitudes.Values.Milli), W = (w * MetricMagnitudes.Values.Milli) }; + + /// Creates a from components in Micrometer. + /// The X component, in Micrometer. + /// The Y component, in Micrometer. + /// The Z component, in Micrometer. + /// The W component, in Micrometer. + /// A new storing the SI-base equivalent. + public static Displacement4D FromMicrometer(T x, T y, T z, T w) => new() { X = (x * MetricMagnitudes.Values.Micro), Y = (y * MetricMagnitudes.Values.Micro), Z = (z * MetricMagnitudes.Values.Micro), W = (w * MetricMagnitudes.Values.Micro) }; + + /// Creates a from components in Nanometer. + /// The X component, in Nanometer. + /// The Y component, in Nanometer. + /// The Z component, in Nanometer. + /// The W component, in Nanometer. + /// A new storing the SI-base equivalent. + public static Displacement4D FromNanometer(T x, T y, T z, T w) => new() { X = (x * MetricMagnitudes.Values.Nano), Y = (y * MetricMagnitudes.Values.Nano), Z = (z * MetricMagnitudes.Values.Nano), W = (w * MetricMagnitudes.Values.Nano) }; + + /// Creates a from components in Angstrom. + /// The X component, in Angstrom. + /// The Y component, in Angstrom. + /// The Z component, in Angstrom. + /// The W component, in Angstrom. + /// A new storing the SI-base equivalent. + public static Displacement4D FromAngstrom(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.AngstromToMeters), Y = (y * Units.ConversionConstants.Values.AngstromToMeters), Z = (z * Units.ConversionConstants.Values.AngstromToMeters), W = (w * Units.ConversionConstants.Values.AngstromToMeters) }; + + /// Creates a from components in Foot. + /// The X component, in Foot. + /// The Y component, in Foot. + /// The Z component, in Foot. + /// The W component, in Foot. + /// A new storing the SI-base equivalent. + public static Displacement4D FromFoot(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.FeetToMeters), Y = (y * Units.ConversionConstants.Values.FeetToMeters), Z = (z * Units.ConversionConstants.Values.FeetToMeters), W = (w * Units.ConversionConstants.Values.FeetToMeters) }; + + /// Creates a from components in Inch. + /// The X component, in Inch. + /// The Y component, in Inch. + /// The Z component, in Inch. + /// The W component, in Inch. + /// A new storing the SI-base equivalent. + public static Displacement4D FromInch(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.InchesToMeters), Y = (y * Units.ConversionConstants.Values.InchesToMeters), Z = (z * Units.ConversionConstants.Values.InchesToMeters), W = (w * Units.ConversionConstants.Values.InchesToMeters) }; + + /// Creates a from components in Yard. + /// The X component, in Yard. + /// The Y component, in Yard. + /// The Z component, in Yard. + /// The W component, in Yard. + /// A new storing the SI-base equivalent. + public static Displacement4D FromYard(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.YardToMeters), Y = (y * Units.ConversionConstants.Values.YardToMeters), Z = (z * Units.ConversionConstants.Values.YardToMeters), W = (w * Units.ConversionConstants.Values.YardToMeters) }; + + /// Creates a from components in Mile. + /// The X component, in Mile. + /// The Y component, in Mile. + /// The Z component, in Mile. + /// The W component, in Mile. + /// A new storing the SI-base equivalent. + public static Displacement4D FromMile(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.MileToMeters), Y = (y * Units.ConversionConstants.Values.MileToMeters), Z = (z * Units.ConversionConstants.Values.MileToMeters), W = (w * Units.ConversionConstants.Values.MileToMeters) }; + + /// Creates a from components in NauticalMile. + /// The X component, in NauticalMile. + /// The Y component, in NauticalMile. + /// The Z component, in NauticalMile. + /// The W component, in NauticalMile. + /// A new storing the SI-base equivalent. + public static Displacement4D FromNauticalMile(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.NauticalMileToMeters), Y = (y * Units.ConversionConstants.Values.NauticalMileToMeters), Z = (z * Units.ConversionConstants.Values.NauticalMileToMeters), W = (w * Units.ConversionConstants.Values.NauticalMileToMeters) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.ILengthUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// 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 7ff6541..6e0f032 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 @@ -41,6 +41,18 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ElectricFieldMagnitude DistanceTo(ElectricField2D other) => global::ktsu.Semantics.Quantities.ElectricFieldMagnitude.Create(Distance(other)); + /// Creates a from components in VoltPerMeter. + /// The X component, in VoltPerMeter. + /// The Y component, in VoltPerMeter. + /// A new storing the SI-base equivalent. + public static ElectricField2D FromVoltPerMeter(T x, T y) => new() { X = x, Y = y }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.IElectricFieldUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 5990ee0..4786625 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ElectricFieldMagnitude DistanceTo(ElectricField3D other) => global::ktsu.Semantics.Quantities.ElectricFieldMagnitude.Create(Distance(other)); + /// Creates a from components in VoltPerMeter. + /// The X component, in VoltPerMeter. + /// The Y component, in VoltPerMeter. + /// The Z component, in VoltPerMeter. + /// A new storing the SI-base equivalent. + public static ElectricField3D FromVoltPerMeter(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IElectricFieldUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 01150a3..b7c3880 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 @@ -41,6 +41,36 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(Force2D other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Creates a from components in Newton. + /// The X component, in Newton. + /// The Y component, in Newton. + /// A new storing the SI-base equivalent. + public static Force2D FromNewton(T x, T y) => new() { X = x, Y = y }; + + /// Creates a from components in Kilonewton. + /// The X component, in Kilonewton. + /// The Y component, in Kilonewton. + /// A new storing the SI-base equivalent. + public static Force2D FromKilonewton(T x, T y) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Dyne. + /// The X component, in Dyne. + /// The Y component, in Dyne. + /// A new storing the SI-base equivalent. + public static Force2D FromDyne(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.DyneToNewtons), Y = (y * Units.ConversionConstants.Values.DyneToNewtons) }; + + /// Creates a from components in PoundForce. + /// The X component, in PoundForce. + /// The Y component, in PoundForce. + /// A new storing the SI-base equivalent. + public static Force2D FromPoundForce(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.PoundForceToNewtons), Y = (y * Units.ConversionConstants.Values.PoundForceToNewtons) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.IForceUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 bbf01a0..06f2fe5 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 @@ -47,6 +47,40 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(Force3D other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Creates a from components in Newton. + /// The X component, in Newton. + /// The Y component, in Newton. + /// The Z component, in Newton. + /// A new storing the SI-base equivalent. + public static Force3D FromNewton(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Kilonewton. + /// The X component, in Kilonewton. + /// The Y component, in Kilonewton. + /// The Z component, in Kilonewton. + /// A new storing the SI-base equivalent. + public static Force3D FromKilonewton(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Dyne. + /// The X component, in Dyne. + /// The Y component, in Dyne. + /// The Z component, in Dyne. + /// A new storing the SI-base equivalent. + public static Force3D FromDyne(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.DyneToNewtons), Y = (y * Units.ConversionConstants.Values.DyneToNewtons), Z = (z * Units.ConversionConstants.Values.DyneToNewtons) }; + + /// Creates a from components in PoundForce. + /// The X component, in PoundForce. + /// The Y component, in PoundForce. + /// The Z component, in PoundForce. + /// A new storing the SI-base equivalent. + public static Force3D FromPoundForce(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.PoundForceToNewtons), Y = (y * Units.ConversionConstants.Values.PoundForceToNewtons), Z = (z * Units.ConversionConstants.Values.PoundForceToNewtons) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IForceUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 94dbfd7..451e373 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 @@ -53,6 +53,44 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(Force4D other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Creates a from components in Newton. + /// The X component, in Newton. + /// The Y component, in Newton. + /// The Z component, in Newton. + /// The W component, in Newton. + /// A new storing the SI-base equivalent. + public static Force4D FromNewton(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Creates a from components in Kilonewton. + /// The X component, in Kilonewton. + /// The Y component, in Kilonewton. + /// The Z component, in Kilonewton. + /// The W component, in Kilonewton. + /// A new storing the SI-base equivalent. + public static Force4D FromKilonewton(T x, T y, T z, T w) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo), W = (w * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Dyne. + /// The X component, in Dyne. + /// The Y component, in Dyne. + /// The Z component, in Dyne. + /// The W component, in Dyne. + /// A new storing the SI-base equivalent. + public static Force4D FromDyne(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.DyneToNewtons), Y = (y * Units.ConversionConstants.Values.DyneToNewtons), Z = (z * Units.ConversionConstants.Values.DyneToNewtons), W = (w * Units.ConversionConstants.Values.DyneToNewtons) }; + + /// Creates a from components in PoundForce. + /// The X component, in PoundForce. + /// The Y component, in PoundForce. + /// The Z component, in PoundForce. + /// The W component, in PoundForce. + /// A new storing the SI-base equivalent. + public static Force4D FromPoundForce(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.PoundForceToNewtons), Y = (y * Units.ConversionConstants.Values.PoundForceToNewtons), Z = (z * Units.ConversionConstants.Values.PoundForceToNewtons), W = (w * Units.ConversionConstants.Values.PoundForceToNewtons) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.IForceUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// 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 49faa20..3822e3e 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 @@ -47,6 +47,26 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.AccelerationMagnitude DistanceTo(GravitationalField3D other) => global::ktsu.Semantics.Quantities.AccelerationMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondSquared. + /// The X component, in MeterPerSecondSquared. + /// The Y component, in MeterPerSecondSquared. + /// The Z component, in MeterPerSecondSquared. + /// A new storing the SI-base equivalent. + public static GravitationalField3D FromMeterPerSecondSquared(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in StandardGravity. + /// The X component, in StandardGravity. + /// The Y component, in StandardGravity. + /// The Z component, in StandardGravity. + /// A new storing the SI-base equivalent. + public static GravitationalField3D FromStandardGravity(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Y = (y * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared), Z = (z * Units.ConversionConstants.Values.StandardGravityToMeterPerSecondSquared) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IAccelerationUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 864fc4a..f8fba65 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 @@ -41,6 +41,18 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.JerkMagnitude DistanceTo(Jerk2D other) => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondCubed. + /// The X component, in MeterPerSecondCubed. + /// The Y component, in MeterPerSecondCubed. + /// A new storing the SI-base equivalent. + public static Jerk2D FromMeterPerSecondCubed(T x, T y) => new() { X = x, Y = y }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.IJerkUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 b5b0796..ea63b1c 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.JerkMagnitude DistanceTo(Jerk3D other) => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondCubed. + /// The X component, in MeterPerSecondCubed. + /// The Y component, in MeterPerSecondCubed. + /// The Z component, in MeterPerSecondCubed. + /// A new storing the SI-base equivalent. + public static Jerk3D FromMeterPerSecondCubed(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IJerkUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 593e8b0..0fce365 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 @@ -53,6 +53,20 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.JerkMagnitude DistanceTo(Jerk4D other) => global::ktsu.Semantics.Quantities.JerkMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondCubed. + /// The X component, in MeterPerSecondCubed. + /// The Y component, in MeterPerSecondCubed. + /// The Z component, in MeterPerSecondCubed. + /// The W component, in MeterPerSecondCubed. + /// A new storing the SI-base equivalent. + public static Jerk4D FromMeterPerSecondCubed(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.IJerkUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// 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 bcdb287..712ad5e 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 @@ -47,6 +47,26 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.MagneticFluxDensityMagnitude DistanceTo(MagneticFluxDensity3D other) => global::ktsu.Semantics.Quantities.MagneticFluxDensityMagnitude.Create(Distance(other)); + /// Creates a from components in Tesla. + /// The X component, in Tesla. + /// The Y component, in Tesla. + /// The Z component, in Tesla. + /// A new storing the SI-base equivalent. + public static MagneticFluxDensity3D FromTesla(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Gauss. + /// The X component, in Gauss. + /// The Y component, in Gauss. + /// The Z component, in Gauss. + /// A new storing the SI-base equivalent. + public static MagneticFluxDensity3D FromGauss(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.GaussToTesla), Y = (y * Units.ConversionConstants.Values.GaussToTesla), Z = (z * Units.ConversionConstants.Values.GaussToTesla) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IMagneticFluxDensityUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 e02a940..bb089b3 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 @@ -41,6 +41,18 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.MomentumMagnitude DistanceTo(Momentum2D other) => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Distance(other)); + /// Creates a from components in NewtonSecond. + /// The X component, in NewtonSecond. + /// The Y component, in NewtonSecond. + /// A new storing the SI-base equivalent. + public static Momentum2D FromNewtonSecond(T x, T y) => new() { X = x, Y = y }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.IMomentumUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 79fbe6f..6f45cf0 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.MomentumMagnitude DistanceTo(Momentum3D other) => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Distance(other)); + /// Creates a from components in NewtonSecond. + /// The X component, in NewtonSecond. + /// The Y component, in NewtonSecond. + /// The Z component, in NewtonSecond. + /// A new storing the SI-base equivalent. + public static Momentum3D FromNewtonSecond(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IMomentumUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 d3c2c5d..96b4699 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 @@ -53,6 +53,20 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.MomentumMagnitude DistanceTo(Momentum4D other) => global::ktsu.Semantics.Quantities.MomentumMagnitude.Create(Distance(other)); + /// Creates a from components in NewtonSecond. + /// The X component, in NewtonSecond. + /// The Y component, in NewtonSecond. + /// The Z component, in NewtonSecond. + /// The W component, in NewtonSecond. + /// A new storing the SI-base equivalent. + public static Momentum4D FromNewtonSecond(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.IMomentumUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// 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 4d2ccc4..25f4b68 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 @@ -47,6 +47,96 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Length DistanceTo(Position3D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Creates a from components in Meter. + /// The X component, in Meter. + /// The Y component, in Meter. + /// The Z component, in Meter. + /// A new storing the SI-base equivalent. + public static Position3D FromMeter(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Kilometer. + /// The X component, in Kilometer. + /// The Y component, in Kilometer. + /// The Z component, in Kilometer. + /// A new storing the SI-base equivalent. + public static Position3D FromKilometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Centimeter. + /// The X component, in Centimeter. + /// The Y component, in Centimeter. + /// The Z component, in Centimeter. + /// A new storing the SI-base equivalent. + public static Position3D FromCentimeter(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Centi), Y = (y * MetricMagnitudes.Values.Centi), Z = (z * MetricMagnitudes.Values.Centi) }; + + /// Creates a from components in Millimeter. + /// The X component, in Millimeter. + /// The Y component, in Millimeter. + /// The Z component, in Millimeter. + /// A new storing the SI-base equivalent. + public static Position3D FromMillimeter(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli), Z = (z * MetricMagnitudes.Values.Milli) }; + + /// Creates a from components in Micrometer. + /// The X component, in Micrometer. + /// The Y component, in Micrometer. + /// The Z component, in Micrometer. + /// A new storing the SI-base equivalent. + public static Position3D FromMicrometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Micro), Y = (y * MetricMagnitudes.Values.Micro), Z = (z * MetricMagnitudes.Values.Micro) }; + + /// Creates a from components in Nanometer. + /// The X component, in Nanometer. + /// The Y component, in Nanometer. + /// The Z component, in Nanometer. + /// A new storing the SI-base equivalent. + public static Position3D FromNanometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Nano), Y = (y * MetricMagnitudes.Values.Nano), Z = (z * MetricMagnitudes.Values.Nano) }; + + /// Creates a from components in Angstrom. + /// The X component, in Angstrom. + /// The Y component, in Angstrom. + /// The Z component, in Angstrom. + /// A new storing the SI-base equivalent. + public static Position3D FromAngstrom(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.AngstromToMeters), Y = (y * Units.ConversionConstants.Values.AngstromToMeters), Z = (z * Units.ConversionConstants.Values.AngstromToMeters) }; + + /// Creates a from components in Foot. + /// The X component, in Foot. + /// The Y component, in Foot. + /// The Z component, in Foot. + /// A new storing the SI-base equivalent. + public static Position3D FromFoot(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.FeetToMeters), Y = (y * Units.ConversionConstants.Values.FeetToMeters), Z = (z * Units.ConversionConstants.Values.FeetToMeters) }; + + /// Creates a from components in Inch. + /// The X component, in Inch. + /// The Y component, in Inch. + /// The Z component, in Inch. + /// A new storing the SI-base equivalent. + public static Position3D FromInch(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.InchesToMeters), Y = (y * Units.ConversionConstants.Values.InchesToMeters), Z = (z * Units.ConversionConstants.Values.InchesToMeters) }; + + /// Creates a from components in Yard. + /// The X component, in Yard. + /// The Y component, in Yard. + /// The Z component, in Yard. + /// A new storing the SI-base equivalent. + public static Position3D FromYard(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.YardToMeters), Y = (y * Units.ConversionConstants.Values.YardToMeters), Z = (z * Units.ConversionConstants.Values.YardToMeters) }; + + /// Creates a from components in Mile. + /// The X component, in Mile. + /// The Y component, in Mile. + /// The Z component, in Mile. + /// A new storing the SI-base equivalent. + public static Position3D FromMile(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.MileToMeters), Y = (y * Units.ConversionConstants.Values.MileToMeters), Z = (z * Units.ConversionConstants.Values.MileToMeters) }; + + /// Creates a from components in NauticalMile. + /// The X component, in NauticalMile. + /// The Y component, in NauticalMile. + /// The Z component, in NauticalMile. + /// A new storing the SI-base equivalent. + public static Position3D FromNauticalMile(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.NauticalMileToMeters), Y = (y * Units.ConversionConstants.Values.NauticalMileToMeters), Z = (z * Units.ConversionConstants.Values.NauticalMileToMeters) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ILengthUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 a5ca5bb..55f9a0b 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 @@ -41,6 +41,18 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.SnapMagnitude DistanceTo(Snap2D other) => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondQuartic. + /// The X component, in MeterPerSecondQuartic. + /// The Y component, in MeterPerSecondQuartic. + /// A new storing the SI-base equivalent. + public static Snap2D FromMeterPerSecondQuartic(T x, T y) => new() { X = x, Y = y }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.ISnapUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 af6deee..63d870a 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 @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.SnapMagnitude DistanceTo(Snap3D other) => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondQuartic. + /// The X component, in MeterPerSecondQuartic. + /// The Y component, in MeterPerSecondQuartic. + /// The Z component, in MeterPerSecondQuartic. + /// A new storing the SI-base equivalent. + public static Snap3D FromMeterPerSecondQuartic(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ISnapUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 a42f879..67bd5d3 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 @@ -53,6 +53,20 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.SnapMagnitude DistanceTo(Snap4D other) => global::ktsu.Semantics.Quantities.SnapMagnitude.Create(Distance(other)); + /// Creates a from components in MeterPerSecondQuartic. + /// The X component, in MeterPerSecondQuartic. + /// The Y component, in MeterPerSecondQuartic. + /// The Z component, in MeterPerSecondQuartic. + /// The W component, in MeterPerSecondQuartic. + /// A new storing the SI-base equivalent. + public static Snap4D FromMeterPerSecondQuartic(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.ISnapUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SpecificAngularMomentum3D.g.cs b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SpecificAngularMomentum3D.g.cs index 483a3c1..aab3c42 100644 --- a/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SpecificAngularMomentum3D.g.cs +++ b/Semantics.Quantities/Generated/Semantics.SourceGenerators/Semantics.SourceGenerators.QuantitiesGenerator/SpecificAngularMomentum3D.g.cs @@ -47,6 +47,19 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.SpecificAngularMomentumMagnitude DistanceTo(SpecificAngularMomentum3D other) => global::ktsu.Semantics.Quantities.SpecificAngularMomentumMagnitude.Create(Distance(other)); + /// Creates a from components in SquareMeterPerSecond. + /// The X component, in SquareMeterPerSecond. + /// The Y component, in SquareMeterPerSecond. + /// The Z component, in SquareMeterPerSecond. + /// A new storing the SI-base equivalent. + public static SpecificAngularMomentum3D FromSquareMeterPerSecond(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ISpecificAngularMomentumUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 8277cd4..bedd85b 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 @@ -47,6 +47,40 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(ThrustVector other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Creates a from components in Newton. + /// The X component, in Newton. + /// The Y component, in Newton. + /// The Z component, in Newton. + /// A new storing the SI-base equivalent. + public static ThrustVector FromNewton(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Kilonewton. + /// The X component, in Kilonewton. + /// The Y component, in Kilonewton. + /// The Z component, in Kilonewton. + /// A new storing the SI-base equivalent. + public static ThrustVector FromKilonewton(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Dyne. + /// The X component, in Dyne. + /// The Y component, in Dyne. + /// The Z component, in Dyne. + /// A new storing the SI-base equivalent. + public static ThrustVector FromDyne(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.DyneToNewtons), Y = (y * Units.ConversionConstants.Values.DyneToNewtons), Z = (z * Units.ConversionConstants.Values.DyneToNewtons) }; + + /// Creates a from components in PoundForce. + /// The X component, in PoundForce. + /// The Y component, in PoundForce. + /// The Z component, in PoundForce. + /// A new storing the SI-base equivalent. + public static ThrustVector FromPoundForce(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.PoundForceToNewtons), Y = (y * Units.ConversionConstants.Values.PoundForceToNewtons), Z = (z * Units.ConversionConstants.Values.PoundForceToNewtons) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IForceUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 f8c7178..20b025c 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 @@ -47,6 +47,26 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.TorqueMagnitude DistanceTo(Torque3D other) => global::ktsu.Semantics.Quantities.TorqueMagnitude.Create(Distance(other)); + /// Creates a from components in NewtonMeter. + /// The X component, in NewtonMeter. + /// The Y component, in NewtonMeter. + /// The Z component, in NewtonMeter. + /// A new storing the SI-base equivalent. + public static Torque3D FromNewtonMeter(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in PoundFoot. + /// The X component, in PoundFoot. + /// The Y component, in PoundFoot. + /// The Z component, in PoundFoot. + /// A new storing the SI-base equivalent. + public static Torque3D FromPoundFoot(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.PoundFootToNewtonMeters), Y = (y * Units.ConversionConstants.Values.PoundFootToNewtonMeters), Z = (z * Units.ConversionConstants.Values.PoundFootToNewtonMeters) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ITorqueUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 4327a1b..e8d4a19 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 @@ -47,6 +47,96 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Length DistanceTo(Translation3D other) => global::ktsu.Semantics.Quantities.Length.Create(Distance(other)); + /// Creates a from components in Meter. + /// The X component, in Meter. + /// The Y component, in Meter. + /// The Z component, in Meter. + /// A new storing the SI-base equivalent. + public static Translation3D FromMeter(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Kilometer. + /// The X component, in Kilometer. + /// The Y component, in Kilometer. + /// The Z component, in Kilometer. + /// A new storing the SI-base equivalent. + public static Translation3D FromKilometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Centimeter. + /// The X component, in Centimeter. + /// The Y component, in Centimeter. + /// The Z component, in Centimeter. + /// A new storing the SI-base equivalent. + public static Translation3D FromCentimeter(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Centi), Y = (y * MetricMagnitudes.Values.Centi), Z = (z * MetricMagnitudes.Values.Centi) }; + + /// Creates a from components in Millimeter. + /// The X component, in Millimeter. + /// The Y component, in Millimeter. + /// The Z component, in Millimeter. + /// A new storing the SI-base equivalent. + public static Translation3D FromMillimeter(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Milli), Y = (y * MetricMagnitudes.Values.Milli), Z = (z * MetricMagnitudes.Values.Milli) }; + + /// Creates a from components in Micrometer. + /// The X component, in Micrometer. + /// The Y component, in Micrometer. + /// The Z component, in Micrometer. + /// A new storing the SI-base equivalent. + public static Translation3D FromMicrometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Micro), Y = (y * MetricMagnitudes.Values.Micro), Z = (z * MetricMagnitudes.Values.Micro) }; + + /// Creates a from components in Nanometer. + /// The X component, in Nanometer. + /// The Y component, in Nanometer. + /// The Z component, in Nanometer. + /// A new storing the SI-base equivalent. + public static Translation3D FromNanometer(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Nano), Y = (y * MetricMagnitudes.Values.Nano), Z = (z * MetricMagnitudes.Values.Nano) }; + + /// Creates a from components in Angstrom. + /// The X component, in Angstrom. + /// The Y component, in Angstrom. + /// The Z component, in Angstrom. + /// A new storing the SI-base equivalent. + public static Translation3D FromAngstrom(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.AngstromToMeters), Y = (y * Units.ConversionConstants.Values.AngstromToMeters), Z = (z * Units.ConversionConstants.Values.AngstromToMeters) }; + + /// Creates a from components in Foot. + /// The X component, in Foot. + /// The Y component, in Foot. + /// The Z component, in Foot. + /// A new storing the SI-base equivalent. + public static Translation3D FromFoot(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.FeetToMeters), Y = (y * Units.ConversionConstants.Values.FeetToMeters), Z = (z * Units.ConversionConstants.Values.FeetToMeters) }; + + /// Creates a from components in Inch. + /// The X component, in Inch. + /// The Y component, in Inch. + /// The Z component, in Inch. + /// A new storing the SI-base equivalent. + public static Translation3D FromInch(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.InchesToMeters), Y = (y * Units.ConversionConstants.Values.InchesToMeters), Z = (z * Units.ConversionConstants.Values.InchesToMeters) }; + + /// Creates a from components in Yard. + /// The X component, in Yard. + /// The Y component, in Yard. + /// The Z component, in Yard. + /// A new storing the SI-base equivalent. + public static Translation3D FromYard(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.YardToMeters), Y = (y * Units.ConversionConstants.Values.YardToMeters), Z = (z * Units.ConversionConstants.Values.YardToMeters) }; + + /// Creates a from components in Mile. + /// The X component, in Mile. + /// The Y component, in Mile. + /// The Z component, in Mile. + /// A new storing the SI-base equivalent. + public static Translation3D FromMile(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.MileToMeters), Y = (y * Units.ConversionConstants.Values.MileToMeters), Z = (z * Units.ConversionConstants.Values.MileToMeters) }; + + /// Creates a from components in NauticalMile. + /// The X component, in NauticalMile. + /// The Y component, in NauticalMile. + /// The Z component, in NauticalMile. + /// A new storing the SI-base equivalent. + public static Translation3D FromNauticalMile(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.NauticalMileToMeters), Y = (y * Units.ConversionConstants.Values.NauticalMileToMeters), Z = (z * Units.ConversionConstants.Values.NauticalMileToMeters) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ILengthUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 acb71be..ab99cac 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 @@ -41,6 +41,42 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Speed DistanceTo(Velocity2D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); + /// Creates a from components in MeterPerSecond. + /// The X component, in MeterPerSecond. + /// The Y component, in MeterPerSecond. + /// A new storing the SI-base equivalent. + public static Velocity2D FromMeterPerSecond(T x, T y) => new() { X = x, Y = y }; + + /// Creates a from components in KilometerPerHour. + /// The X component, in KilometerPerHour. + /// The Y component, in KilometerPerHour. + /// A new storing the SI-base equivalent. + public static Velocity2D FromKilometerPerHour(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond) }; + + /// Creates a from components in MilePerHour. + /// The X component, in MilePerHour. + /// The Y component, in MilePerHour. + /// A new storing the SI-base equivalent. + public static Velocity2D FromMilePerHour(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond) }; + + /// Creates a from components in FootPerSecond. + /// The X component, in FootPerSecond. + /// The Y component, in FootPerSecond. + /// A new storing the SI-base equivalent. + public static Velocity2D FromFootPerSecond(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond) }; + + /// Creates a from components in Knot. + /// The X component, in Knot. + /// The Y component, in Knot. + /// A new storing the SI-base equivalent. + public static Velocity2D FromKnot(T x, T y) => new() { X = (x * Units.ConversionConstants.Values.KnotToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KnotToMeterPerSecond) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y) In(global::ktsu.Semantics.Quantities.IVelocityUnit unit) => (unit.FromBase(X), unit.FromBase(Y)); + /// 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 16bcfd7..c34e97f 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 @@ -47,6 +47,47 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Speed DistanceTo(Velocity3D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); + /// Creates a from components in MeterPerSecond. + /// The X component, in MeterPerSecond. + /// The Y component, in MeterPerSecond. + /// The Z component, in MeterPerSecond. + /// A new storing the SI-base equivalent. + public static Velocity3D FromMeterPerSecond(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in KilometerPerHour. + /// The X component, in KilometerPerHour. + /// The Y component, in KilometerPerHour. + /// The Z component, in KilometerPerHour. + /// A new storing the SI-base equivalent. + public static Velocity3D FromKilometerPerHour(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond) }; + + /// Creates a from components in MilePerHour. + /// The X component, in MilePerHour. + /// The Y component, in MilePerHour. + /// The Z component, in MilePerHour. + /// A new storing the SI-base equivalent. + public static Velocity3D FromMilePerHour(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond) }; + + /// Creates a from components in FootPerSecond. + /// The X component, in FootPerSecond. + /// The Y component, in FootPerSecond. + /// The Z component, in FootPerSecond. + /// A new storing the SI-base equivalent. + public static Velocity3D FromFootPerSecond(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond) }; + + /// Creates a from components in Knot. + /// The X component, in Knot. + /// The Y component, in Knot. + /// The Z component, in Knot. + /// A new storing the SI-base equivalent. + public static Velocity3D FromKnot(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.KnotToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KnotToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.KnotToMeterPerSecond) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IVelocityUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 7035ea8..dc31821 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 @@ -53,6 +53,52 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Speed DistanceTo(Velocity4D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); + /// Creates a from components in MeterPerSecond. + /// The X component, in MeterPerSecond. + /// The Y component, in MeterPerSecond. + /// The Z component, in MeterPerSecond. + /// The W component, in MeterPerSecond. + /// A new storing the SI-base equivalent. + public static Velocity4D FromMeterPerSecond(T x, T y, T z, T w) => new() { X = x, Y = y, Z = z, W = w }; + + /// Creates a from components in KilometerPerHour. + /// The X component, in KilometerPerHour. + /// The Y component, in KilometerPerHour. + /// The Z component, in KilometerPerHour. + /// The W component, in KilometerPerHour. + /// A new storing the SI-base equivalent. + public static Velocity4D FromKilometerPerHour(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), W = (w * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond) }; + + /// Creates a from components in MilePerHour. + /// The X component, in MilePerHour. + /// The Y component, in MilePerHour. + /// The Z component, in MilePerHour. + /// The W component, in MilePerHour. + /// A new storing the SI-base equivalent. + public static Velocity4D FromMilePerHour(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), W = (w * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond) }; + + /// Creates a from components in FootPerSecond. + /// The X component, in FootPerSecond. + /// The Y component, in FootPerSecond. + /// The Z component, in FootPerSecond. + /// The W component, in FootPerSecond. + /// A new storing the SI-base equivalent. + public static Velocity4D FromFootPerSecond(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), W = (w * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond) }; + + /// Creates a from components in Knot. + /// The X component, in Knot. + /// The Y component, in Knot. + /// The Z component, in Knot. + /// The W component, in Knot. + /// A new storing the SI-base equivalent. + public static Velocity4D FromKnot(T x, T y, T z, T w) => new() { X = (x * Units.ConversionConstants.Values.KnotToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KnotToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.KnotToMeterPerSecond), W = (w * Units.ConversionConstants.Values.KnotToMeterPerSecond) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z, T W) In(global::ktsu.Semantics.Quantities.IVelocityUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z), unit.FromBase(W)); + /// 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 dfb5edd..5d79f81 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 @@ -47,6 +47,40 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.ForceMagnitude DistanceTo(WeightVector other) => global::ktsu.Semantics.Quantities.ForceMagnitude.Create(Distance(other)); + /// Creates a from components in Newton. + /// The X component, in Newton. + /// The Y component, in Newton. + /// The Z component, in Newton. + /// A new storing the SI-base equivalent. + public static WeightVector FromNewton(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in Kilonewton. + /// The X component, in Kilonewton. + /// The Y component, in Kilonewton. + /// The Z component, in Kilonewton. + /// A new storing the SI-base equivalent. + public static WeightVector FromKilonewton(T x, T y, T z) => new() { X = (x * MetricMagnitudes.Values.Kilo), Y = (y * MetricMagnitudes.Values.Kilo), Z = (z * MetricMagnitudes.Values.Kilo) }; + + /// Creates a from components in Dyne. + /// The X component, in Dyne. + /// The Y component, in Dyne. + /// The Z component, in Dyne. + /// A new storing the SI-base equivalent. + public static WeightVector FromDyne(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.DyneToNewtons), Y = (y * Units.ConversionConstants.Values.DyneToNewtons), Z = (z * Units.ConversionConstants.Values.DyneToNewtons) }; + + /// Creates a from components in PoundForce. + /// The X component, in PoundForce. + /// The Y component, in PoundForce. + /// The Z component, in PoundForce. + /// A new storing the SI-base equivalent. + public static WeightVector FromPoundForce(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.PoundForceToNewtons), Y = (y * Units.ConversionConstants.Values.PoundForceToNewtons), Z = (z * Units.ConversionConstants.Values.PoundForceToNewtons) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IForceUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// 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 b8d989f..d3e125b 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 @@ -47,6 +47,47 @@ namespace ktsu.Semantics.Quantities; /// The vector to measure the distance to. public global::ktsu.Semantics.Quantities.Speed DistanceTo(WindVelocity3D other) => global::ktsu.Semantics.Quantities.Speed.Create(Distance(other)); + /// Creates a from components in MeterPerSecond. + /// The X component, in MeterPerSecond. + /// The Y component, in MeterPerSecond. + /// The Z component, in MeterPerSecond. + /// A new storing the SI-base equivalent. + public static WindVelocity3D FromMeterPerSecond(T x, T y, T z) => new() { X = x, Y = y, Z = z }; + + /// Creates a from components in KilometerPerHour. + /// The X component, in KilometerPerHour. + /// The Y component, in KilometerPerHour. + /// The Z component, in KilometerPerHour. + /// A new storing the SI-base equivalent. + public static WindVelocity3D FromKilometerPerHour(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.KilometerPerHourToMeterPerSecond) }; + + /// Creates a from components in MilePerHour. + /// The X component, in MilePerHour. + /// The Y component, in MilePerHour. + /// The Z component, in MilePerHour. + /// A new storing the SI-base equivalent. + public static WindVelocity3D FromMilePerHour(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.MilePerHourToMeterPerSecond) }; + + /// Creates a from components in FootPerSecond. + /// The X component, in FootPerSecond. + /// The Y component, in FootPerSecond. + /// The Z component, in FootPerSecond. + /// A new storing the SI-base equivalent. + public static WindVelocity3D FromFootPerSecond(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.FootPerSecondToMeterPerSecond) }; + + /// Creates a from components in Knot. + /// The X component, in Knot. + /// The Y component, in Knot. + /// The Z component, in Knot. + /// A new storing the SI-base equivalent. + public static WindVelocity3D FromKnot(T x, T y, T z) => new() { X = (x * Units.ConversionConstants.Values.KnotToMeterPerSecond), Y = (y * Units.ConversionConstants.Values.KnotToMeterPerSecond), Z = (z * Units.ConversionConstants.Values.KnotToMeterPerSecond) }; + + /// Converts this vector's SI-base components to . + /// Returns bare components rather than a , because a vector that is not in base units cannot be one. + /// The dimensionally-compatible target unit. + /// The components expressed in . + public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.IVelocityUnit unit) => (unit.FromBase(X), unit.FromBase(Y), unit.FromBase(Z)); + /// Calculates the length of the vector. public T Length() { diff --git a/Semantics.SourceGenerators/AnalyzerReleases.Unshipped.md b/Semantics.SourceGenerators/AnalyzerReleases.Unshipped.md index 18be11e..b220fd2 100644 --- a/Semantics.SourceGenerators/AnalyzerReleases.Unshipped.md +++ b/Semantics.SourceGenerators/AnalyzerReleases.Unshipped.md @@ -14,3 +14,4 @@ SEM006 | Semantics.SourceGenerators | Warning | Reports a metadata file a gener SEM007 | Semantics.SourceGenerators | Error | Reports a metadata file that could not be parsed. Replaces the base generator's CONV001. SEM008 | Semantics.SourceGenerators | Warning | Reports a relationship whose declared result does not follow from the dimensions of its operands, or whose signed value cannot land in a magnitude result. SEM009 | Semantics.SourceGenerators | Error | Reports a conversions.json factor whose value is neither a decimal literal nor a fraction of two decimal literals with a non-zero denominator, or that a double cannot hold. +SEM010 | Semantics.SourceGenerators | Warning | Reports a dimension that declares both a vector form and an offset unit, whose vector types therefore get no `From{Unit}` factories and no `In(unit)` reader. diff --git a/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs b/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs index 01a726a..9209f06 100644 --- a/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs +++ b/Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs @@ -164,8 +164,10 @@ private void EmitType(SourceProductionContext context, QuantityType type, Emissi else { // V2/3/4 overloads are rare — the strategy document shows them mainly for V3 - // (Position3D, Translation3D) — and carry no units or relationships of their own. - EmitVectorOverloadType(context, type); + // (Position3D, Translation3D) — and carry no relationships of their own. They do get + // the per-unit surface (#237): Position3D is exactly the type whose callers were + // hand-writing the ×1000, and it reaches its units through the dimension it refines. + EmitVectorOverloadType(context, type, dim, emission); } } @@ -595,7 +597,7 @@ private static void AddUnitFactories( bool isBase = unitName == baseUnit; string conversionExpr = isBase ? Emit.ValueParameter - : BuildToBaseExpression(unitName, unitMap); + : BuildToBaseExpression(unitName, unitMap, Emit.ValueParameter); string body = applyV0Guard ? $"=> Create(Vector0Guards.{guardMethod}({conversionExpr}, nameof(value)));" @@ -631,10 +633,10 @@ private static void AddUnitFactories( } /// - /// Builds the C# expression converting value in to the SI - /// base unit. Honours magnitude (Kilo, Centi, …), conversionFactor (lookup in - /// ), their product when a unit declares both, and offset - /// (additive, after scaling). + /// Builds the C# expression converting in + /// to the SI base unit. Honours magnitude (Kilo, Centi, …), conversionFactor + /// (lookup in ), their product when a unit declares both, and + /// offset (additive, after scaling). /// /// /// Each factor is read from the Values<T> holder that @@ -642,7 +644,17 @@ private static void AddUnitFactories( /// type once. It used to be T.CreateChecked of the constant, which /// capped every storage type at the precision of . /// - private static string BuildToBaseExpression(string unitName, IReadOnlyDictionary unitMap) + /// The unit the operand is expressed in. + /// Every unit declared in units.json, keyed by name. + /// + /// The expression being converted. The scalar factories pass their value parameter; the + /// vector factories (#237) pass one component parameter at a time, which is the only reason + /// this is a parameter rather than the constant it used to be. + /// + private static string BuildToBaseExpression( + string unitName, + IReadOnlyDictionary unitMap, + string operand) { // If we don't have unit metadata, fall back to identity. The dimensions.json author is // responsible for keeping availableUnits in sync with units.json; if a unit is missing, @@ -650,10 +662,10 @@ private static string BuildToBaseExpression(string unitName, IReadOnlyDictionary // (A future SEM00x diagnostic could surface this gap.) if (!unitMap.TryGetValue(unitName, out UnitDefinition? unit) || unit == null) { - return Emit.ValueParameter; + return operand; } - string scaled = Emit.ValueParameter; + string scaled = operand; bool hasMagnitude = !string.IsNullOrEmpty(unit.Magnitude) && unit.Magnitude != "1"; bool hasFactor = !string.IsNullOrEmpty(unit.ConversionFactor) && unit.ConversionFactor != "1"; @@ -661,19 +673,18 @@ private static string BuildToBaseExpression(string unitName, IReadOnlyDictionary // IUnit.ToBaseFactorAs() reports (UnitsGenerator.BuildStorageFactorExpression). if (hasMagnitude && hasFactor) { - scaled = $"(value * (MetricMagnitudes.Values.{unit.Magnitude} * Units.ConversionConstants.Values.{unit.ConversionFactor}))"; + scaled = $"({operand} * (MetricMagnitudes.Values.{unit.Magnitude} * Units.ConversionConstants.Values.{unit.ConversionFactor}))"; } else if (hasMagnitude) { - scaled = $"(value * MetricMagnitudes.Values.{unit.Magnitude})"; + scaled = $"({operand} * MetricMagnitudes.Values.{unit.Magnitude})"; } else if (hasFactor) { - scaled = $"(value * Units.ConversionConstants.Values.{unit.ConversionFactor})"; + scaled = $"({operand} * Units.ConversionConstants.Values.{unit.ConversionFactor})"; } - bool hasOffset = !string.IsNullOrEmpty(unit.Offset) && unit.Offset != "0"; - if (hasOffset) + if (HasOffset(unit)) { scaled = $"({scaled} + Units.ConversionConstants.Values.{unit.Offset})"; } @@ -681,6 +692,18 @@ private static string BuildToBaseExpression(string unitName, IReadOnlyDictionary return scaled; } + /// + /// Whether converts to the SI base with a non-zero additive offset — + /// the temperature scales, and nothing else today. + /// + /// + /// Scalar factories apply the offset; the vector factories refuse to be generated at all when + /// one is in reach (#237, decision 2), so both paths need the same question answered the same + /// way rather than each spelling out the null-and-"0" check. + /// + private static bool HasOffset(UnitDefinition? unit) => + unit != null && !string.IsNullOrEmpty(unit.Offset) && unit.Offset != "0"; + /// /// Adds the per-quantity surface required by /// (#59): a Dimension override returning PhysicalDimensions.{dim}, plus a @@ -1142,6 +1165,7 @@ private static void EmitVectorType( WriteVectorStaticProperties(cb, fullType, components); WriteVectorMagnitudeMembers(cb, fullType, v0TypeName); + WriteVectorUnitMembers(cb, context, typeName, fullType, components, dim, emission.Units); WriteVectorMethods(cb, fullType, components, dims); WriteVectorOperators(cb, fullType, components); @@ -1347,7 +1371,11 @@ private void EmitOverloadType( context.AddSource(sourceFile.FileName, cb.ToString()); } - private static void EmitVectorOverloadType(SourceProductionContext context, QuantityType type) + private static void EmitVectorOverloadType( + SourceProductionContext context, + QuantityType type, + PhysicalDimension dim, + Emission emission) { int dims = type.Form; string[] components = Components(dims); @@ -1383,6 +1411,7 @@ private static void EmitVectorOverloadType(SourceProductionContext context, Quan WriteVectorComponentProperties(cb, components); WriteVectorStaticProperties(cb, fullType, components); WriteVectorMagnitudeMembers(cb, fullType, type.MagnitudeType); + WriteVectorUnitMembers(cb, context, typeName, fullType, components, dim, emission.Units); WriteVectorMethods(cb, fullType, components, dims); WriteVectorOperators(cb, fullType, components); @@ -1644,6 +1673,108 @@ private static void WriteVectorMagnitudeMembers(CodeBlocker cb, string fullType, cb.NewLine(); } + /// + /// Writes the per-unit surface a vector form was missing: one From{Unit} factory per + /// entry in the dimension's availableUnits, and the In(unit) reader that answers + /// in the caller's unit again. Issue #237. + /// + /// + /// + /// The factories take one per component and convert each with the + /// same Values<T> holder the scalar factories read, so a decimal or + /// PreciseNumber vector converts at its own precision rather than through + /// . Naming follows the same mechanical rule: the unit's singular + /// lemma from units.json, verbatim. + /// + /// + /// Deliberately no Vector0Guards. Vector components are signed by construction — a + /// Position3D with a negative X is ordinary — so the non-negativity rule that belongs + /// to the V0 form must not leak in here (#237, decision 1). + /// + /// + /// The reader returns a tuple of components rather than the vector type. It cannot return the + /// vector type: the result is no longer in base units, and a Position3D that is not in + /// base units would be a lie in the type system. The tuple's elements carry the component + /// names, so var (x, y, z) = p.In(Units.Kilometer) reads at the call site. + /// + /// + /// The code blocker to write to. + /// Where SEM010 goes if the dimension is one this cannot serve. + /// The vector type being written, for the diagnostic message. + /// The vector type including its type argument. + /// The component names, e.g. X, Y, Z. + /// The dimension the vector form belongs to. + /// Every unit declared in units.json, keyed by name. + private static void WriteVectorUnitMembers( + CodeBlocker cb, + SourceProductionContext context, + string typeName, + string fullType, + string[] components, + PhysicalDimension dim, + IReadOnlyDictionary unitMap) + { + List availableUnits = dim.AvailableUnits; + if (availableUnits == null || availableUnits.Count == 0) + { + return; + } + + // An offset conversion applied componentwise is meaningless — adding 273.15 to each + // component of a displacement is not a unit change, it is nonsense — and the In(unit) + // reader takes I{dim}Unit, so it would accept the offset unit at runtime even if only + // the factories were skipped. So the whole per-unit surface is refused for the dimension + // rather than emitting something quietly wrong for part of it (#237, decision 2). + // + // No dimension declaring a vector form has an offset unit today: this is the guard that + // keeps that true rather than a bug being worked around. + List offsetUnits = [.. availableUnits.Where(u => unitMap.TryGetValue(u, out UnitDefinition? d) && HasOffset(d))]; + if (offsetUnits.Count > 0) + { + context.ReportAt( + SemanticsDiagnostics.OffsetUnitOnVectorForm, + location: null, + typeName, + dim.Name, + string.Join(", ", offsetUnits)); + return; + } + + string baseUnit = availableUnits[0]; + string[] parameters = [.. components.Select(c => c.ToLowerInvariant())]; + string parameterList = string.Join(", ", parameters.Select(p => $"T {p}")); + + foreach (string unitName in availableUnits) + { + bool isBase = unitName == baseUnit; + string initializers = string.Join( + ", ", + components.Zip(parameters, (component, parameter) => (component, parameter)) + .Select(pair => $"{pair.component} = {(isBase ? pair.parameter : BuildToBaseExpression(unitName, unitMap, pair.parameter))}")); + + cb.WriteLine($"/// Creates a from components in {unitName}."); + foreach (string parameter in parameters) + { + cb.WriteLine($"/// The {parameter.ToUpperInvariant()} component, in {unitName}."); + } + + cb.WriteLine($"/// A new storing the SI-base equivalent."); + cb.WriteLine($"public static {fullType} From{unitName}({parameterList}) => new() {{ {initializers} }};"); + cb.NewLine(); + } + + string unitInterface = $"global::ktsu.Semantics.Quantities.I{dim.Name}Unit"; + string tupleType = string.Join(", ", components.Select(c => $"T {c}")); + string tupleValue = string.Join(", ", components.Select(c => $"unit.FromBase({c})")); + + cb.WriteLine("/// Converts this vector's SI-base components to ."); + cb.WriteLine($"/// Returns bare components rather than a , because a vector that is not in base units cannot be one."); + cb.WriteLine("/// The dimensionally-compatible target unit."); + cb.WriteLine("/// The components expressed in ."); + cb.WriteLine($"public ({tupleType}) In({unitInterface} unit) => ({tupleValue});"); + 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.SourceGenerators/SemanticsDiagnostics.cs b/Semantics.SourceGenerators/SemanticsDiagnostics.cs index 14d0947..6d837ba 100644 --- a/Semantics.SourceGenerators/SemanticsDiagnostics.cs +++ b/Semantics.SourceGenerators/SemanticsDiagnostics.cs @@ -122,4 +122,26 @@ public static class SemanticsDiagnostics 9, "conversions.json factor value is malformed", "Conversion factor '{0}' has value '{1}', which is not a decimal literal such as \"0.3048\" or a fraction of two such as \"5/9\" with a non-zero denominator, that a double can hold without overflowing or rounding to zero. No constant is generated for it. Fix conversions.json."); + + /// + /// SEM010: a dimension declaring a vector form has an offset unit in its + /// availableUnits, so that vector form gets no per-unit surface. + /// + /// + /// An additive offset is meaningless applied componentwise — adding 273.15 to each component + /// of a displacement is not a unit change — so the From{Unit} factories and the + /// In(unit) reader are not emitted for that vector type, rather than being emitted + /// quietly wrong (#237, decision 2). The scalar forms keep their factories: the offset is + /// correct for a V0 or V1, and only the componentwise reading of it is not. + /// + /// Defensive rather than observed. No dimension declaring a vector form has an offset unit + /// today, and this is what keeps that true instead of letting the combination appear silently. + /// A warning rather than an error, because the vector type itself still generates and every + /// other member on it is unaffected. + /// + /// + public static DiagnosticDescriptor OffsetUnitOnVectorForm { get; } = Catalog.Warning( + 10, + "Vector form cannot express a unit with an additive offset", + "Vector type '{0}' belongs to dimension '{1}', whose availableUnits include offset unit(s) {2}. An offset conversion is meaningless applied componentwise, so no From{{Unit}} factories and no In(unit) reader are generated for '{0}'. Give the offset unit its own dimension, or drop the vector form."); } diff --git a/Semantics.Test/Quantities/GeneratorDiagnosticTests.cs b/Semantics.Test/Quantities/GeneratorDiagnosticTests.cs index d9fce56..221b135 100644 --- a/Semantics.Test/Quantities/GeneratorDiagnosticTests.cs +++ b/Semantics.Test/Quantities/GeneratorDiagnosticTests.cs @@ -593,6 +593,122 @@ public void AUnitWithAMagnitudeAndAFactorAppliesBothInItsFactoryAndItsUnit() Assert.Contains("=> MetricMagnitudes.Values.Kilo * ConversionConstants.Values.FeetToMeters;", units); } + /// + /// A units document whose second unit converts with an additive offset, so a dimension can be + /// given the combination — a vector form and an offset unit — that no real dimension has. + /// + /// + /// DimensionsDocument declares vector3: Displacement3D, so naming Stepped + /// in its availableUnits is the whole of the setup. + /// + private const string OffsetUnitsDocument = + """ + { + "unitCategories": [ + { + "name": "Test", + "description": "A category.", + "units": [ + { "name": "Meter", "symbol": "m", "description": "Meter.", "system": "SIBase" }, + { "name": "Stepped", "symbol": "st", "description": "A scale with a zero somewhere else.", "system": "Other", "offset": "CelsiusToKelvinOffset" } + ] + } + ] + } + """; + + /// + /// Runs the quantities generator over a dimension declaring a vector form, with the units it + /// should be able to reach. + /// + /// The units the dimension declares, as JSON list items. + /// The units.json to resolve them against. + /// What the generator reported, and everything it wrote. + private static (IReadOnlyList Diagnostics, string Source) RunOverVectorDimension( + string availableUnits, + string unitsDocument) + { + Dictionary metadata = new() + { + ["dimensions.json"] = DimensionsDocument(availableUnits: availableUnits), + ["units.json"] = unitsDocument, + }; + + GeneratorRunResult result = Harness.Run(new QuantitiesGenerator(), metadata); + + return ( + [.. result.Diagnostics], + string.Join("\n", result.GeneratedSources.Select(static source => source.SourceText.ToString()))); + } + + /// + /// A dimension that declares a vector form and an offset unit gets SEM010, and its vector type + /// gets no per-unit surface at all rather than a componentwise offset that means nothing (#237). + /// + [TestMethod] + public void Sem010_IsReportedForAVectorFormWhoseDimensionDeclaresAnOffsetUnit() + { + (IReadOnlyList diagnostics, string source) = + RunOverVectorDimension("\"Meter\", \"Stepped\"", OffsetUnitsDocument); + + AssertReports(diagnostics, "SEM010"); + + // The refusal is the whole surface, not just the offending unit: In(unit) takes the + // dimension's unit interface, so it would accept Stepped at runtime even if only the + // FromStepped factory were skipped. + Assert.DoesNotContain("public static Displacement3D FromMeter(", source); + Assert.DoesNotContain("public static Displacement3D FromStepped(", source); + Assert.DoesNotContain("public (T X, T Y, T Z) In(", source); + } + + /// + /// The scalar forms of that same dimension keep their factories. The offset is correct for a + /// V0 — only reading it componentwise is not — so SEM010 must not cost them anything. + /// + [TestMethod] + public void Sem010_DoesNotTakeTheScalarFactoriesWithIt() + { + (_, string source) = RunOverVectorDimension("\"Meter\", \"Stepped\"", OffsetUnitsDocument); + + Assert.Contains("public static Length FromStepped(T value)", source); + } + + /// + /// Without the offset unit the same dimension gets the full vector surface and no diagnostic, + /// so SEM010 is pinned to the offset rather than to declaring a vector form at all. + /// + [TestMethod] + public void AVectorFormWithoutAnOffsetUnitGetsItsFactoriesAndReader() + { + (IReadOnlyList diagnostics, string source) = + RunOverVectorDimension("\"Meter\", \"Kilofoot\"", OffsetFreeUnitsDocument); + + Assert.IsEmpty( + diagnostics.Where(static diagnostic => diagnostic.Id == "SEM010"), + "SEM010 fired for a dimension with no offset unit."); + + Assert.Contains("public static Displacement3D FromMeter(T x, T y, T z) => new() { X = x, Y = y, Z = z };", source); + Assert.Contains("public static Displacement3D FromKilofoot(T x, T y, T z)", source); + Assert.Contains("public (T X, T Y, T Z) In(global::ktsu.Semantics.Quantities.ILengthUnit unit)", source); + } + + /// The same two units as , neither carrying an offset. + private const string OffsetFreeUnitsDocument = + """ + { + "unitCategories": [ + { + "name": "Test", + "description": "A category.", + "units": [ + { "name": "Meter", "symbol": "m", "description": "Meter.", "system": "SIBase" }, + { "name": "Kilofoot", "symbol": "kft", "description": "A thousand feet.", "system": "Imperial", "magnitude": "Kilo", "conversionFactor": "FeetToMeters" } + ] + } + ] + } + """; + /// /// The real metadata reports nothing except the relationships it is already known to get wrong. /// diff --git a/Semantics.Test/Quantities/StorageConversionTests.cs b/Semantics.Test/Quantities/StorageConversionTests.cs index 38a4bfc..c767778 100644 --- a/Semantics.Test/Quantities/StorageConversionTests.cs +++ b/Semantics.Test/Quantities/StorageConversionTests.cs @@ -2,6 +2,7 @@ namespace ktsu.Semantics.Test.Quantities; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -170,6 +171,72 @@ public void AnIrrationalLengthHasThePrecisionOfTheStorageType() AssertValue("1.41421356237309504880168872420969807856967187537694807317667973799", diagonal.Length(), terminates: false); } + /// + /// A vector factory converts every component, so the ×1000 a kilometre-native caller used to + /// write by hand now lives in the type. Issue #237. + /// + [TestMethod] + public void AVectorFactoryConvertsEveryComponent() + { + Position3D orbit = Position3D.FromKilometer(Of("6778"), Of("-1.5"), T.Zero); + + AssertValue("6778000", orbit.X, terminates: true); + AssertValue("-1500", orbit.Y, terminates: true); + AssertValue("0", orbit.Z, terminates: true); + } + + /// + /// The vector factories read the same Values<T> holder as the scalar ones, so a + /// non-terminating factor lands at the storage type's own precision rather than arriving + /// through . The knot is the sharpest case the catalogue has. + /// + [TestMethod] + public void AVectorFactoryAgreesWithTheScalarFactoryForTheSameUnit() + { + Velocity3D velocity = Velocity3D.FromKnot(T.One, T.One, T.One); + Speed speed = Speed.FromKnot(T.One); + + AssertValue("0.51444444444444444444444444444444444444", velocity.X, terminates: false); + Assert.AreEqual(speed.Value, velocity.X); + Assert.AreEqual(speed.Value, velocity.Y); + Assert.AreEqual(speed.Value, velocity.Z); + } + + /// + /// The reader answers in the caller's unit again, as bare components rather than the vector + /// type — which it could not be, the result no longer being in base units. + /// + [TestMethod] + public void TheVectorReaderRoundTripsThroughItsUnit() + { + (T x, T y, T z) = Position3D.FromKilometer(Of("36"), Of("-4"), T.Zero).In(Units.Kilometer); + + AssertValue("36", x, terminates: true); + AssertValue("-4", y, terminates: true); + AssertValue("0", z, terminates: true); + } + + /// + /// Vector components are signed by construction, so the factories carry no + /// Vector0Guards: a position with a negative X is ordinary, and the V0 non-negativity + /// rule must not leak into the vector forms (#237, decision 1). + /// + /// + /// The paired scalar call is what makes this an assertion rather than a coincidence. The same + /// unit and the same negative magnitude does throw on the V0, so a guard added to the vector + /// factories would be caught here rather than quietly narrowing what they accept. + /// + [TestMethod] + public void AVectorFactoryAcceptsNegativeComponentsWhereTheMagnitudeFormRefusesThem() + { + Position3D behind = Position3D.FromKilometer(Of("-1"), Of("-2"), Of("-3")); + + AssertValue("-1000", behind.X, terminates: true); + AssertValue("-3000", behind.Z, terminates: true); + + Assert.ThrowsExactly(() => Length.FromKilometer(Of("-1"))); + } + /// /// Parses a literal into . /// diff --git a/docs/physics-generator.md b/docs/physics-generator.md index 2e5dcf6..25b258b 100644 --- a/docs/physics-generator.md +++ b/docs/physics-generator.md @@ -235,6 +235,7 @@ them. See the type's own documentation for what each one guarantees. | SEM007 | A metadata file that could not be parsed. | | SEM008 | A relationship whose declared result does not follow from the dimensions of its operands, or whose signed value cannot land in a magnitude result. No operator is generated for it. | | SEM009 | A `conversions.json` factor whose `value` is neither a decimal literal nor a fraction of two with a non-zero denominator, or that a `double` cannot hold. An error, and no constant is generated for it. | + | SEM010 | A dimension declaring both a vector form and an offset unit. Its vector types get no `From{Unit}` factories and no `In(unit)` reader, because an additive offset applied componentwise is not a unit change. The scalar forms keep theirs, where the offset is correct. | Adding one means adding it to `SemanticsDiagnostics` and to `AnalyzerReleases.Unshipped.md`; `AnalyzerReleaseTrackingTests` fails if the second step is forgotten. `GeneratorDiagnosticTests` proves each one still fires on the input it is meant to catch. - `availableUnits` order matters: the first entry is treated as the SI base unit by `UnitsGenerator`.