From 59bb156bf9ff25c6eb7c3ec7a0cf9ac4059c5b94 Mon Sep 17 00:00:00 2001 From: Joel <5474278+noisegul@users.noreply.github.com> Date: Sat, 6 Jan 2024 20:37:58 +0100 Subject: [PATCH] math: Add vector comparison functions (#1131) --- src/math/vec.zig | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ src/testing.zig | 14 ++++++------- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/math/vec.zig b/src/math/vec.zig index 66150ac9..054037d0 100644 --- a/src/math/vec.zig +++ b/src/math/vec.zig @@ -374,9 +374,61 @@ pub fn Vec(comptime n_value: usize, comptime Scalar: type) type { return min_scalar; } + + /// Checks for approximate (absolute tolerance) equality between two vectors + /// of the same type and dimensions + pub inline fn eqlApprox(a: *const VecN, b: *const VecN, tolerance: T) bool { + var i: usize = 0; + while (i < VecN.n) : (i += 1) { + if (!math.eql(T, a.v[i], b.v[i], tolerance)) { + return false; + } + } + return true; + } + + /// Checks for approximate (absolute epsilon tolerance) equality + /// between two vectors of the same type and dimensions + pub inline fn eql(a: *const VecN, b: *const VecN) bool { + return a.eqlApprox(b, math.eps(T)); + } }; } +test "eql_vec2" { + const a: math.Vec2 = math.vec2(92, 103); + const b: math.Vec2 = math.vec2(92, 103); + const c: math.Vec2 = math.vec2(92, 103.2); + + try testing.expect(bool, true).eql(a.eql(&b)); + try testing.expect(bool, false).eql(a.eql(&c)); +} + +test "eql_vec3" { + const a: math.Vec3 = math.vec3(92, 103, 576); + const b: math.Vec3 = math.vec3(92, 103, 576); + const c: math.Vec3 = math.vec3(92.009, 103.2, 578); + + try testing.expect(bool, true).eql(a.eql(&b)); + try testing.expect(bool, false).eql(a.eql(&c)); +} + +test "eqlApprox_vec2" { + const a: math.Vec2 = math.vec2(92.92837, 103.54682); + const b: math.Vec2 = math.vec2(92.92998, 103.54791); + + try testing.expect(bool, true).eql(a.eqlApprox(&b, 1e-2)); + try testing.expect(bool, false).eql(a.eqlApprox(&b, 1e-3)); +} + +test "eqlApprox_vec3" { + const a: math.Vec3 = math.vec3(92.92837, 103.54682, 256.9); + const b: math.Vec3 = math.vec3(92.92998, 103.54791, 256.9); + + try testing.expect(bool, true).eql(a.eqlApprox(&b, 1e-2)); + try testing.expect(bool, false).eql(a.eqlApprox(&b, 1e-3)); +} + test "gpu_compatibility" { // https://www.w3.org/TR/WGSL/#alignment-and-size try testing.expect(usize, 8).eql(@sizeOf(math.Vec2)); // WGSL AlignOf 8, SizeOf 8 diff --git a/src/testing.zig b/src/testing.zig index 5cf15b5c..0c6cf571 100644 --- a/src/testing.zig +++ b/src/testing.zig @@ -8,12 +8,12 @@ fn ExpectFloat(comptime T: type) type { return struct { expected: T, - /// Approximate (absolute epsilon tolerence) equality + /// Approximate (absolute epsilon tolerance) equality pub fn eql(e: *const @This(), actual: T) !void { try e.eqlApprox(actual, math.eps(T)); } - /// Approximate (tolerence) equality + /// Approximate (absolute tolerance) equality pub fn eqlApprox(e: *const @This(), actual: T, tolerance: T) !void { try testing.expectApproxEqAbs(e.expected, actual, tolerance); } @@ -31,12 +31,12 @@ fn ExpectVector(comptime T: type) type { return struct { expected: T, - /// Approximate (absolute epsilon tolerence) equality + /// Approximate (absolute epsilon tolerance) equality pub fn eql(e: *const @This(), actual: T) !void { try e.eqlApprox(actual, math.eps(Elem)); } - /// Approximate (tolerence) equality + /// Approximate (absolute tolerance) equality pub fn eqlApprox(e: *const @This(), actual: T, tolerance: Elem) !void { var i: usize = 0; while (i < len) : (i += 1) { @@ -58,12 +58,12 @@ fn ExpectVecMat(comptime T: type) type { return struct { expected: T, - /// Approximate (absolute epsilon tolerence) equality + /// Approximate (absolute epsilon tolerance) equality pub fn eql(e: *const @This(), actual: T) !void { try e.eqlApprox(actual, math.eps(T.T)); } - /// Approximate (tolerence) equality + /// Approximate (absolute tolerance) equality pub fn eqlApprox(e: *const @This(), actual: T, tolerance: T.T) !void { var i: usize = 0; while (i < T.n) : (i += 1) { @@ -155,7 +155,7 @@ fn Expect(comptime T: type) type { /// Floats, mach.math.Vec, and mach.math.Mat types support: /// /// * `.eql(v)` (epsilon equality) -/// * `.eqlApprox(v, tolerence)` (specific tolerence equality) +/// * `.eqlApprox(v, tolerance)` (specific tolerance equality) /// * `.eqlBinary(v)` binary equality /// /// All other types support only `.eql(v)` binary equality.