Skip to content

Commit

Permalink
fix: SAT divide by 0 NaN fix preserving a_in_b and b_in_a
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacek Jan Pietal committed Sep 15, 2021
1 parent adb1887 commit c0ac06e
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 21 deletions.
4 changes: 2 additions & 2 deletions docs/demo/demo.bundle.js

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions docs/modules_Circle.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,8 @@ <h1 class="page-title">
}

get scale() {
return {
x: this.scale_x,
y: this.scale_y,
};
// for compatibility in SAT
return (this.scale_x + this.scale_y) / 2;
}
}

Expand Down
8 changes: 4 additions & 4 deletions docs/modules_SAT.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ <h1 class="page-title">
* @returns {Boolean}
*/
function SAT(a, b, result = null, aabb = true) {
const a_polygon = a._polygon;
const b_polygon = b._polygon;
const a_polygon = a._polygon &amp;&amp; !a.radius;
const b_polygon = b._polygon &amp;&amp; !b.radius;

let collision = false;

Expand Down Expand Up @@ -420,8 +420,8 @@ <h1 class="page-title">
result.a_in_b = a_radius &lt;= b_radius &amp;&amp; length &lt;= b_radius - a_radius;
result.b_in_a = b_radius &lt;= a_radius &amp;&amp; length &lt;= a_radius - b_radius;
result.overlap = radius_sum - length;
result.overlap_x = difference_x / length;
result.overlap_y = difference_y / length;
result.overlap_x = length ? difference_x / length : 1;
result.overlap_y = length ? difference_y / length : 1;
}

return true;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "detect-collisions",
"types": "collisions.d.ts",
"version": "2.5.6",
"version": "2.6.0",
"description": "zero-dependency 2d collision detection for circles, polygons, and points (with SAT and BVH)",
"main": "source/index.js",
"scripts": {
Expand All @@ -11,7 +11,7 @@
"docs": "yarn docs:make && yarn docs:copy",
"docs:dev": "yarn docs && node node_modules/@jacekpietal/bouncer.js/bin docs",
"lint": "eslint ./source --fix",
"demo": "yarn build-demo && http-server docs/demo",
"demo": "yarn build-demo && bouncer.js docs/demo",
"build-demo": "webpack && cp -r demo/ docs/",
"compile": "babel ./source --presets es2015 --out-dir ./es2015",
"build": "rm -rf ./docs/* && esdoc && webpack",
Expand Down
31 changes: 30 additions & 1 deletion source/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { Collisions } = require(".");
const { Collisions, Result, SAT } = require(".");

describe("GIVEN a world with a polygon", () => {
it("THEN collides with a circle", () => {
Expand Down Expand Up @@ -27,4 +27,33 @@ describe("GIVEN a world with a polygon", () => {

expect(world.potentials(rect).length).toBe(2);
});

it("THEN collides with two circles at same place", () => {
const world = new Collisions();
const c1 = world.createCircle(0, 0, 50);
const c2 = world.createCircle(0, 0, 100);
const result = new Result();

[c1, c2].forEach((body) => {
new SAT(body, body === c1 ? c2 : c1, result);

expect(result.a_in_b).toBe(body === c1);
expect(result.b_in_a).toBe(body === c2);
expect(result.overlap).toBe(150);
});

[c1, c2].forEach((body) => {
new SAT(body, body === c1 ? c2 : c1, result);

body.x -= result.overlap * result.overlap_x;
body.y -= result.overlap * result.overlap_y;
});

world.update();

new SAT(c1, c2, result);

expect(c1.x).toBe(-150);
expect(c2.x).toBe(0);
});
});
6 changes: 2 additions & 4 deletions source/modules/Circle.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ class Circle extends Polygon {
}

get scale() {
return {
x: this.scale_x,
y: this.scale_y,
};
// for compatibility in SAT
return (this.scale_x + this.scale_y) / 2;
}
}

Expand Down
8 changes: 4 additions & 4 deletions source/modules/SAT.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
* @returns {Boolean}
*/
function SAT(a, b, result = null, aabb = true) {
const a_polygon = a._polygon;
const b_polygon = b._polygon;
const a_polygon = a._polygon && !a.radius;
const b_polygon = b._polygon && !b.radius;

let collision = false;

Expand Down Expand Up @@ -328,8 +328,8 @@ function circleCircle(a, b, result = null) {
result.a_in_b = a_radius <= b_radius && length <= b_radius - a_radius;
result.b_in_a = b_radius <= a_radius && length <= a_radius - b_radius;
result.overlap = radius_sum - length;
result.overlap_x = difference_x / length;
result.overlap_y = difference_y / length;
result.overlap_x = length ? difference_x / length : 1;
result.overlap_y = length ? difference_y / length : 1;
}

return true;
Expand Down

0 comments on commit c0ac06e

Please sign in to comment.