math: Add vector comparison functions (#1131)

This commit is contained in:
Joel 2024-01-06 20:37:58 +01:00 committed by GitHub
parent e9489ee560
commit 59bb156bf9
Failed to generate hash of commit
2 changed files with 59 additions and 7 deletions

View file

@ -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

View file

@ -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.