Changed how Scalar is generated to use Dimensions.ArgOpts and Scales.ArgOpts
This commit is contained in:
parent
a2d46e3f55
commit
82bdb96746
53
src/Base.zig
53
src/Base.zig
@ -5,22 +5,32 @@ const Dimensions = @import("Dimensions.zig");
|
||||
const Scales = @import("Scales.zig");
|
||||
const Scalar = @import("Scalar.zig").Scalar;
|
||||
|
||||
/// Helper function to create a clean namespace for each physical dimension.
|
||||
/// It exposes the raw dimensions, and easy type-creators for Base or Scaled variants.
|
||||
pub fn BaseScalar(comptime d: anytype) type {
|
||||
fn PhysicalConstant(comptime d: Dimensions.ArgOpts, comptime val: f64, comptime s: Scales.ArgOpts) type {
|
||||
return struct {
|
||||
pub const dims = Dimensions.init(d);
|
||||
const dims = Dimensions.init(d);
|
||||
const scales = Scales.init(s);
|
||||
|
||||
/// Instantiates the constant into a specific numeric type.
|
||||
pub fn Of(comptime T: type) Scalar(T, d, s) {
|
||||
return .{ .value = @as(T, @floatCast(val)) };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn BaseScalar(comptime d: Dimensions.ArgOpts) type {
|
||||
return struct {
|
||||
const dims = Dimensions.init(d);
|
||||
|
||||
/// Creates a Scalar of this dimension using default scales.
|
||||
/// Example: const V = Quantities.Velocity.Base(f32);
|
||||
pub fn Of(comptime T: type) type {
|
||||
return Scalar(T, dims, Scales.init(.{}));
|
||||
return Scalar(T, d, .{});
|
||||
}
|
||||
|
||||
/// Creates a Scalar of this dimension using custom scales.
|
||||
/// Example: const Kmh = Quantities.Velocity.Scaled(f32, Scales.init(.{ .L = .k, .T = .hour }));
|
||||
pub fn Scaled(comptime T: type, comptime s: Scales) type {
|
||||
return Scalar(T, dims, s);
|
||||
pub fn Scaled(comptime T: type, comptime s: Scales.ArgOpts) type {
|
||||
return Scalar(T, d, s);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -95,6 +105,31 @@ pub const Frequency = BaseScalar(.{ .T = -1 });
|
||||
pub const Viscosity = BaseScalar(.{ .M = 1, .L = -1, .T = -1 });
|
||||
pub const SurfaceTension = BaseScalar(.{ .M = 1, .T = -2 }); // Corrected from MT-2a
|
||||
|
||||
// ==========================================
|
||||
// Physical Constants
|
||||
// ==========================================
|
||||
pub const Constants = struct {
|
||||
/// Speed of light in vacuum
|
||||
pub const c = Speed.Constant(299792458.0, Scales.init(.{}));
|
||||
|
||||
/// Standard gravity
|
||||
pub const g = Acceleration.Constant(9.80665, Scales.init(.{}));
|
||||
|
||||
/// Newton's Gravitational Constant: L³ M⁻¹ T⁻²
|
||||
pub const GravitationalConstant = PhysicalConstant(
|
||||
.{ .L = 3, .M = -1, .T = -2 },
|
||||
6.67430e-11,
|
||||
Scales.init(.{}),
|
||||
);
|
||||
|
||||
/// Planck Constant: M L² T⁻¹
|
||||
pub const Planck = PhysicalConstant(
|
||||
.{ .M = 1, .L = 2, .T = -1 },
|
||||
6.62607015e-34,
|
||||
Scales.init(.{}),
|
||||
);
|
||||
};
|
||||
|
||||
test "BaseQuantities - Core dimensions instantiation" {
|
||||
// Basic types via generic wrappers
|
||||
const M = Meter.Of(f32);
|
||||
@ -104,7 +139,7 @@ test "BaseQuantities - Core dimensions instantiation" {
|
||||
try std.testing.expectEqual(0, M.dims.get(.T));
|
||||
|
||||
// Test specific scale variants
|
||||
const Kmh = Speed.Scaled(f32, Scales.init(.{ .L = .k, .T = .hour }));
|
||||
const Kmh = Speed.Scaled(f32, .{ .L = .k, .T = .hour });
|
||||
const speed = Kmh{ .value = 120.0 };
|
||||
try std.testing.expectEqual(120.0, speed.value);
|
||||
try std.testing.expectEqual(.k, @TypeOf(speed).scales.get(.L));
|
||||
@ -128,7 +163,7 @@ test "BaseQuantities - Kinematics equations" {
|
||||
|
||||
test "BaseQuantities - Dynamics (Force and Work)" {
|
||||
// 10 kg
|
||||
const m = Gramm.Scaled(f32, Scales.init(.{ .M = .k })){ .value = 10.0 };
|
||||
const m = Gramm.Scaled(f32, .{ .M = .k }){ .value = 10.0 };
|
||||
// 9.8 m/s^2
|
||||
const a = Acceleration.Of(f32){ .value = 9.8 };
|
||||
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const ArgOpts = struct {
|
||||
L: comptime_int = 0,
|
||||
M: comptime_int = 0,
|
||||
T: comptime_int = 0,
|
||||
I: comptime_int = 0,
|
||||
Tp: comptime_int = 0,
|
||||
N: comptime_int = 0,
|
||||
J: comptime_int = 0,
|
||||
};
|
||||
|
||||
pub const Dimension = enum {
|
||||
/// Length
|
||||
L,
|
||||
@ -37,9 +47,9 @@ const Self = @This();
|
||||
|
||||
data: std.EnumArray(Dimension, comptime_int),
|
||||
|
||||
/// Create a `Dimensions` from an anonymous struct literal, e.g. `.{ .L = 1, .T = -1 }`.
|
||||
/// Create a `Dimensions` from a struct literal, e.g. `.{ .L = 1, .T = -1 }`.
|
||||
/// Unspecified dimensions default to 0.
|
||||
pub fn init(comptime init_val: anytype) Self {
|
||||
pub fn init(comptime init_val: ArgOpts) Self {
|
||||
var s = Self{ .data = std.EnumArray(Dimension, comptime_int).initFill(0) };
|
||||
inline for (std.meta.fields(@TypeOf(init_val))) |f|
|
||||
s.data.set(@field(Dimension, f.name), @field(init_val, f.name));
|
||||
|
||||
139
src/Scalar.zig
139
src/Scalar.zig
@ -7,12 +7,17 @@ const UnitScale = Scales.UnitScale;
|
||||
const Dimensions = @import("Dimensions.zig");
|
||||
const Dimension = Dimensions.Dimension;
|
||||
|
||||
// TODO: Be able to use comptime float and int and T for mulBy ect
|
||||
// TODO:
|
||||
// - Be able to use comptime float and int and T for mulBy ect
|
||||
// Which endup being Dimension less
|
||||
|
||||
/// A dimensioned scalar value. `T` is the numeric type, `d` the dimension exponents, `s` the SI scales.
|
||||
/// All dimension and unit tracking is resolved at comptime — zero runtime overhead.
|
||||
pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type {
|
||||
pub fn Scalar(comptime T: type, comptime d_opt: Dimensions.ArgOpts, comptime s_opt: Scales.ArgOpts) type {
|
||||
return Scalar_(T, Dimensions.init(d_opt), Scales.init(s_opt));
|
||||
}
|
||||
|
||||
pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) type {
|
||||
@setEvalBranchQuota(10_000_000);
|
||||
return struct {
|
||||
value: T,
|
||||
@ -33,7 +38,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
|
||||
/// Add two quantities. Dimensions must match — compile error otherwise.
|
||||
/// Scales are auto-resolved to the finer of the two.
|
||||
pub inline fn add(self: Self, rhs: anytype) Scalar(
|
||||
pub inline fn add(self: Self, rhs: anytype) Scalar_(
|
||||
T,
|
||||
dims,
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
@ -43,7 +48,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return .{ .value = self.value + rhs.value };
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -52,7 +57,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
|
||||
/// Subtract two quantities. Dimensions must match — compile error otherwise.
|
||||
/// Scales are auto-resolved to the finer of the two.
|
||||
pub inline fn sub(self: Self, rhs: anytype) Scalar(
|
||||
pub inline fn sub(self: Self, rhs: anytype) Scalar_(
|
||||
T,
|
||||
dims,
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
@ -62,7 +67,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return .{ .value = self.value - rhs.value };
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -70,14 +75,14 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
}
|
||||
|
||||
/// Multiply two quantities. Dimension exponents are summed: `L¹ * T⁻¹ → L¹T⁻¹`.
|
||||
pub inline fn mulBy(self: Self, rhs: anytype) Scalar(
|
||||
pub inline fn mulBy(self: Self, rhs: anytype) Scalar_(
|
||||
T,
|
||||
dims.add(@TypeOf(rhs).dims),
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
) {
|
||||
const RhsType = @TypeOf(rhs);
|
||||
const SelfNorm = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const RhsNorm = Scalar(T, RhsType.dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const SelfNorm = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const RhsNorm = Scalar_(T, RhsType.dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
if (comptime Self == SelfNorm and RhsType == RhsNorm)
|
||||
return .{ .value = self.value * rhs.value };
|
||||
|
||||
@ -88,14 +93,14 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
|
||||
/// Divide two quantities. Dimension exponents are subtracted: `L¹ / T¹ → L¹T⁻¹`.
|
||||
/// Integer types use truncating division.
|
||||
pub inline fn divBy(self: Self, rhs: anytype) Scalar(
|
||||
pub inline fn divBy(self: Self, rhs: anytype) Scalar_(
|
||||
T,
|
||||
dims.sub(@TypeOf(rhs).dims),
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
) {
|
||||
const RhsType = @TypeOf(rhs);
|
||||
const SelfNorm = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const RhsNorm = Scalar(T, RhsType.dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const SelfNorm = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const RhsNorm = Scalar_(T, RhsType.dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime Self == SelfNorm) self.value else self.to(SelfNorm).value;
|
||||
const rhs_val = if (comptime RhsType == RhsNorm) rhs.value else rhs.to(RhsNorm).value;
|
||||
if (comptime @typeInfo(T) == .int) {
|
||||
@ -116,7 +121,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
|
||||
/// Raises the quantity to a compile-time integer exponent.
|
||||
/// Dimension exponents are multiplied by the exponent: `(L²)³ → L⁶`.
|
||||
pub inline fn pow(self: Self, comptime exp: comptime_int) Scalar(
|
||||
pub inline fn pow(self: Self, comptime exp: comptime_int) Scalar_(
|
||||
T,
|
||||
dims.scale(exp),
|
||||
s,
|
||||
@ -127,7 +132,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
return .{ .value = std.math.pow(T, self.value, @as(T, @floatFromInt(exp))) };
|
||||
}
|
||||
|
||||
pub inline fn sqrt(self: Self) Scalar(
|
||||
pub inline fn sqrt(self: Self) Scalar_(
|
||||
T,
|
||||
dims.div(2),
|
||||
s,
|
||||
@ -196,7 +201,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return self.value == rhs.value;
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -211,7 +216,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return self.value != rhs.value;
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -226,7 +231,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return self.value > rhs.value;
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -240,7 +245,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return self.value >= rhs.value;
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -255,7 +260,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return self.value < rhs.value;
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -269,7 +274,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
if (comptime @TypeOf(rhs) == Self)
|
||||
return self.value <= rhs.value;
|
||||
|
||||
const TargetType = Scalar(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const TargetType = Scalar_(T, dims, hlp.finerScales(Self, @TypeOf(rhs)));
|
||||
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
|
||||
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
|
||||
|
||||
@ -329,8 +334,8 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type
|
||||
}
|
||||
|
||||
test "Generate quantity" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = -3 }));
|
||||
const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .n }));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{ .L = @enumFromInt(-3) });
|
||||
const Second = Scalar(f32, .{ .T = 1 }, .{ .T = .n });
|
||||
|
||||
const distance = Meter{ .value = 10 };
|
||||
const time = Second{ .value = 2 };
|
||||
@ -340,8 +345,8 @@ test "Generate quantity" {
|
||||
}
|
||||
|
||||
test "Comparisons (eq, ne, gt, gte, lt, lte)" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const KiloMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const KiloMeter = Scalar(i128, .{ .L = 1 }, .{ .L = .k });
|
||||
|
||||
const m1000 = Meter{ .value = 1000 };
|
||||
const km1 = KiloMeter{ .value = 1 };
|
||||
@ -366,7 +371,7 @@ test "Comparisons (eq, ne, gt, gte, lt, lte)" {
|
||||
}
|
||||
|
||||
test "Add" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
|
||||
const distance = Meter{ .value = 10 };
|
||||
const distance2 = Meter{ .value = 20 };
|
||||
@ -375,7 +380,7 @@ test "Add" {
|
||||
try std.testing.expectEqual(30, added.value);
|
||||
try std.testing.expectEqual(1, @TypeOf(added).dims.get(.L));
|
||||
|
||||
const KiloMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const KiloMeter = Scalar(i128, .{ .L = 1 }, .{ .L = .k });
|
||||
const distance3 = KiloMeter{ .value = 2 };
|
||||
const added2 = distance.add(distance3);
|
||||
try std.testing.expectEqual(2010, added2.value);
|
||||
@ -385,7 +390,7 @@ test "Add" {
|
||||
try std.testing.expectEqual(2, added3.value);
|
||||
try std.testing.expectEqual(1, @TypeOf(added3).dims.get(.L));
|
||||
|
||||
const KiloMeter_f = Scalar(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const KiloMeter_f = Scalar(f64, .{ .L = 1 }, .{ .L = .k });
|
||||
const distance4 = KiloMeter_f{ .value = 2 };
|
||||
const added4 = distance4.add(distance).to(KiloMeter_f);
|
||||
try std.testing.expectApproxEqAbs(2.01, added4.value, 0.000001);
|
||||
@ -393,8 +398,8 @@ test "Add" {
|
||||
}
|
||||
|
||||
test "Sub" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const KiloMeter_f = Scalar(f64, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const KiloMeter_f = Scalar(f64, .{ .L = 1 }, .{ .L = .k });
|
||||
|
||||
const a = Meter{ .value = 500 };
|
||||
const b = Meter{ .value = 200 };
|
||||
@ -410,8 +415,8 @@ test "Sub" {
|
||||
}
|
||||
|
||||
test "MulBy" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const Second = Scalar(f32, .{ .T = 1 }, .{});
|
||||
|
||||
const d = Meter{ .value = 3.0 };
|
||||
const t = Second{ .value = 4.0 };
|
||||
@ -429,8 +434,8 @@ test "MulBy" {
|
||||
}
|
||||
|
||||
test "MulBy with scale" {
|
||||
const KiloMeter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const KiloGram = Scalar(f32, Dimensions.init(.{ .M = 1 }), Scales.init(.{ .M = .k }));
|
||||
const KiloMeter = Scalar(f32, .{ .L = 1 }, .{ .L = .k });
|
||||
const KiloGram = Scalar(f32, .{ .M = 1 }, .{ .M = .k });
|
||||
|
||||
const dist = KiloMeter{ .value = 2.0 };
|
||||
const mass = KiloGram{ .value = 3.0 };
|
||||
@ -440,10 +445,10 @@ test "MulBy with scale" {
|
||||
}
|
||||
|
||||
test "MulBy with type change" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Second = Scalar(f64, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const KmSec = Scalar(i64, Dimensions.init(.{ .L = 1, .T = 1 }), Scales.init(.{ .L = .k }));
|
||||
const KmSec_f = Scalar(f32, Dimensions.init(.{ .L = 1, .T = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{ .L = .k });
|
||||
const Second = Scalar(f64, .{ .T = 1 }, .{});
|
||||
const KmSec = Scalar(i64, .{ .L = 1, .T = 1 }, .{ .L = .k });
|
||||
const KmSec_f = Scalar(f32, .{ .L = 1, .T = 1 }, .{ .L = .k });
|
||||
|
||||
const d = Meter{ .value = 3.0 };
|
||||
const t = Second{ .value = 4.0 };
|
||||
@ -457,8 +462,8 @@ test "MulBy with type change" {
|
||||
}
|
||||
|
||||
test "MulBy small" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .n }));
|
||||
const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{ .L = .n });
|
||||
const Second = Scalar(f32, .{ .T = 1 }, .{});
|
||||
|
||||
const d = Meter{ .value = 3.0 };
|
||||
const t = Second{ .value = 4.0 };
|
||||
@ -470,8 +475,8 @@ test "MulBy small" {
|
||||
}
|
||||
|
||||
test "MulBy dimensionless" {
|
||||
const DimLess = Scalar(i128, Dimensions.init(.{}), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const DimLess = Scalar(i128, .{}, .{});
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
|
||||
const d = Meter{ .value = 7 };
|
||||
const scaled = d.mulBy(DimLess{ .value = 3 });
|
||||
@ -480,7 +485,7 @@ test "MulBy dimensionless" {
|
||||
}
|
||||
|
||||
test "Sqrt" {
|
||||
const MeterSquare = Scalar(i128, Dimensions.init(.{ .L = 2 }), Scales.init(.{}));
|
||||
const MeterSquare = Scalar(i128, .{ .L = 2 }, .{});
|
||||
|
||||
var d = MeterSquare{ .value = 9 };
|
||||
var scaled = d.sqrt();
|
||||
@ -492,7 +497,7 @@ test "Sqrt" {
|
||||
try std.testing.expectEqual(0, scaled.value);
|
||||
try std.testing.expectEqual(1, @TypeOf(scaled).dims.get(.L));
|
||||
|
||||
const MeterSquare_f = Scalar(f64, Dimensions.init(.{ .L = 2 }), Scales.init(.{}));
|
||||
const MeterSquare_f = Scalar(f64, .{ .L = 2 }, .{});
|
||||
const d2 = MeterSquare_f{ .value = 20 };
|
||||
const scaled2 = d2.sqrt();
|
||||
try std.testing.expectApproxEqAbs(4.472135955, scaled2.value, 1e-4);
|
||||
@ -500,8 +505,8 @@ test "Sqrt" {
|
||||
}
|
||||
|
||||
test "Chained: velocity and acceleration" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const Second = Scalar(f32, .{ .T = 1 }, .{});
|
||||
|
||||
const dist = Meter{ .value = 100.0 };
|
||||
const t1 = Second{ .value = 5.0 };
|
||||
@ -518,8 +523,8 @@ test "Chained: velocity and acceleration" {
|
||||
}
|
||||
|
||||
test "DivBy integer exact" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Second = Scalar(f32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const Second = Scalar(f32, .{ .T = 1 }, .{});
|
||||
|
||||
const dist = Meter{ .value = 120 };
|
||||
const time = Second{ .value = 4 };
|
||||
@ -531,8 +536,8 @@ test "DivBy integer exact" {
|
||||
}
|
||||
|
||||
test "Finer scales skip dim 0" {
|
||||
const Dimless = Scalar(i128, Dimensions.init(.{}), Scales.init(.{}));
|
||||
const KiloMetre = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Dimless = Scalar(i128, .{}, .{});
|
||||
const KiloMetre = Scalar(i128, .{ .L = 1 }, .{ .L = .k });
|
||||
|
||||
const r = Dimless{ .value = 30 };
|
||||
const time = KiloMetre{ .value = 4 };
|
||||
@ -543,9 +548,9 @@ test "Finer scales skip dim 0" {
|
||||
}
|
||||
|
||||
test "Conversion chain: km -> m -> cm" {
|
||||
const KiloMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const CentiMeter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .c }));
|
||||
const KiloMeter = Scalar(i128, .{ .L = 1 }, .{ .L = .k });
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const CentiMeter = Scalar(i128, .{ .L = 1 }, .{ .L = .c });
|
||||
|
||||
const km = KiloMeter{ .value = 15 };
|
||||
const m = km.to(Meter);
|
||||
@ -556,9 +561,9 @@ test "Conversion chain: km -> m -> cm" {
|
||||
}
|
||||
|
||||
test "Conversion: hours -> minutes -> seconds" {
|
||||
const Hour = Scalar(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .hour }));
|
||||
const Minute = Scalar(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{ .T = .min }));
|
||||
const Second = Scalar(i128, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const Hour = Scalar(i128, .{ .T = 1 }, .{ .T = .hour });
|
||||
const Minute = Scalar(i128, .{ .T = 1 }, .{ .T = .min });
|
||||
const Second = Scalar(i128, .{ .T = 1 }, .{});
|
||||
|
||||
const h = Hour{ .value = 1.0 };
|
||||
const min = h.to(Minute);
|
||||
@ -569,7 +574,7 @@ test "Conversion: hours -> minutes -> seconds" {
|
||||
}
|
||||
|
||||
test "Negative values" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
|
||||
const a = Meter{ .value = 5 };
|
||||
const b = Meter{ .value = 20 };
|
||||
@ -578,17 +583,9 @@ test "Negative values" {
|
||||
}
|
||||
|
||||
test "Format Scalar" {
|
||||
const MeterPerSecondSq = Scalar(
|
||||
f32,
|
||||
Dimensions.init(.{ .L = 1, .T = -2 }),
|
||||
Scales.init(.{ .T = .n }),
|
||||
);
|
||||
const KgMeterPerSecond = Scalar(
|
||||
f32,
|
||||
Dimensions.init(.{ .M = 1, .L = 1, .T = -1 }),
|
||||
Scales.init(.{ .M = .k }),
|
||||
);
|
||||
const Meter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const MeterPerSecondSq = Scalar(f32, .{ .L = 1, .T = -2 }, .{ .T = .n });
|
||||
const KgMeterPerSecond = Scalar(f32, .{ .M = 1, .L = 1, .T = -1 }, .{ .M = .k });
|
||||
const Meter = Scalar(f32, .{ .L = 1 }, .{});
|
||||
|
||||
const m = Meter{ .value = 1.23456 };
|
||||
const accel = MeterPerSecondSq{ .value = 9.81 };
|
||||
@ -609,20 +606,20 @@ test "Format Scalar" {
|
||||
}
|
||||
|
||||
test "Abs" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const m1 = Meter{ .value = -50 };
|
||||
const m2 = m1.abs();
|
||||
|
||||
try std.testing.expectEqual(50, m2.value);
|
||||
try std.testing.expectEqual(1, @TypeOf(m2).dims.get(.L));
|
||||
|
||||
const m_float = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const m_float = Scalar(f32, .{ .L = 1 }, .{});
|
||||
const m3 = m_float{ .value = -42.5 };
|
||||
try std.testing.expectEqual(42.5, m3.abs().value);
|
||||
}
|
||||
|
||||
test "Pow" {
|
||||
const Meter = Scalar(i128, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i128, .{ .L = 1 }, .{});
|
||||
const d = Meter{ .value = 4 };
|
||||
|
||||
const area = d.pow(2);
|
||||
@ -634,7 +631,7 @@ test "Pow" {
|
||||
try std.testing.expectEqual(3, @TypeOf(volume).dims.get(.L));
|
||||
|
||||
// Float test
|
||||
const MeterF = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const MeterF = Scalar(f32, .{ .L = 1 }, .{});
|
||||
const d_f = MeterF{ .value = 2.0 };
|
||||
const area_f = d_f.pow(3);
|
||||
try std.testing.expectEqual(8.0, area_f.value);
|
||||
|
||||
@ -3,6 +3,17 @@ const hlp = @import("helper.zig");
|
||||
const Dimensions = @import("Dimensions.zig");
|
||||
const Dimension = @import("Dimensions.zig").Dimension;
|
||||
|
||||
/// Use to initiate Scalar and Scales type
|
||||
pub const ArgOpts = struct {
|
||||
L: UnitScale = .none,
|
||||
M: UnitScale = .none,
|
||||
T: UnitScale = .none,
|
||||
I: UnitScale = .none,
|
||||
Tp: UnitScale = .none,
|
||||
N: UnitScale = .none,
|
||||
J: UnitScale = .none,
|
||||
};
|
||||
|
||||
/// SI prefix (pico…peta) plus time-unit aliases (min, hour, year).
|
||||
/// The integer value encodes the exponent for SI prefixes (e.g. `k = 3` → 10³),
|
||||
/// and the literal factor for time units (e.g. `hour = 3600`).
|
||||
@ -62,9 +73,9 @@ const Scales = @This();
|
||||
|
||||
data: std.EnumArray(Dimension, UnitScale),
|
||||
|
||||
/// Create a `Scales` from an anonymous struct literal, e.g. `.{ .L = .k, .T = .hour }`.
|
||||
/// Create a `Scales` from a struct literal, e.g. `.{ .L = .k, .T = .hour }`.
|
||||
/// Unspecified dimensions default to `.none` (factor 1).
|
||||
pub fn init(comptime init_val: anytype) Scales {
|
||||
pub fn init(comptime init_val: ArgOpts) Scales {
|
||||
comptime var s = Scales{ .data = std.EnumArray(Dimension, UnitScale).initFill(.none) };
|
||||
inline for (std.meta.fields(@TypeOf(init_val))) |f| {
|
||||
if (comptime hlp.isInt(@TypeOf(@field(init_val, f.name))))
|
||||
|
||||
@ -2,6 +2,7 @@ const std = @import("std");
|
||||
const hlp = @import("helper.zig");
|
||||
|
||||
const Scalar = @import("Scalar.zig").Scalar;
|
||||
const Scalar_ = @import("Scalar.zig").Scalar_;
|
||||
const Scales = @import("Scales.zig");
|
||||
const UnitScale = Scales.UnitScale;
|
||||
const Dimensions = @import("Dimensions.zig");
|
||||
@ -32,13 +33,13 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
}
|
||||
|
||||
/// Element-wise addition. Dimensions must match; scales resolve to the finer of the two.
|
||||
pub inline fn add(self: Self, rhs: anytype) Vector(len, Scalar(
|
||||
pub inline fn add(self: Self, rhs: anytype) Vector(len, Scalar_(
|
||||
T,
|
||||
dims,
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
)) {
|
||||
const Tr = @TypeOf(rhs);
|
||||
var res: Vector(len, Scalar(T, d, hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
var res: Vector(len, Scalar_(T, d, hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = (Q{ .value = v }).add(Tr.ScalarType{ .value = rhs.data[i] });
|
||||
res.data[i] = q.value;
|
||||
@ -46,13 +47,13 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
return res;
|
||||
}
|
||||
/// Element-wise subtraction. Dimensions must match; scales resolve to the finer of the two.
|
||||
pub inline fn sub(self: Self, rhs: anytype) Vector(len, Scalar(
|
||||
pub inline fn sub(self: Self, rhs: anytype) Vector(len, Scalar_(
|
||||
T,
|
||||
dims,
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
)) {
|
||||
const Tr = @TypeOf(rhs);
|
||||
var res: Vector(len, Scalar(T, d, hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
var res: Vector(len, Scalar_(T, d, hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = (Q{ .value = v }).sub(Tr.ScalarType{ .value = rhs.data[i] });
|
||||
res.data[i] = q.value;
|
||||
@ -64,13 +65,13 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
pub inline fn divBy(
|
||||
self: Self,
|
||||
rhs: anytype,
|
||||
) Vector(len, Scalar(
|
||||
) Vector(len, Scalar_(
|
||||
T,
|
||||
dims.sub(@TypeOf(rhs).dims),
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
)) {
|
||||
const Tr = @TypeOf(rhs);
|
||||
var res: Vector(len, Scalar(T, d.sub(Tr.dims), hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
var res: Vector(len, Scalar_(T, d.sub(Tr.dims), hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = (Q{ .value = v }).divBy(Tr.ScalarType{ .value = rhs.data[i] });
|
||||
res.data[i] = q.value;
|
||||
@ -82,13 +83,13 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
pub inline fn mulBy(
|
||||
self: Self,
|
||||
rhs: anytype,
|
||||
) Vector(len, Scalar(
|
||||
) Vector(len, Scalar_(
|
||||
T,
|
||||
dims.add(@TypeOf(rhs).dims),
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
)) {
|
||||
const Tr = @TypeOf(rhs);
|
||||
var res: Vector(len, Scalar(T, d.add(Tr.dims), hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
var res: Vector(len, Scalar_(T, d.add(Tr.dims), hlp.finerScales(Self, @TypeOf(rhs)))) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = (Q{ .value = v }).mulBy(Tr.ScalarType{ .value = rhs.data[i] });
|
||||
res.data[i] = q.value;
|
||||
@ -100,12 +101,12 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
pub inline fn divByScalar(
|
||||
self: Self,
|
||||
scalar: anytype,
|
||||
) Vector(len, Scalar(
|
||||
) Vector(len, Scalar_(
|
||||
T,
|
||||
dims.sub(@TypeOf(scalar).dims),
|
||||
hlp.finerScales(Self, @TypeOf(scalar)),
|
||||
)) {
|
||||
var res: Vector(len, Scalar(T, d.sub(@TypeOf(scalar).dims), hlp.finerScales(Self, @TypeOf(scalar)))) = undefined;
|
||||
var res: Vector(len, Scalar_(T, d.sub(@TypeOf(scalar).dims), hlp.finerScales(Self, @TypeOf(scalar)))) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = Q{ .value = v };
|
||||
res.data[i] = q.divBy(scalar).value;
|
||||
@ -117,12 +118,12 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
pub inline fn mulByScalar(
|
||||
self: Self,
|
||||
scalar: anytype,
|
||||
) Vector(len, Scalar(
|
||||
) Vector(len, Scalar_(
|
||||
T,
|
||||
dims.add(@TypeOf(scalar).dims),
|
||||
hlp.finerScales(Self, @TypeOf(scalar)),
|
||||
)) {
|
||||
var res: Vector(len, Scalar(T, d.add(@TypeOf(scalar).dims), hlp.finerScales(Self, @TypeOf(scalar)))) = undefined;
|
||||
var res: Vector(len, Scalar_(T, d.add(@TypeOf(scalar).dims), hlp.finerScales(Self, @TypeOf(scalar)))) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = Q{ .value = v };
|
||||
res.data[i] = q.mulBy(scalar).value;
|
||||
@ -132,7 +133,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
|
||||
/// Standard dot product. Dimensions are summed (e.g., Force * Distance = Energy).
|
||||
/// Returns a Scalar type with the combined dimensions and finest scale.
|
||||
pub inline fn dot(self: Self, rhs: anytype) Scalar(
|
||||
pub inline fn dot(self: Self, rhs: anytype) Scalar_(
|
||||
T,
|
||||
dims.add(@TypeOf(rhs).dims),
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
@ -150,7 +151,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
|
||||
/// 3D Cross product. Dimensions are summed.
|
||||
/// Only valid for vectors of length 3.
|
||||
pub inline fn cross(self: Self, rhs: anytype) Vector(3, Scalar(
|
||||
pub inline fn cross(self: Self, rhs: anytype) Vector(3, Scalar_(
|
||||
T,
|
||||
dims.add(@TypeOf(rhs).dims),
|
||||
hlp.finerScales(Self, @TypeOf(rhs)),
|
||||
@ -159,7 +160,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
@compileError("Cross product is only defined for Vector(3, ...)");
|
||||
|
||||
const Tr = @TypeOf(rhs);
|
||||
const ResScalar = Scalar(T, d.add(Tr.dims), hlp.finerScales(Self, Tr));
|
||||
const ResScalar = Scalar_(T, d.add(Tr.dims), hlp.finerScales(Self, Tr));
|
||||
const ResVec = Vector(3, ResScalar);
|
||||
|
||||
// Calculation: [y1*z2 - z1*y2, z1*x2 - x1*z2, x1*y2 - y1*x2]
|
||||
@ -202,7 +203,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
|
||||
/// Multiplies all components of the vector together.
|
||||
/// Resulting dimensions are (Original Dims * len).
|
||||
pub inline fn product(self: Self) Scalar(
|
||||
pub inline fn product(self: Self) Scalar_(
|
||||
T,
|
||||
dims.scale(len),
|
||||
scales,
|
||||
@ -215,12 +216,12 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
|
||||
/// Raises every component to a compile-time integer power.
|
||||
/// Dimensions are scaled by the exponent.
|
||||
pub inline fn pow(self: Self, comptime exp: comptime_int) Vector(len, Scalar(
|
||||
pub inline fn pow(self: Self, comptime exp: comptime_int) Vector(len, Scalar_(
|
||||
T,
|
||||
dims.scale(exp),
|
||||
scales,
|
||||
)) {
|
||||
const ResScalar = Scalar(T, dims.scale(exp), s);
|
||||
const ResScalar = Scalar_(T, dims.scale(exp), s);
|
||||
var res: Vector(len, ResScalar) = undefined;
|
||||
inline for (self.data, 0..) |v, i| {
|
||||
const q = Q{ .value = v };
|
||||
@ -436,16 +437,8 @@ pub fn Vector(comptime len: usize, comptime Q: type) type {
|
||||
}
|
||||
|
||||
test "Format VectorX" {
|
||||
const MeterPerSecondSq = Scalar(
|
||||
f32,
|
||||
Dimensions.init(.{ .L = 1, .T = -2 }),
|
||||
Scales.init(.{ .T = .n }),
|
||||
);
|
||||
const KgMeterPerSecond = Scalar(
|
||||
f32,
|
||||
Dimensions.init(.{ .M = 1, .L = 1, .T = -1 }),
|
||||
Scales.init(.{ .M = .k }),
|
||||
);
|
||||
const MeterPerSecondSq = Scalar(f32, .{ .L = 1, .T = -2 }, .{ .T = .n });
|
||||
const KgMeterPerSecond = Scalar(f32, .{ .M = 1, .L = 1, .T = -1 }, .{ .M = .k });
|
||||
|
||||
const accel = MeterPerSecondSq.Vec3.initDefault(9.81);
|
||||
const momentum = KgMeterPerSecond.Vec3{ .data = .{ 43, 0, 11 } };
|
||||
@ -459,7 +452,7 @@ test "Format VectorX" {
|
||||
}
|
||||
|
||||
test "VecX Init and Basic Arithmetic" {
|
||||
const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i32, .{ .L = 1 }, .{});
|
||||
const Vec3M = Meter.Vec3;
|
||||
|
||||
// Test zero, one, initDefault
|
||||
@ -500,8 +493,8 @@ test "VecX Init and Basic Arithmetic" {
|
||||
}
|
||||
|
||||
test "VecX Kinematics (Scalar Mul/Div)" {
|
||||
const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Second = Scalar(i32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i32, .{ .L = 1 }, .{});
|
||||
const Second = Scalar(i32, .{ .T = 1 }, .{});
|
||||
const Vec3M = Meter.Vec3;
|
||||
|
||||
const pos = Vec3M{ .data = .{ 100, 200, 300 } };
|
||||
@ -525,7 +518,7 @@ test "VecX Kinematics (Scalar Mul/Div)" {
|
||||
}
|
||||
|
||||
test "VecX Element-wise Math and Scaling" {
|
||||
const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(i32, .{ .L = 1 }, .{});
|
||||
const Vec3M = Meter.Vec3;
|
||||
|
||||
const v1 = Vec3M{ .data = .{ 10, 20, 30 } };
|
||||
@ -540,8 +533,8 @@ test "VecX Element-wise Math and Scaling" {
|
||||
}
|
||||
|
||||
test "VecX Conversions" {
|
||||
const KiloMeter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const KiloMeter = Scalar(i32, .{ .L = 1 }, .{ .L = .k });
|
||||
const Meter = Scalar(i32, .{ .L = 1 }, .{});
|
||||
|
||||
const v_km = KiloMeter.Vec3{ .data = .{ 1, 2, 3 } };
|
||||
const v_m = v_km.to(Meter);
|
||||
@ -556,8 +549,8 @@ test "VecX Conversions" {
|
||||
}
|
||||
|
||||
test "VecX Length" {
|
||||
const MeterInt = Scalar(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const MeterFloat = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const MeterInt = Scalar(i32, .{ .L = 1 }, .{});
|
||||
const MeterFloat = Scalar(f32, .{ .L = 1 }, .{});
|
||||
|
||||
// Integer length
|
||||
// 3-4-5 triangle on XY plane
|
||||
@ -572,8 +565,8 @@ test "VecX Length" {
|
||||
}
|
||||
|
||||
test "Vector Comparisons" {
|
||||
const Meter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const KiloMeter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(f32, .{ .L = 1 }, .{});
|
||||
const KiloMeter = Scalar(f32, .{ .L = 1 }, .{ .L = .k });
|
||||
|
||||
const v1 = Meter.Vec3{ .data = .{ 1000.0, 500.0, 0.0 } };
|
||||
const v2 = KiloMeter.Vec3{ .data = .{ 1.0, 0.5, 0.0 } };
|
||||
@ -601,8 +594,8 @@ test "Vector Comparisons" {
|
||||
}
|
||||
|
||||
test "Vector vs Scalar Comparisons" {
|
||||
const Meter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const KiloMeter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||
const Meter = Scalar(f32, .{ .L = 1 }, .{});
|
||||
const KiloMeter = Scalar(f32, .{ .L = 1 }, .{ .L = .k });
|
||||
|
||||
const positions = Meter.Vec3{ .data = .{ 500.0, 1200.0, 3000.0 } };
|
||||
const threshold = KiloMeter{ .value = 1.0 }; // 1km (1000m)
|
||||
@ -621,8 +614,8 @@ test "Vector vs Scalar Comparisons" {
|
||||
}
|
||||
|
||||
test "Vector Dot and Cross Products" {
|
||||
const Meter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Newton = Scalar(f32, Dimensions.init(.{ .M = 1, .L = 1, .T = -2 }), Scales.init(.{}));
|
||||
const Meter = Scalar(f32, .{ .L = 1 }, .{});
|
||||
const Newton = Scalar(f32, .{ .M = 1, .L = 1, .T = -2 }, .{});
|
||||
|
||||
const pos = Meter.Vec3{ .data = .{ 10.0, 0.0, 0.0 } };
|
||||
const force = Newton.Vec3{ .data = .{ 5.0, 5.0, 0.0 } };
|
||||
@ -645,7 +638,7 @@ test "Vector Dot and Cross Products" {
|
||||
}
|
||||
|
||||
test "Vector Abs, Pow, Sqrt and Product" {
|
||||
const Meter = Scalar(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||
const Meter = Scalar(f32, .{ .L = 1 }, .{});
|
||||
|
||||
const v1 = Meter.Vec3{ .data = .{ -2.0, 3.0, -4.0 } };
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user