math: zig fmt
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
12e69752d3
commit
dc5c1f69a6
1 changed files with 123 additions and 169 deletions
|
|
@ -92,7 +92,6 @@ pub const Rectangle = struct {
|
||||||
try testing.expect(Vec2, vec2(1.0, 1.0)).eql(v[2]);
|
try testing.expect(Vec2, vec2(1.0, 1.0)).eql(v[2]);
|
||||||
try testing.expect(Vec2, vec2(0.0, 1.0)).eql(v[3]);
|
try testing.expect(Vec2, vec2(0.0, 1.0)).eql(v[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A circle shape defined by position and radius.
|
// A circle shape defined by position and radius.
|
||||||
|
|
@ -320,7 +319,6 @@ pub const Point = struct {
|
||||||
try testing.expect(bool, Point.collidesLine(Point{ .pos = vec2(0.0, 0.09) }, l)).eql(true);
|
try testing.expect(bool, Point.collidesLine(Point{ .pos = vec2(0.0, 0.09) }, l)).eql(true);
|
||||||
try testing.expect(bool, Point.collidesLine(Point{ .pos = vec2(0.0, 1.0) }, l)).eql(false);
|
try testing.expect(bool, Point.collidesLine(Point{ .pos = vec2(0.0, 1.0) }, l)).eql(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A line specified by a start and endpoint and a threshold for the line thickness.
|
/// A line specified by a start and endpoint and a threshold for the line thickness.
|
||||||
|
|
@ -345,24 +343,17 @@ pub const Line = struct {
|
||||||
|
|
||||||
test collidesLine {
|
test collidesLine {
|
||||||
const l0 = Line{ .start = vec2(-1.0, -1.0), .end = vec2(1.0, 1.0), .threshold = 0.0 };
|
const l0 = Line{ .start = vec2(-1.0, -1.0), .end = vec2(1.0, 1.0), .threshold = 0.0 };
|
||||||
try testing.expect(bool, true).eql(
|
try testing.expect(bool, true).eql(l0.collidesLine(Line{ .start = vec2(-1.0, 1.0), .end = vec2(1.0, -1.0), .threshold = 0.0 }));
|
||||||
l0.collidesLine(Line{.start = vec2(-1.0, 1.0), .end = vec2(1.0, -1.0), .threshold=0.0}));
|
try testing.expect(bool, true).eql(l0.collidesLine(Line{ .start = vec2(-10.0, 0.0), .end = vec2(10.0, 0.0), .threshold = 0.0 }));
|
||||||
try testing.expect(bool, true).eql(
|
try testing.expect(bool, true).eql(l0.collidesLine(Line{ .start = vec2(-10.0, 1.0), .end = vec2(10.0, 1.0), .threshold = 0.0 }));
|
||||||
l0.collidesLine(Line{.start = vec2(-10.0, 0.0), .end = vec2(10.0, 0.0), .threshold=0.0}));
|
try testing.expect(bool, true).eql(l0.collidesLine(Line{ .start = vec2(-10.0, -1.0), .end = vec2(10.0, -1.0), .threshold = 0.0 }));
|
||||||
try testing.expect(bool, true).eql(
|
|
||||||
l0.collidesLine(Line{.start = vec2(-10.0, 1.0), .end = vec2(10.0, 1.0), .threshold=0.0}));
|
|
||||||
try testing.expect(bool, true).eql(
|
|
||||||
l0.collidesLine(Line{.start = vec2(-10.0, -1.0), .end = vec2(10.0, -1.0), .threshold=0.0}));
|
|
||||||
|
|
||||||
// TODO: fails if same line
|
// TODO: fails if same line
|
||||||
//try testing.expect(bool, true).eql(
|
//try testing.expect(bool, true).eql(
|
||||||
// l0.collidesLine(l0));
|
// l0.collidesLine(l0));
|
||||||
|
|
||||||
try testing.expect(bool, false).eql(
|
try testing.expect(bool, false).eql(l0.collidesLine(Line{ .start = vec2(-1.1, -1.1), .end = vec2(1.1, 1.1), .threshold = 0.0 }));
|
||||||
l0.collidesLine(Line{.start = vec2(-1.1, -1.1), .end = vec2(1.1, 1.1), .threshold=0.0}));
|
try testing.expect(bool, false).eql(l0.collidesLine(Line{ .start = vec2(-10.0, 2.0), .end = vec2(10.0, 2.0), .threshold = 0.0 }));
|
||||||
try testing.expect(bool, false).eql(
|
|
||||||
l0.collidesLine(Line{.start = vec2(-10.0, 2.0), .end = vec2(10.0, 2.0), .threshold=0.0}));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -403,13 +394,7 @@ test minmaxProjectionDistance {
|
||||||
const n_up = vec2(0.0, 1.0);
|
const n_up = vec2(0.0, 1.0);
|
||||||
const n_right = vec2(1.0, 0.0);
|
const n_right = vec2(1.0, 0.0);
|
||||||
const v0 = vec2(0.0, 0.0);
|
const v0 = vec2(0.0, 0.0);
|
||||||
const v = [_]Vec2{
|
const v = [_]Vec2{ vec2(2.0, 0.0), vec2(1.0, 1.0), vec2(0.0, -2.0), vec2(-1.0, 2.0), vec2(-2.0, 1.0) };
|
||||||
vec2(2.0, 0.0),
|
|
||||||
vec2(1.0, 1.0),
|
|
||||||
vec2(0.0, -2.0),
|
|
||||||
vec2(-1.0, 2.0),
|
|
||||||
vec2(-2.0, 1.0)
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const minmax = minmaxProjectionDistance(n_up, v0, &v);
|
const minmax = minmaxProjectionDistance(n_up, v0, &v);
|
||||||
|
|
@ -422,22 +407,18 @@ test minmaxProjectionDistance {
|
||||||
try testing.expect(f32, -2.0).eql(minmax[0]);
|
try testing.expect(f32, -2.0).eql(minmax[0]);
|
||||||
try testing.expect(f32, 2.0).eql(minmax[1]);
|
try testing.expect(f32, 2.0).eql(minmax[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexDepthResult = struct {
|
const VertexDepthResult = struct {
|
||||||
v0: Vec2 = undefined,
|
v0: Vec2 = undefined,
|
||||||
v1: ?Vec2 = null,
|
v1: ?Vec2 = null,
|
||||||
/// Depth of vertex. Positive in the opposite direction of the normal.
|
/// Depth of vertex. Positive in the opposite direction of the normal.
|
||||||
d: f32
|
d: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Find the vertex in v that is deepest behind the line defined by the point v0 and normal n.
|
/// Find the vertex in v that is deepest behind the line defined by the point v0 and normal n.
|
||||||
pub fn findDeepestVertex(n: Vec2, v0: Vec2, v: []const Vec2) VertexDepthResult {
|
pub fn findDeepestVertex(n: Vec2, v0: Vec2, v: []const Vec2) VertexDepthResult {
|
||||||
var min_depth = VertexDepthResult{
|
var min_depth = VertexDepthResult{ .v0 = v[0], .d = n.dot(&v[0].sub(&v0)) };
|
||||||
.v0 = v[0],
|
|
||||||
.d = n.dot(&v[0].sub(&v0))
|
|
||||||
};
|
|
||||||
for (v[1..]) |vb| {
|
for (v[1..]) |vb| {
|
||||||
const d = n.dot(&vb.sub(&v0));
|
const d = n.dot(&vb.sub(&v0));
|
||||||
if (d < min_depth.d) {
|
if (d < min_depth.d) {
|
||||||
|
|
@ -463,7 +444,7 @@ test findDeepestVertex {
|
||||||
vec2(1.0, 1.0),
|
vec2(1.0, 1.0),
|
||||||
vec2(0.0, -2.0), // Deepest
|
vec2(0.0, -2.0), // Deepest
|
||||||
vec2(-1.0, 2.0),
|
vec2(-1.0, 2.0),
|
||||||
vec2(-2.0, 1.0)
|
vec2(-2.0, 1.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
const depth = findDeepestVertex(n_up, v0, &v);
|
const depth = findDeepestVertex(n_up, v0, &v);
|
||||||
|
|
@ -478,7 +459,7 @@ test findDeepestVertex {
|
||||||
vec2(1.0, 1.0),
|
vec2(1.0, 1.0),
|
||||||
vec2(0.0, -3.0), // Deepest
|
vec2(0.0, -3.0), // Deepest
|
||||||
vec2(-1.0, -3.0), // Deepest
|
vec2(-1.0, -3.0), // Deepest
|
||||||
vec2(-2.0, 1.0)
|
vec2(-2.0, 1.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
const depth = findDeepestVertex(n_up, v0, &v);
|
const depth = findDeepestVertex(n_up, v0, &v);
|
||||||
|
|
@ -493,7 +474,7 @@ test findDeepestVertex {
|
||||||
vec2(2.0, 0.5), // Closest
|
vec2(2.0, 0.5), // Closest
|
||||||
vec2(1.0, 1.0),
|
vec2(1.0, 1.0),
|
||||||
vec2(0.0, 3.0),
|
vec2(0.0, 3.0),
|
||||||
vec2(-2.0, 1.0)
|
vec2(-2.0, 1.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
const depth = findDeepestVertex(n_up, v0, &v);
|
const depth = findDeepestVertex(n_up, v0, &v);
|
||||||
|
|
@ -501,7 +482,6 @@ test findDeepestVertex {
|
||||||
try testing.expect(?Vec2, null).eql(depth.v1);
|
try testing.expect(?Vec2, null).eql(depth.v1);
|
||||||
try testing.expect(f32, -0.5).eql(depth.d);
|
try testing.expect(f32, -0.5).eql(depth.d);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains information to separate two colliding shapes.
|
/// Contains information to separate two colliding shapes.
|
||||||
|
|
@ -571,10 +551,7 @@ test findMinSeparation {
|
||||||
try testing.expect(f32, 0.25).eql(result.?.d);
|
try testing.expect(f32, 0.25).eql(result.?.d);
|
||||||
|
|
||||||
// Not colliding - bottom edge of triangle_0 separates the two
|
// Not colliding - bottom edge of triangle_0 separates the two
|
||||||
try testing.expect(?SeparationResult, null).eql(
|
try testing.expect(?SeparationResult, null).eql(findMinSeparation(&triangle_2, &triangle_0));
|
||||||
findMinSeparation(&triangle_2, &triangle_0)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute a Contact report between polygon_a and polygon_b if they are colliding.
|
/// Compute a Contact report between polygon_a and polygon_b if they are colliding.
|
||||||
|
|
@ -612,11 +589,7 @@ pub fn polygonPolygonContact(polygon_a: []const Vec2, polygon_b: []const Vec2) ?
|
||||||
} else {
|
} else {
|
||||||
// Paralell edges - find two contact points
|
// Paralell edges - find two contact points
|
||||||
const edge = vec2(min_separation_a.n.y(), -min_separation_a.n.x());
|
const edge = vec2(min_separation_a.n.y(), -min_separation_a.n.x());
|
||||||
const vertices = [_]Vec2{
|
const vertices = [_]Vec2{ min_separation_a.v0, min_separation_a.v1.?, min_separation_b.v0, min_separation_b.v1.? };
|
||||||
min_separation_a.v0,
|
|
||||||
min_separation_a.v1.?,
|
|
||||||
min_separation_b.v0,
|
|
||||||
min_separation_b.v1.?};
|
|
||||||
const from_a = [4]bool{ true, true, false, false };
|
const from_a = [4]bool{ true, true, false, false };
|
||||||
var distances: [4]f32 = undefined;
|
var distances: [4]f32 = undefined;
|
||||||
for (vertices, &distances) |v, *d| {
|
for (vertices, &distances) |v, *d| {
|
||||||
|
|
@ -636,10 +609,8 @@ pub fn polygonPolygonContact(polygon_a: []const Vec2, polygon_b: []const Vec2) ?
|
||||||
|
|
||||||
depth = min_separation_a.d;
|
depth = min_separation_a.d;
|
||||||
normal = min_separation_a.n.mulScalar(-1.0);
|
normal = min_separation_a.n.mulScalar(-1.0);
|
||||||
cp1_a = if (from_a[idx[1]]) vertices[idx[1]]
|
cp1_a = if (from_a[idx[1]]) vertices[idx[1]] else vertices[idx[1]].add(&normal.mulScalar(depth));
|
||||||
else vertices[idx[1]].add(&normal.mulScalar(depth));
|
cp2_a = if (from_a[idx[2]]) vertices[idx[2]] else vertices[idx[2]].add(&normal.mulScalar(depth));
|
||||||
cp2_a = if (from_a[idx[2]]) vertices[idx[2]]
|
|
||||||
else vertices[idx[2]].add(&normal.mulScalar(depth));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -730,15 +701,7 @@ pub fn circlePolygonContact(circle_a: Circle, polygon_b: []const Vec2) ?Contact
|
||||||
var cp1_a: ?Vec2 = null;
|
var cp1_a: ?Vec2 = null;
|
||||||
|
|
||||||
var v0 = polygon_b[polygon_b.len - 1];
|
var v0 = polygon_b[polygon_b.len - 1];
|
||||||
var min_result = struct {
|
var min_result = struct { n: Vec2, d: f32, i: usize }{ .n = vec2(0.0, 0.0), .d = std.math.floatMax(f32), .i = undefined };
|
||||||
n: Vec2,
|
|
||||||
d: f32,
|
|
||||||
i: usize
|
|
||||||
}{
|
|
||||||
.n = vec2(0.0, 0.0),
|
|
||||||
.d = std.math.floatMax(f32),
|
|
||||||
.i = undefined
|
|
||||||
};
|
|
||||||
var closest_vertex = struct {
|
var closest_vertex = struct {
|
||||||
v: Vec2 = undefined,
|
v: Vec2 = undefined,
|
||||||
d: f32 = std.math.floatMax(f32),
|
d: f32 = std.math.floatMax(f32),
|
||||||
|
|
@ -816,9 +779,7 @@ test circlePolygonContact {
|
||||||
try testing.expect(bool, true).eql(false);
|
try testing.expect(bool, true).eql(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
try testing.expect(?Contact, null).eql(
|
try testing.expect(?Contact, null).eql(circlePolygonContact(Circle{ .pos = vec2(-1.0, 0.0), .radius = 1.0 }, &r1));
|
||||||
circlePolygonContact(Circle{.pos=vec2(-1.0, 0.0), .radius = 1.0}, &r1)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute a Contact report between two circles.
|
/// Compute a Contact report between two circles.
|
||||||
|
|
@ -841,9 +802,7 @@ pub fn circleCircleContact(circle_a: Circle, circle_b: Circle) ?Contact {
|
||||||
}
|
}
|
||||||
|
|
||||||
test circleCircleContact {
|
test circleCircleContact {
|
||||||
if (circleCircleContact(Circle{.pos=vec2(0.0, 0.0), .radius = 1.0},
|
if (circleCircleContact(Circle{ .pos = vec2(0.0, 0.0), .radius = 1.0 }, Circle{ .pos = vec2(1.75, 0.0), .radius = 1.0 })) |contact| {
|
||||||
Circle{.pos = vec2(1.75, 0.0), .radius = 1.0})) |contact| {
|
|
||||||
|
|
||||||
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.normal);
|
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.normal);
|
||||||
try testing.expect(f32, 0.25).eql(contact.depth);
|
try testing.expect(f32, 0.25).eql(contact.depth);
|
||||||
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.cp1.?);
|
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.cp1.?);
|
||||||
|
|
@ -852,9 +811,7 @@ test circleCircleContact {
|
||||||
try testing.expect(bool, true).eql(false);
|
try testing.expect(bool, true).eql(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (circleCircleContact(Circle{.pos=vec2(0.0, 0.0), .radius = 1.0},
|
if (circleCircleContact(Circle{ .pos = vec2(0.0, 0.0), .radius = 1.0 }, Circle{ .pos = vec2(2.0, 0.0), .radius = 1.0 })) |contact| {
|
||||||
Circle{.pos = vec2(2.0, 0.0), .radius = 1.0})) |contact| {
|
|
||||||
|
|
||||||
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.normal);
|
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.normal);
|
||||||
try testing.expect(f32, 0.0).eql(contact.depth);
|
try testing.expect(f32, 0.0).eql(contact.depth);
|
||||||
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.cp1.?);
|
try testing.expect(Vec2, vec2(1.0, 0.0)).eql(contact.cp1.?);
|
||||||
|
|
@ -863,8 +820,5 @@ test circleCircleContact {
|
||||||
try testing.expect(bool, true).eql(false);
|
try testing.expect(bool, true).eql(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
try testing.expect(?Contact, null).eql(
|
try testing.expect(?Contact, null).eql(circleCircleContact(Circle{ .pos = vec2(0.0, 0.0), .radius = 1.0 }, Circle{ .pos = vec2(2.01, 0.0), .radius = 1.0 }));
|
||||||
circleCircleContact(Circle{.pos=vec2(0.0, 0.0), .radius = 1.0},
|
|
||||||
Circle{.pos = vec2(2.01, 0.0), .radius = 1.0})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue