Changed QuantityVec3 to QuantityVecX for vectors of any size
This commit is contained in:
parent
de210588ee
commit
fd423f2bf6
250
src/main.zig
250
src/main.zig
@ -11,7 +11,7 @@ pub fn Quantity(T: type, d: Dimensions, s: Scales) type {
|
|||||||
value: T,
|
value: T,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const Vec3: type = QuantityVec3(Self);
|
pub const Vec3: type = QuantityVecX(3, Self);
|
||||||
pub const ValueType: type = T;
|
pub const ValueType: type = T;
|
||||||
|
|
||||||
pub const dims: Dimensions = d;
|
pub const dims: Dimensions = d;
|
||||||
@ -113,8 +113,12 @@ pub fn Quantity(T: type, d: Dimensions, s: Scales) type {
|
|||||||
return .{ .value = @intFromFloat(@round(val_f * ratio)) };
|
return .{ .value = @intFromFloat(@round(val_f * ratio)) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn vecX(self: Self, comptime len: usize) QuantityVecX(len, Self) {
|
||||||
|
return QuantityVecX(len, Self).initDefault(self.value);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn vec3(self: Self) Vec3 {
|
pub fn vec3(self: Self) Vec3 {
|
||||||
return .{ .x = self.value, .y = self.value, .z = self.value };
|
return Vec3.initDefault(self.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(
|
pub fn format(
|
||||||
@ -145,15 +149,13 @@ pub fn Quantity(T: type, d: Dimensions, s: Scales) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn QuantityVec3(Q: type) type {
|
pub fn QuantityVecX(comptime len: usize, comptime Q: type) type {
|
||||||
const T = Q.ValueType;
|
const T = Q.ValueType;
|
||||||
const d: Dimensions = Q.dims;
|
const d: Dimensions = Q.dims;
|
||||||
const s: Scales = Q.scales;
|
const s: Scales = Q.scales;
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
x: T,
|
data: [len]T,
|
||||||
y: T,
|
|
||||||
z: T,
|
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const QuantityType = Q;
|
pub const QuantityType = Q;
|
||||||
@ -161,116 +163,115 @@ pub fn QuantityVec3(Q: type) type {
|
|||||||
pub const dims: Dimensions = d;
|
pub const dims: Dimensions = d;
|
||||||
pub const scales = s;
|
pub const scales = s;
|
||||||
|
|
||||||
pub const zero = Self{ .x = 0, .y = 0, .z = 0 };
|
pub const zero = initDefault(0);
|
||||||
pub const one = Self{ .x = 1, .y = 1, .z = 1 };
|
pub const one = initDefault(1);
|
||||||
|
|
||||||
pub fn initDefault(v: T) Self {
|
pub fn initDefault(v: T) Self {
|
||||||
return .{ .x = v, .y = v, .z = v };
|
var data: [len]T = undefined;
|
||||||
|
for (&data) |*item| item.* = v;
|
||||||
|
return .{ .data = data };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(self: Self, rhs: anytype) QuantityVec3(Quantity(T, d, s.min(@TypeOf(rhs).scales))) {
|
pub fn add(self: Self, rhs: anytype) QuantityVecX(len, Quantity(T, d, s.min(@TypeOf(rhs).scales))) {
|
||||||
const Tr = @TypeOf(rhs);
|
const Tr = @TypeOf(rhs);
|
||||||
// We leverage the logic in the scalar Quantity.add
|
var res: QuantityVecX(len, Quantity(T, d, s.min(Tr.scales))) = undefined;
|
||||||
const qx = (Q{ .value = self.x }).add(Tr.QuantityType{ .value = rhs.x });
|
for (self.data, 0..) |v, i| {
|
||||||
const qy = (Q{ .value = self.y }).add(Tr.QuantityType{ .value = rhs.y });
|
const q = (Q{ .value = v }).add(Tr.QuantityType{ .value = rhs.data[i] });
|
||||||
const qz = (Q{ .value = self.z }).add(Tr.QuantityType{ .value = rhs.z });
|
res.data[i] = q.value;
|
||||||
|
}
|
||||||
return .{
|
return res;
|
||||||
.x = qx.value,
|
|
||||||
.y = qy.value,
|
|
||||||
.z = qz.value,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub(self: Self, rhs: anytype) QuantityVec3(Quantity(T, d, s.min(@TypeOf(rhs).scales))) {
|
pub fn sub(self: Self, rhs: anytype) QuantityVecX(len, Quantity(T, d, s.min(@TypeOf(rhs).scales))) {
|
||||||
const Tr = @TypeOf(rhs);
|
const Tr = @TypeOf(rhs);
|
||||||
const qx = (Q{ .value = self.x }).sub(Tr.QuantityType{ .value = rhs.x });
|
var res: QuantityVecX(len, Quantity(T, d, s.min(Tr.scales))) = undefined;
|
||||||
const qy = (Q{ .value = self.y }).sub(Tr.QuantityType{ .value = rhs.y });
|
for (self.data, 0..) |v, i| {
|
||||||
const qz = (Q{ .value = self.z }).sub(Tr.QuantityType{ .value = rhs.z });
|
const q = (Q{ .value = v }).sub(Tr.QuantityType{ .value = rhs.data[i] });
|
||||||
|
res.data[i] = q.value;
|
||||||
return .{
|
}
|
||||||
.x = qx.value,
|
return res;
|
||||||
.y = qy.value,
|
|
||||||
.z = qz.value,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn divBy(
|
pub fn divBy(
|
||||||
self: Self,
|
self: Self,
|
||||||
rhs: anytype,
|
rhs: anytype,
|
||||||
) QuantityVec3(Quantity(T, d.sub(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) {
|
) QuantityVecX(len, Quantity(T, d.sub(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) {
|
||||||
const Tr = @TypeOf(rhs);
|
const Tr = @TypeOf(rhs);
|
||||||
return .{
|
var res: QuantityVecX(len, Quantity(T, d.sub(Tr.dims), s.min(Tr.scales))) = undefined;
|
||||||
.x = (Q{ .value = self.x }).divBy(Tr.QuantityType{ .value = rhs.x }).value,
|
for (self.data, 0..) |v, i| {
|
||||||
.y = (Q{ .value = self.y }).divBy(Tr.QuantityType{ .value = rhs.y }).value,
|
const q = (Q{ .value = v }).divBy(Tr.QuantityType{ .value = rhs.data[i] });
|
||||||
.z = (Q{ .value = self.z }).divBy(Tr.QuantityType{ .value = rhs.z }).value,
|
res.data[i] = q.value;
|
||||||
};
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mulBy(
|
pub fn mulBy(
|
||||||
self: Self,
|
self: Self,
|
||||||
rhs: anytype,
|
rhs: anytype,
|
||||||
) QuantityVec3(Quantity(T, d.sub(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) {
|
) QuantityVecX(len, Quantity(T, d.add(@TypeOf(rhs).dims), s.min(@TypeOf(rhs).scales))) {
|
||||||
const Tr = @TypeOf(rhs);
|
const Tr = @TypeOf(rhs);
|
||||||
return .{
|
var res: QuantityVecX(len, Quantity(T, d.add(Tr.dims), s.min(Tr.scales))) = undefined;
|
||||||
.x = (Q{ .value = self.x }).mulBy(Tr.QuantityType{ .value = rhs.x }).value,
|
for (self.data, 0..) |v, i| {
|
||||||
.y = (Q{ .value = self.y }).mulBy(Tr.QuantityType{ .value = rhs.y }).value,
|
const q = (Q{ .value = v }).mulBy(Tr.QuantityType{ .value = rhs.data[i] });
|
||||||
.z = (Q{ .value = self.z }).mulBy(Tr.QuantityType{ .value = rhs.z }).value,
|
res.data[i] = q.value;
|
||||||
};
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn divByScalar(
|
pub fn divByScalar(
|
||||||
self: Self,
|
self: Self,
|
||||||
scalar: anytype,
|
scalar: anytype,
|
||||||
) QuantityVec3(Quantity(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) {
|
) QuantityVecX(len, Quantity(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) {
|
||||||
const q_x = Q{ .value = self.x };
|
var res: QuantityVecX(len, Quantity(T, d.sub(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) = undefined;
|
||||||
const q_y = Q{ .value = self.y };
|
for (self.data, 0..) |v, i| {
|
||||||
const q_z = Q{ .value = self.z };
|
const q = Q{ .value = v };
|
||||||
|
res.data[i] = q.divBy(scalar).value;
|
||||||
return .{
|
}
|
||||||
.x = q_x.divBy(scalar).value,
|
return res;
|
||||||
.y = q_y.divBy(scalar).value,
|
|
||||||
.z = q_z.divBy(scalar).value,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mulByScalar(
|
pub fn mulByScalar(
|
||||||
self: Self,
|
self: Self,
|
||||||
scalar: anytype,
|
scalar: anytype,
|
||||||
) QuantityVec3(Quantity(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) {
|
) QuantityVecX(len, Quantity(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) {
|
||||||
const q_x = Q{ .value = self.x };
|
var res: QuantityVecX(len, Quantity(T, d.add(@TypeOf(scalar).dims), s.min(@TypeOf(scalar).scales))) = undefined;
|
||||||
const q_y = Q{ .value = self.y };
|
for (self.data, 0..) |v, i| {
|
||||||
const q_z = Q{ .value = self.z };
|
const q = Q{ .value = v };
|
||||||
|
res.data[i] = q.mulBy(scalar).value;
|
||||||
return .{
|
}
|
||||||
.x = q_x.mulBy(scalar).value,
|
return res;
|
||||||
.y = q_y.mulBy(scalar).value,
|
|
||||||
.z = q_z.mulBy(scalar).value,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn negate(self: Self) Self {
|
pub fn negate(self: Self) Self {
|
||||||
return .{ .x = -self.x, .y = -self.y, .z = -self.z };
|
var res: Self = undefined;
|
||||||
|
for (self.data, 0..) |v, i| {
|
||||||
|
res.data[i] = -v;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scale(self: Self, rhs: T) Self {
|
pub fn scale(self: Self, rhs: T) Self {
|
||||||
return .{
|
var res: Self = undefined;
|
||||||
.x = (Q{ .value = self.x }).scale(rhs).value,
|
for (self.data, 0..) |v, i| {
|
||||||
.y = (Q{ .value = self.y }).scale(rhs).value,
|
res.data[i] = (Q{ .value = v }).scale(rhs).value;
|
||||||
.z = (Q{ .value = self.z }).scale(rhs).value,
|
}
|
||||||
};
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to(self: Self, comptime DestQ: type) QuantityVec3(DestQ) {
|
pub fn to(self: Self, comptime DestQ: type) QuantityVecX(len, DestQ) {
|
||||||
return .{
|
var res: QuantityVecX(len, DestQ) = undefined;
|
||||||
.x = (Q{ .value = self.x }).to(DestQ).value,
|
for (self.data, 0..) |v, i| {
|
||||||
.y = (Q{ .value = self.y }).to(DestQ).value,
|
res.data[i] = (Q{ .value = v }).to(DestQ).value;
|
||||||
.z = (Q{ .value = self.z }).to(DestQ).value,
|
}
|
||||||
};
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lengthSqr(self: Self) T {
|
pub fn lengthSqr(self: Self) T {
|
||||||
return self.x * self.x + self.y * self.y + self.z * self.z;
|
var sum: T = 0;
|
||||||
|
for (self.data) |v| {
|
||||||
|
sum += v * v;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(self: Self) T {
|
pub fn length(self: Self) T {
|
||||||
@ -289,7 +290,12 @@ pub fn QuantityVec3(Q: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: Self, writer: *std.Io.Writer) !void {
|
pub fn format(self: Self, writer: *std.Io.Writer) !void {
|
||||||
try writer.print("({d:.2}, {d:.2}, {d:.2})", .{ self.x, self.y, self.z });
|
try writer.writeAll("(");
|
||||||
|
for (self.data, 0..) |v, i| {
|
||||||
|
if (i > 0) try writer.writeAll(", ");
|
||||||
|
try writer.print("{d:.2}", .{v});
|
||||||
|
}
|
||||||
|
try writer.writeAll(")");
|
||||||
var iter = std.EnumSet(Dimension).initFull().iterator();
|
var iter = std.EnumSet(Dimension).initFull().iterator();
|
||||||
var first = true;
|
var first = true;
|
||||||
while (iter.next()) |bu| {
|
while (iter.next()) |bu| {
|
||||||
@ -542,7 +548,7 @@ test "Format Quantity" {
|
|||||||
std.debug.print("Momentum: {f}\n", .{momentum});
|
std.debug.print("Momentum: {f}\n", .{momentum});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Format Vector3" {
|
test "Format VectorX" {
|
||||||
const MeterPerSecondSq = Quantity(
|
const MeterPerSecondSq = Quantity(
|
||||||
f32,
|
f32,
|
||||||
Dimensions.init(.{ .L = 1, .T = -2 }),
|
Dimensions.init(.{ .L = 1, .T = -2 }),
|
||||||
@ -555,123 +561,127 @@ test "Format Vector3" {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const accel = MeterPerSecondSq.Vec3.initDefault(9.81);
|
const accel = MeterPerSecondSq.Vec3.initDefault(9.81);
|
||||||
const momentum = KgMeterPerSecond.Vec3{ .x = 43, .y = 0, .z = 11 };
|
const momentum = KgMeterPerSecond.Vec3{ .data = .{ 43, 0, 11 } };
|
||||||
|
|
||||||
std.debug.print("Acceleration: {f}\n", .{accel});
|
std.debug.print("Acceleration: {f}\n", .{accel});
|
||||||
std.debug.print("Momentum: {f}\n", .{momentum});
|
std.debug.print("Momentum: {f}\n", .{momentum});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Vec3 Init and Basic Arithmetic" {
|
test "VecX Init and Basic Arithmetic" {
|
||||||
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||||
const Vec3M = Meter.Vec3;
|
const Vec3M = Meter.Vec3;
|
||||||
|
|
||||||
// Test zero, one, initDefault
|
// Test zero, one, initDefault
|
||||||
const v_zero = Vec3M.zero;
|
const v_zero = Vec3M.zero;
|
||||||
try std.testing.expectEqual(0, v_zero.x);
|
try std.testing.expectEqual(0, v_zero.data[0]);
|
||||||
|
try std.testing.expectEqual(0, v_zero.data[1]);
|
||||||
|
try std.testing.expectEqual(0, v_zero.data[2]);
|
||||||
|
|
||||||
const v_one = Vec3M.one;
|
const v_one = Vec3M.one;
|
||||||
try std.testing.expectEqual(1, v_one.x);
|
try std.testing.expectEqual(1, v_one.data[0]);
|
||||||
|
try std.testing.expectEqual(1, v_one.data[1]);
|
||||||
|
try std.testing.expectEqual(1, v_one.data[2]);
|
||||||
|
|
||||||
const v_def = Vec3M.initDefault(5);
|
const v_def = Vec3M.initDefault(5);
|
||||||
try std.testing.expectEqual(5, v_def.x);
|
try std.testing.expectEqual(5, v_def.data[0]);
|
||||||
try std.testing.expectEqual(5, v_def.y);
|
try std.testing.expectEqual(5, v_def.data[1]);
|
||||||
try std.testing.expectEqual(5, v_def.z);
|
try std.testing.expectEqual(5, v_def.data[2]);
|
||||||
|
|
||||||
// Test add and sub
|
// Test add and sub
|
||||||
const v1 = Vec3M{ .x = 10, .y = 20, .z = 30 };
|
const v1 = Vec3M{ .data = .{ 10, 20, 30 } };
|
||||||
const v2 = Vec3M{ .x = 2, .y = 4, .z = 6 };
|
const v2 = Vec3M{ .data = .{ 2, 4, 6 } };
|
||||||
|
|
||||||
const added = v1.add(v2);
|
const added = v1.add(v2);
|
||||||
try std.testing.expectEqual(12, added.x);
|
try std.testing.expectEqual(12, added.data[0]);
|
||||||
try std.testing.expectEqual(24, added.y);
|
try std.testing.expectEqual(24, added.data[1]);
|
||||||
try std.testing.expectEqual(36, added.z);
|
try std.testing.expectEqual(36, added.data[2]);
|
||||||
|
|
||||||
const subbed = v1.sub(v2);
|
const subbed = v1.sub(v2);
|
||||||
try std.testing.expectEqual(8, subbed.x);
|
try std.testing.expectEqual(8, subbed.data[0]);
|
||||||
try std.testing.expectEqual(16, subbed.y);
|
try std.testing.expectEqual(16, subbed.data[1]);
|
||||||
try std.testing.expectEqual(24, subbed.z);
|
try std.testing.expectEqual(24, subbed.data[2]);
|
||||||
|
|
||||||
// Test negate
|
// Test negate
|
||||||
const neg = v1.negate();
|
const neg = v1.negate();
|
||||||
try std.testing.expectEqual(-10, neg.x);
|
try std.testing.expectEqual(-10, neg.data[0]);
|
||||||
try std.testing.expectEqual(-20, neg.y);
|
try std.testing.expectEqual(-20, neg.data[1]);
|
||||||
try std.testing.expectEqual(-30, neg.z);
|
try std.testing.expectEqual(-30, neg.data[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Vec3 Kinematics (Scalar Mul/Div)" {
|
test "VecX Kinematics (Scalar Mul/Div)" {
|
||||||
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||||
const Second = Quantity(i32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
const Second = Quantity(i32, Dimensions.init(.{ .T = 1 }), Scales.init(.{}));
|
||||||
const Vec3M = Meter.Vec3;
|
const Vec3M = Meter.Vec3;
|
||||||
|
|
||||||
const pos = Vec3M{ .x = 100, .y = 200, .z = 300 };
|
const pos = Vec3M{ .data = .{ 100, 200, 300 } };
|
||||||
const time = Second{ .value = 10 };
|
const time = Second{ .value = 10 };
|
||||||
|
|
||||||
// Vector divided by scalar Quantity (Velocity = Position / Time)
|
// Vector divided by scalar Quantity (Velocity = Position / Time)
|
||||||
const vel = pos.divByScalar(time);
|
const vel = pos.divByScalar(time);
|
||||||
try std.testing.expectEqual(10, vel.x);
|
try std.testing.expectEqual(10, vel.data[0]);
|
||||||
try std.testing.expectEqual(20, vel.y);
|
try std.testing.expectEqual(20, vel.data[1]);
|
||||||
try std.testing.expectEqual(30, vel.z);
|
try std.testing.expectEqual(30, vel.data[2]);
|
||||||
try std.testing.expectEqual(1, @TypeOf(vel).dims.get(.L));
|
try std.testing.expectEqual(1, @TypeOf(vel).dims.get(.L));
|
||||||
try std.testing.expectEqual(-1, @TypeOf(vel).dims.get(.T));
|
try std.testing.expectEqual(-1, @TypeOf(vel).dims.get(.T));
|
||||||
|
|
||||||
// Vector multiplied by scalar Quantity (Position = Velocity * Time)
|
// Vector multiplied by scalar Quantity (Position = Velocity * Time)
|
||||||
const new_pos = vel.mulByScalar(time);
|
const new_pos = vel.mulByScalar(time);
|
||||||
try std.testing.expectEqual(100, new_pos.x);
|
try std.testing.expectEqual(100, new_pos.data[0]);
|
||||||
try std.testing.expectEqual(200, new_pos.y);
|
try std.testing.expectEqual(200, new_pos.data[1]);
|
||||||
try std.testing.expectEqual(300, new_pos.z);
|
try std.testing.expectEqual(300, new_pos.data[2]);
|
||||||
try std.testing.expectEqual(1, @TypeOf(new_pos).dims.get(.L));
|
try std.testing.expectEqual(1, @TypeOf(new_pos).dims.get(.L));
|
||||||
try std.testing.expectEqual(0, @TypeOf(new_pos).dims.get(.T));
|
try std.testing.expectEqual(0, @TypeOf(new_pos).dims.get(.T));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Vec3 Element-wise Math and Scaling" {
|
test "VecX Element-wise Math and Scaling" {
|
||||||
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||||
const Vec3M = Meter.Vec3;
|
const Vec3M = Meter.Vec3;
|
||||||
|
|
||||||
const v1 = Vec3M{ .x = 10, .y = 20, .z = 30 };
|
const v1 = Vec3M{ .data = .{ 10, 20, 30 } };
|
||||||
const v2 = Vec3M{ .x = 2, .y = 5, .z = 10 };
|
const v2 = Vec3M{ .data = .{ 2, 5, 10 } };
|
||||||
|
|
||||||
// Element-wise division
|
// Element-wise division
|
||||||
const div = v1.divBy(v2);
|
const div = v1.divBy(v2);
|
||||||
try std.testing.expectEqual(5, div.x);
|
try std.testing.expectEqual(5, div.data[0]);
|
||||||
try std.testing.expectEqual(4, div.y);
|
try std.testing.expectEqual(4, div.data[1]);
|
||||||
try std.testing.expectEqual(3, div.z);
|
try std.testing.expectEqual(3, div.data[2]);
|
||||||
try std.testing.expectEqual(0, @TypeOf(div).dims.get(.L)); // M / M = Dimensionless
|
try std.testing.expectEqual(0, @TypeOf(div).dims.get(.L)); // M / M = Dimensionless
|
||||||
|
|
||||||
// Scale by primitive
|
// Scale by primitive
|
||||||
const scaled = v1.scale(2);
|
const scaled = v1.scale(2);
|
||||||
try std.testing.expectEqual(20, scaled.x);
|
try std.testing.expectEqual(20, scaled.data[0]);
|
||||||
try std.testing.expectEqual(40, scaled.y);
|
try std.testing.expectEqual(40, scaled.data[1]);
|
||||||
try std.testing.expectEqual(60, scaled.z);
|
try std.testing.expectEqual(60, scaled.data[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Vec3 Conversions" {
|
test "VecX Conversions" {
|
||||||
const KiloMeter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
const KiloMeter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{ .L = .k }));
|
||||||
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
const Meter = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||||
|
|
||||||
const v_km = KiloMeter.Vec3{ .x = 1, .y = 2, .z = 3 };
|
const v_km = KiloMeter.Vec3{ .data = .{ 1, 2, 3 } };
|
||||||
const v_m = v_km.to(Meter);
|
const v_m = v_km.to(Meter);
|
||||||
|
|
||||||
try std.testing.expectEqual(1000, v_m.x);
|
try std.testing.expectEqual(1000, v_m.data[0]);
|
||||||
try std.testing.expectEqual(2000, v_m.y);
|
try std.testing.expectEqual(2000, v_m.data[1]);
|
||||||
try std.testing.expectEqual(3000, v_m.z);
|
try std.testing.expectEqual(3000, v_m.data[2]);
|
||||||
|
|
||||||
// Type checking the result
|
// Type checking the result
|
||||||
try std.testing.expectEqual(1, @TypeOf(v_m).dims.get(.L));
|
try std.testing.expectEqual(1, @TypeOf(v_m).dims.get(.L));
|
||||||
try std.testing.expectEqual(UnitScale.none, @TypeOf(v_m).scales.get(.L));
|
try std.testing.expectEqual(UnitScale.none, @TypeOf(v_m).scales.get(.L));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Vec3 Length" {
|
test "VecX Length" {
|
||||||
const MeterInt = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
const MeterInt = Quantity(i32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||||
const MeterFloat = Quantity(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
const MeterFloat = Quantity(f32, Dimensions.init(.{ .L = 1 }), Scales.init(.{}));
|
||||||
|
|
||||||
// Integer length (using your custom isqrt)
|
// Integer length (using your custom isqrt)
|
||||||
// 3-4-5 triangle on XY plane
|
// 3-4-5 triangle on XY plane
|
||||||
const v_int = MeterInt.Vec3{ .x = 3, .y = 4, .z = 0 };
|
const v_int = MeterInt.Vec3{ .data = .{ 3, 4, 0 } };
|
||||||
try std.testing.expectEqual(25, v_int.lengthSqr());
|
try std.testing.expectEqual(25, v_int.lengthSqr());
|
||||||
try std.testing.expectEqual(5, v_int.length());
|
try std.testing.expectEqual(5, v_int.length());
|
||||||
|
|
||||||
// Float length
|
// Float length
|
||||||
const v_float = MeterFloat.Vec3{ .x = 3.0, .y = 4.0, .z = 0.0 };
|
const v_float = MeterFloat.Vec3{ .data = .{ 3.0, 4.0, 0.0 } };
|
||||||
try std.testing.expectApproxEqAbs(@as(f32, 25.0), v_float.lengthSqr(), 1e-4);
|
try std.testing.expectApproxEqAbs(@as(f32, 25.0), v_float.lengthSqr(), 1e-4);
|
||||||
try std.testing.expectApproxEqAbs(@as(f32, 5.0), v_float.length(), 1e-4);
|
try std.testing.expectApproxEqAbs(@as(f32, 5.0), v_float.length(), 1e-4);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user