Comparing version 0.5.0 to 0.6.0
@@ -5,2 +5,8 @@ # Changelog | ||
## 0.6.0 (Sept 11, 2016) | ||
- Fix "Vornoi" -> "Voronoi" everywhere. Changes are all in private code, no functional changes. (Fixes #27) | ||
- Exposed isSeparatingAxis() function - thanks [hexus](https://github.com/hexus)! | ||
- Allow pointInPolygon to work with small polygons. (Fixes #41) | ||
## 0.5.0 (Dec 26, 2014) | ||
@@ -7,0 +13,0 @@ |
{ | ||
"name": "sat", | ||
"description": "Library for performing 2D collision detection", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"author": "Jim Riecken <jriecken@gmail.com>", | ||
@@ -22,3 +22,9 @@ "keywords": [ | ||
}, | ||
"main": "SAT.js" | ||
"scripts":{ | ||
"test": "mocha" | ||
}, | ||
"main": "SAT.js", | ||
"devDependencies": { | ||
"mocha": "^2.1.0" | ||
} | ||
} |
@@ -5,5 +5,5 @@ SAT.js | ||
- [Classes](#classes) | ||
- [Collision Tests](#tests) | ||
- [Collision Tests](#collision-tests) | ||
- [Examples](#examples) | ||
About | ||
@@ -15,3 +15,3 @@ ----- | ||
It supports detecting collisions between: | ||
- Circles (using Vornoi Regions.) | ||
- Circles (using Voronoi Regions.) | ||
- Convex Polygons (and simple Axis-Aligned Boxes, which are of course, convex polygons.) | ||
@@ -23,3 +23,3 @@ | ||
Current version: `0.5.0`. [Annotated source code](http://jriecken.github.io/sat-js/docs/SAT.html) is available. | ||
Current version: `0.6.0`. [Annotated source code](http://jriecken.github.io/sat-js/docs/SAT.html) is available. | ||
@@ -29,3 +29,3 @@ Nicely compresses with the [Google Closure Compiler](https://developers.google.com/closure/compiler/) in **Advanced** mode to about 6KB (2KB gzipped) | ||
To use it in node.js, you can run `npm install sat` and then use it with `var SAT = require('sat');` | ||
<a name="classes"></a> | ||
@@ -42,3 +42,3 @@ Classes | ||
// Create the vector (10,10) - If (x,y) not specified, defaults to (0,0). | ||
var v = new SAT.Vector(10, 10) | ||
var v = new SAT.Vector(10, 10) | ||
``` | ||
@@ -69,3 +69,3 @@ | ||
- `len()` - Get the length of this Vector | ||
### SAT.Circle | ||
@@ -76,3 +76,3 @@ | ||
// Create a circle whose center is (10,10) with radius of 20 | ||
var c = new SAT.Circle(new Sat.Vector(10,10), 20); | ||
var c = new SAT.Circle(new SAT.Vector(10,10), 20); | ||
``` | ||
@@ -98,2 +98,6 @@ | ||
Note: The points are counter-clockwise *with respect to the coordinate system*. If you directly draw the points on a screen that has the origin at the top-left corner it will _appear_ visually that the points are being specified clockwise. This is just because of the inversion of the Y-axis when being displayed. | ||
You can create a line segment by creating a `Polygon` that contains only 2 ppoints. | ||
It has the following properties: | ||
@@ -117,4 +121,4 @@ | ||
- `rotate(angle)` - Rotate the original points of this polygon counter-clockwise (around its local coordinate system) by the specified number of radians. The `angle` rotation will be applied on top of this rotation. | ||
- `translate(x, y)` - Translate the original points of this polygin (relative to the local coordinate system) by the specified amounts. The `offset` translation will be applied on top of this translation. | ||
- `translate(x, y)` - Translate the original points of this polygon (relative to the local coordinate system) by the specified amounts. The `offset` translation will be applied on top of this translation. | ||
### SAT.Box | ||
@@ -130,6 +134,6 @@ | ||
- `pos` - The bottom-left coordinate of the box. | ||
- `pos` - The bottom-left coordinate of the box (i.e the smallest `x` value and the smallest `y` value). | ||
- `w` - The width of the box. | ||
- `h` - The height of the box. | ||
It has the following methods: | ||
@@ -152,3 +156,3 @@ | ||
- `bInA` - Whether the second object is completely inside the first. | ||
It has the following methods: | ||
@@ -158,3 +162,3 @@ | ||
<a name="tests"></a> | ||
@@ -288,2 +292,14 @@ Collision Tests | ||
SAT.pointInCircle(new V(110,110), circle); // true | ||
``` | ||
Tests | ||
----- | ||
To run the tests from your console: | ||
``` | ||
mocha | ||
``` | ||
To install `mocha` you will need to have run `npm install` after cloning the repo. |
68
SAT.js
@@ -1,2 +0,2 @@ | ||
// Version 0.5.0 - Copyright 2012 - 2015 - Jim Riecken <jimr@jimr.ca> | ||
// Version 0.6.0 - Copyright 2012 - 2016 - Jim Riecken <jimr@jimr.ca> | ||
// | ||
@@ -7,3 +7,3 @@ // Released under the MIT License - https://github.com/jriecken/sat-js | ||
// polygons using the Separating Axis Theorem. | ||
/** @preserve SAT.js - Version 0.5.0 - Copyright 2012 - 2015 - Jim Riecken <jimr@jimr.ca> - released under the MIT License. https://github.com/jriecken/sat-js */ | ||
/** @preserve SAT.js - Version 0.6.0 - Copyright 2012 - 2016 - Jim Riecken <jimr@jimr.ca> - released under the MIT License. https://github.com/jriecken/sat-js */ | ||
@@ -304,2 +304,7 @@ /*global define: false, module: false*/ | ||
// Set the points of the polygon. | ||
// | ||
// Note: The points are counter-clockwise *with respect to the coordinate system*. | ||
// If you directly draw the points on a screen that has the origin at the top-left corner | ||
// it will _appear_ visually that the points are being specified clockwise. This is just | ||
// because of the inversion of the Y-axis when being displayed. | ||
/** | ||
@@ -477,3 +482,3 @@ * @param {Array.<Vector>=} points An array of vectors representing the points in the polygon, | ||
/** | ||
* @param {Vector=} pos A vector representing the top-left of the box. | ||
* @param {Vector=} pos A vector representing the bottom-left of the box (i.e. the smallest x and smallest y value). | ||
* @param {?number=} w The width of the box. | ||
@@ -561,7 +566,7 @@ * @param {?number=} h The height of the box. | ||
// Unit square polygon used for polygon hit detection. | ||
// Tiny "point" polygon used for polygon hit detection. | ||
/** | ||
* @type {Polygon} | ||
*/ | ||
var UNIT_SQUARE = new Box(new Vector(), 1, 1).toPolygon(); | ||
var TEST_POINT = new Box(new Vector(), 0.000001, 0.000001).toPolygon(); | ||
@@ -672,4 +677,5 @@ // ## Helper Functions | ||
} | ||
SAT['isSeparatingAxis'] = isSeparatingAxis; | ||
// Calculates which Vornoi region a point is on a line segment. | ||
// Calculates which Voronoi region a point is on a line segment. | ||
// It is assumed that both the line and the point are relative to `(0,0)` | ||
@@ -683,31 +689,31 @@ // | ||
* @param {Vector} point The point. | ||
* @return {number} LEFT_VORNOI_REGION (-1) if it is the left region, | ||
* MIDDLE_VORNOI_REGION (0) if it is the middle region, | ||
* RIGHT_VORNOI_REGION (1) if it is the right region. | ||
* @return {number} LEFT_VORONOI_REGION (-1) if it is the left region, | ||
* MIDDLE_VORONOI_REGION (0) if it is the middle region, | ||
* RIGHT_VORONOI_REGION (1) if it is the right region. | ||
*/ | ||
function vornoiRegion(line, point) { | ||
function voronoiRegion(line, point) { | ||
var len2 = line.len2(); | ||
var dp = point.dot(line); | ||
// If the point is beyond the start of the line, it is in the | ||
// left vornoi region. | ||
if (dp < 0) { return LEFT_VORNOI_REGION; } | ||
// left voronoi region. | ||
if (dp < 0) { return LEFT_VORONOI_REGION; } | ||
// If the point is beyond the end of the line, it is in the | ||
// right vornoi region. | ||
else if (dp > len2) { return RIGHT_VORNOI_REGION; } | ||
// right voronoi region. | ||
else if (dp > len2) { return RIGHT_VORONOI_REGION; } | ||
// Otherwise, it's in the middle one. | ||
else { return MIDDLE_VORNOI_REGION; } | ||
else { return MIDDLE_VORONOI_REGION; } | ||
} | ||
// Constants for Vornoi regions | ||
// Constants for Voronoi regions | ||
/** | ||
* @const | ||
*/ | ||
var LEFT_VORNOI_REGION = -1; | ||
var LEFT_VORONOI_REGION = -1; | ||
/** | ||
* @const | ||
*/ | ||
var MIDDLE_VORNOI_REGION = 0; | ||
var MIDDLE_VORONOI_REGION = 0; | ||
/** | ||
* @const | ||
*/ | ||
var RIGHT_VORNOI_REGION = 1; | ||
var RIGHT_VORONOI_REGION = 1; | ||
@@ -739,5 +745,5 @@ // ## Collision Tests | ||
function pointInPolygon(p, poly) { | ||
UNIT_SQUARE['pos'].copy(p); | ||
TEST_POINT['pos'].copy(p); | ||
T_RESPONSE.clear(); | ||
var result = testPolygonPolygon(UNIT_SQUARE, poly, T_RESPONSE); | ||
var result = testPolygonPolygon(TEST_POINT, poly, T_RESPONSE); | ||
if (result) { | ||
@@ -823,12 +829,12 @@ result = T_RESPONSE['aInB']; | ||
// Calculate which Vornoi region the center of the circle is in. | ||
var region = vornoiRegion(edge, point); | ||
// Calculate which Voronoi region the center of the circle is in. | ||
var region = voronoiRegion(edge, point); | ||
// If it's the left region: | ||
if (region === LEFT_VORNOI_REGION) { | ||
// We need to make sure we're in the RIGHT_VORNOI_REGION of the previous edge. | ||
if (region === LEFT_VORONOI_REGION) { | ||
// We need to make sure we're in the RIGHT_VORONOI_REGION of the previous edge. | ||
edge.copy(polygon['edges'][prev]); | ||
// Calculate the center of the circle relative the starting point of the previous edge | ||
var point2 = T_VECTORS.pop().copy(circlePos).sub(points[prev]); | ||
region = vornoiRegion(edge, point2); | ||
if (region === RIGHT_VORNOI_REGION) { | ||
region = voronoiRegion(edge, point2); | ||
if (region === RIGHT_VORONOI_REGION) { | ||
// It's in the region we want. Check if the circle intersects the point. | ||
@@ -852,3 +858,3 @@ var dist = point.len(); | ||
// If it's the right region: | ||
} else if (region === RIGHT_VORNOI_REGION) { | ||
} else if (region === RIGHT_VORONOI_REGION) { | ||
// We need to make sure we're in the left region on the next edge | ||
@@ -858,4 +864,4 @@ edge.copy(polygon['edges'][next]); | ||
point.copy(circlePos).sub(points[next]); | ||
region = vornoiRegion(edge, point); | ||
if (region === LEFT_VORNOI_REGION) { | ||
region = voronoiRegion(edge, point); | ||
if (region === LEFT_VORONOI_REGION) { | ||
// It's in the region we want. Check if the circle intersects the point. | ||
@@ -905,3 +911,3 @@ var dist = point.len(); | ||
// If this is the smallest overlap we've seen, keep it. | ||
// (overlapN may be null if the circle was in the wrong Vornoi region). | ||
// (overlapN may be null if the circle was in the wrong Voronoi region). | ||
if (overlapN && response && Math.abs(overlap) < Math.abs(response['overlap'])) { | ||
@@ -908,0 +914,0 @@ response['overlap'] = overlap; |
@@ -1,14 +0,14 @@ | ||
/* SAT.js - Version 0.5.0 - Copyright 2012 - 2015 - Jim Riecken <jimr@jimr.ca> - released under the MIT License. https://github.com/jriecken/sat-js */ | ||
function x(){function c(a,e){this.x=a||0;this.y=e||0}function A(a,e){this.pos=a||new c;this.r=e||0}function m(a,e){this.pos=a||new c;this.angle=0;this.offset=new c;this.m(e||[])}function r(a,e,b){this.pos=a||new c;this.w=e||0;this.h=b||0}function w(){this.b=this.a=null;this.overlapN=new c;this.overlapV=new c;this.clear()}function B(a,e,b){for(var f=Number.MAX_VALUE,c=-Number.MAX_VALUE,k=a.length,h=0;h<k;h++){var d=a[h].d(e);d<f&&(f=d);d>c&&(c=d)}b[0]=f;b[1]=c}function C(a,e,b,f,c,k){var h=t.pop(), | ||
d=t.pop();a=g.pop().c(e).sub(a);e=a.d(c);B(b,c,h);B(f,c,d);d[0]+=e;d[1]+=e;if(h[0]>d[1]||d[0]>h[1])return g.push(a),t.push(h),t.push(d),!0;k&&(b=0,h[0]<d[0]?(k.aInB=!1,h[1]<d[1]?(b=h[1]-d[0],k.bInA=!1):(b=h[1]-d[0],f=d[1]-h[0],b=b<f?b:-f)):(k.bInA=!1,h[1]>d[1]?(b=h[0]-d[1],k.aInB=!1):(b=h[1]-d[0],f=d[1]-h[0],b=b<f?b:-f)),f=Math.abs(b),f<k.overlap&&(k.overlap=f,k.overlapN.c(c),0>b&&k.overlapN.reverse()));g.push(a);t.push(h);t.push(d);return!1}function y(a,e){var b=a.e(),c=e.d(a);return 0>c?-1:c>b? | ||
1:0}function D(a,e,b){for(var c=g.pop().c(e.pos).sub(a.pos),l=e.r,k=l*l,h=a.calcPoints,d=h.length,v=g.pop(),q=g.pop(),n=0;n<d;n++){var m=n===d-1?0:n+1,t=0===n?d-1:n-1,r=0,u=null;v.c(a.edges[n]);q.c(c).sub(h[n]);b&&q.e()>k&&(b.aInB=!1);var p=y(v,q);if(-1===p){v.c(a.edges[t]);m=g.pop().c(c).sub(h[t]);p=y(v,m);if(1===p){p=q.g();if(p>l)return g.push(c),g.push(v),g.push(q),g.push(m),!1;b&&(b.bInA=!1,u=q.normalize(),r=l-p)}g.push(m)}else if(1===p){if(v.c(a.edges[m]),q.c(c).sub(h[m]),p=y(v,q),-1===p){p= | ||
q.g();if(p>l)return g.push(c),g.push(v),g.push(q),!1;b&&(b.bInA=!1,u=q.normalize(),r=l-p)}}else{m=v.j().normalize();p=q.d(m);t=Math.abs(p);if(0<p&&t>l)return g.push(c),g.push(m),g.push(q),!1;b&&(u=m,r=l-p,0<=p||r<2*l)&&(b.bInA=!1)}u&&b&&Math.abs(r)<Math.abs(b.overlap)&&(b.overlap=r,b.overlapN.c(u))}b&&(b.a=a,b.b=e,b.overlapV.c(b.overlapN).scale(b.overlap));g.push(c);g.push(v);g.push(q);return!0}function E(a,e,b){for(var c=a.calcPoints,l=c.length,k=e.calcPoints,h=k.length,d=0;d<l;d++)if(C(a.pos,e.pos, | ||
c,k,a.normals[d],b))return!1;for(d=0;d<h;d++)if(C(a.pos,e.pos,c,k,e.normals[d],b))return!1;b&&(b.a=a,b.b=e,b.overlapV.c(b.overlapN).scale(b.overlap));return!0}var n={};n.Vector=c;n.V=c;c.prototype.copy=c.prototype.c=function(a){this.x=a.x;this.y=a.y;return this};c.prototype.clone=c.prototype.clone=function(){return new c(this.x,this.y)};c.prototype.perp=c.prototype.j=function(){var a=this.x;this.x=this.y;this.y=-a;return this};c.prototype.rotate=c.prototype.rotate=function(a){var e=this.x,b=this.y; | ||
this.x=e*Math.cos(a)-b*Math.sin(a);this.y=e*Math.sin(a)+b*Math.cos(a);return this};c.prototype.reverse=c.prototype.reverse=function(){this.x=-this.x;this.y=-this.y;return this};c.prototype.normalize=c.prototype.normalize=function(){var a=this.g();0<a&&(this.x/=a,this.y/=a);return this};c.prototype.add=c.prototype.add=function(a){this.x+=a.x;this.y+=a.y;return this};c.prototype.sub=c.prototype.sub=function(a){this.x-=a.x;this.y-=a.y;return this};c.prototype.scale=c.prototype.scale=function(a,e){this.x*= | ||
a;this.y*=e||a;return this};c.prototype.project=c.prototype.k=function(a){var e=this.d(a)/a.e();this.x=e*a.x;this.y=e*a.y;return this};c.prototype.projectN=c.prototype.l=function(a){var e=this.d(a);this.x=e*a.x;this.y=e*a.y;return this};c.prototype.reflect=function(a){var e=this.x,b=this.y;this.k(a).scale(2);this.x-=e;this.y-=b;return this};c.prototype.reflectN=function(a){var e=this.x,b=this.y;this.l(a).scale(2);this.x-=e;this.y-=b;return this};c.prototype.dot=c.prototype.d=function(a){return this.x* | ||
a.x+this.y*a.y};c.prototype.len2=c.prototype.e=function(){return this.d(this)};c.prototype.len=c.prototype.g=function(){return Math.sqrt(this.e())};n.Circle=A;A.prototype.getAABB=function(){var a=this.r,e=this.pos.clone().sub(new c(a,a));return(new r(e,2*a,2*a)).i()};n.Polygon=m;m.prototype.setPoints=m.prototype.m=function(a){if(!this.points||this.points.length!==a.length){var e,b=this.calcPoints=[],f=this.edges=[],l=this.normals=[];for(e=0;e<a.length;e++)b.push(new c),f.push(new c),l.push(new c)}this.points= | ||
a;this.f();return this};m.prototype.setAngle=function(a){this.angle=a;this.f();return this};m.prototype.setOffset=function(a){this.offset=a;this.f();return this};m.prototype.rotate=m.prototype.rotate=function(a){for(var e=this.points,b=e.length,c=0;c<b;c++)e[c].rotate(a);this.f();return this};m.prototype.translate=m.prototype.translate=function(a,c){for(var b=this.points,f=b.length,l=0;l<f;l++)b[l].x+=a,b[l].y+=c;this.f();return this};m.prototype.f=function(){var a=this.calcPoints,c=this.edges,b= | ||
this.normals,f=this.points,l=this.offset,k=this.angle,h=f.length,d;for(d=0;d<h;d++){var g=a[d].c(f[d]);g.x+=l.x;g.y+=l.y;0!==k&&g.rotate(k)}for(d=0;d<h;d++)f=a[d],f=c[d].c(d<h-1?a[d+1]:a[0]).sub(f),b[d].c(f).j().normalize()};m.prototype.getAABB=function(){for(var a=this.calcPoints,e=a.length,b=a[0].x,f=a[0].y,g=a[0].x,k=a[0].y,h=1;h<e;h++){var d=a[h];d.x<b?b=d.x:d.x>g&&(g=d.x);d.y<f?f=d.y:d.y>k&&(k=d.y)}return(new r(this.pos.clone().add(new c(b,f)),g-b,k-f)).i()};n.Box=r;r.prototype.toPolygon=r.prototype.i= | ||
function(){var a=this.pos,e=this.w,b=this.h;return new m(new c(a.x,a.y),[new c,new c(e,0),new c(e,b),new c(0,b)])};n.Response=w;w.prototype.clear=w.prototype.clear=function(){this.bInA=this.aInB=!0;this.overlap=Number.MAX_VALUE;return this};for(var g=[],u=0;10>u;u++)g.push(new c);for(var t=[],u=0;5>u;u++)t.push([]);var z=new w,F=(new r(new c,1,1)).i();n.pointInCircle=function(a,c){var b=g.pop().c(a).sub(c.pos),f=c.r*c.r,l=b.e();g.push(b);return l<=f};n.pointInPolygon=function(a,c){F.pos.c(a);z.clear(); | ||
var b=E(F,c,z);b&&(b=z.aInB);return b};n.testCircleCircle=function(a,c,b){var f=g.pop().c(c.pos).sub(a.pos),l=a.r+c.r,k=f.e();if(k>l*l)return g.push(f),!1;b&&(k=Math.sqrt(k),b.a=a,b.b=c,b.overlap=l-k,b.overlapN.c(f.normalize()),b.overlapV.c(f).scale(b.overlap),b.aInB=a.r<=c.r&&k<=c.r-a.r,b.bInA=c.r<=a.r&&k<=a.r-c.r);g.push(f);return!0};n.testPolygonCircle=D;n.testCirclePolygon=function(a,c,b){if((a=D(c,a,b))&&b){c=b.a;var f=b.aInB;b.overlapN.reverse();b.overlapV.reverse();b.a=b.b;b.b=c;b.aInB=b.bInA; | ||
b.bInA=f}return a};n.testPolygonPolygon=E;return n}"function"===typeof define&&define.amd?define(x):"object"===typeof exports?module.exports=x():this.SAT=x(); | ||
/* SAT.js - Version 0.6.0 - Copyright 2012 - 2016 - Jim Riecken <jimr@jimr.ca> - released under the MIT License. https://github.com/jriecken/sat-js */ | ||
function x(){function c(a,e){this.x=a||0;this.y=e||0}function B(a,e){this.pos=a||new c;this.r=e||0}function n(a,e){this.pos=a||new c;this.angle=0;this.offset=new c;this.u(e||[])}function q(a,e,b){this.pos=a||new c;this.w=e||0;this.h=b||0}function w(){this.b=this.a=null;this.overlapN=new c;this.overlapV=new c;this.clear()}function C(a,e,b){for(var h=Number.MAX_VALUE,c=-Number.MAX_VALUE,k=a.length,g=0;g<k;g++){var d=a[g].f(e);d<h&&(h=d);d>c&&(c=d)}b[0]=h;b[1]=c}function y(a,e,b,h,c,k){var g=r.pop(), | ||
d=r.pop();a=m.pop().c(e).sub(a);e=a.f(c);C(b,c,g);C(h,c,d);d[0]+=e;d[1]+=e;if(g[0]>d[1]||d[0]>g[1])return m.push(a),r.push(g),r.push(d),!0;k&&(g[0]<d[0]?(k.aInB=!1,g[1]<d[1]?(b=g[1]-d[0],k.bInA=!1):(b=g[1]-d[0],h=d[1]-g[0],b=b<h?b:-h)):(k.bInA=!1,g[1]>d[1]?(b=g[0]-d[1],k.aInB=!1):(b=g[1]-d[0],h=d[1]-g[0],b=b<h?b:-h)),h=Math.abs(b),h<k.overlap&&(k.overlap=h,k.overlapN.c(c),0>b&&k.overlapN.reverse()));m.push(a);r.push(g);r.push(d);return!1}function z(a,e){var b=a.g(),c=e.f(a);return 0>c?-1:c>b?1:0} | ||
function D(a,e,b){for(var c=m.pop().c(e.pos).sub(a.pos),l=e.r,k=l*l,g=a.calcPoints,d=g.length,u=m.pop(),f=m.pop(),n=0;n<d;n++){var v=n===d-1?0:n+1,r=0===n?d-1:n-1,q=0,t=null;u.c(a.edges[n]);f.c(c).sub(g[n]);b&&f.g()>k&&(b.aInB=!1);var p=z(u,f);if(-1===p){u.c(a.edges[r]);v=m.pop().c(c).sub(g[r]);p=z(u,v);if(1===p){p=f.j();if(p>l)return m.push(c),m.push(u),m.push(f),m.push(v),!1;b&&(b.bInA=!1,t=f.normalize(),q=l-p)}m.push(v)}else if(1===p){if(u.c(a.edges[v]),f.c(c).sub(g[v]),p=z(u,f),-1===p){p=f.j(); | ||
if(p>l)return m.push(c),m.push(u),m.push(f),!1;b&&(b.bInA=!1,t=f.normalize(),q=l-p)}}else{v=u.m().normalize();p=f.f(v);r=Math.abs(p);if(0<p&&r>l)return m.push(c),m.push(v),m.push(f),!1;b&&(t=v,q=l-p,0<=p||q<2*l)&&(b.bInA=!1)}t&&b&&Math.abs(q)<Math.abs(b.overlap)&&(b.overlap=q,b.overlapN.c(t))}b&&(b.a=a,b.b=e,b.overlapV.c(b.overlapN).scale(b.overlap));m.push(c);m.push(u);m.push(f);return!0}function E(a,e,b){for(var c=a.calcPoints,l=c.length,k=e.calcPoints,g=k.length,d=0;d<l;d++)if(y(a.pos,e.pos,c, | ||
k,a.normals[d],b))return!1;for(d=0;d<g;d++)if(y(a.pos,e.pos,c,k,e.normals[d],b))return!1;b&&(b.a=a,b.b=e,b.overlapV.c(b.overlapN).scale(b.overlap));return!0}var f={};f.Vector=c;f.V=c;c.prototype.copy=c.prototype.c=function(a){this.x=a.x;this.y=a.y;return this};c.prototype.clone=c.prototype.clone=function(){return new c(this.x,this.y)};c.prototype.perp=c.prototype.m=function(){var a=this.x;this.x=this.y;this.y=-a;return this};c.prototype.rotate=c.prototype.rotate=function(a){var e=this.x,b=this.y; | ||
this.x=e*Math.cos(a)-b*Math.sin(a);this.y=e*Math.sin(a)+b*Math.cos(a);return this};c.prototype.reverse=c.prototype.reverse=function(){this.x=-this.x;this.y=-this.y;return this};c.prototype.normalize=c.prototype.normalize=function(){var a=this.j();0<a&&(this.x/=a,this.y/=a);return this};c.prototype.add=c.prototype.add=function(a){this.x+=a.x;this.y+=a.y;return this};c.prototype.sub=c.prototype.sub=function(a){this.x-=a.x;this.y-=a.y;return this};c.prototype.scale=c.prototype.scale=function(a,e){this.x*= | ||
a;this.y*=e||a;return this};c.prototype.project=c.prototype.o=function(a){var e=this.f(a)/a.g();this.x=e*a.x;this.y=e*a.y;return this};c.prototype.projectN=c.prototype.s=function(a){var e=this.f(a);this.x=e*a.x;this.y=e*a.y;return this};c.prototype.reflect=function(a){var e=this.x,b=this.y;this.o(a).scale(2);this.x-=e;this.y-=b;return this};c.prototype.reflectN=function(a){var e=this.x,b=this.y;this.s(a).scale(2);this.x-=e;this.y-=b;return this};c.prototype.dot=c.prototype.f=function(a){return this.x* | ||
a.x+this.y*a.y};c.prototype.len2=c.prototype.g=function(){return this.f(this)};c.prototype.len=c.prototype.j=function(){return Math.sqrt(this.g())};f.Circle=B;B.prototype.getAABB=function(){var a=this.r,e=this.pos.clone().sub(new c(a,a));return(new q(e,2*a,2*a)).l()};f.Polygon=n;n.prototype.setPoints=n.prototype.u=function(a){if(!this.points||this.points.length!==a.length){var e,b=this.calcPoints=[],h=this.edges=[],l=this.normals=[];for(e=0;e<a.length;e++)b.push(new c),h.push(new c),l.push(new c)}this.points= | ||
a;this.i();return this};n.prototype.setAngle=function(a){this.angle=a;this.i();return this};n.prototype.setOffset=function(a){this.offset=a;this.i();return this};n.prototype.rotate=n.prototype.rotate=function(a){for(var e=this.points,b=e.length,c=0;c<b;c++)e[c].rotate(a);this.i();return this};n.prototype.translate=n.prototype.translate=function(a,c){for(var b=this.points,h=b.length,l=0;l<h;l++)b[l].x+=a,b[l].y+=c;this.i();return this};n.prototype.i=function(){var a=this.calcPoints,c=this.edges,b= | ||
this.normals,h=this.points,l=this.offset,k=this.angle,g=h.length,d;for(d=0;d<g;d++){var f=a[d].c(h[d]);f.x+=l.x;f.y+=l.y;0!==k&&f.rotate(k)}for(d=0;d<g;d++)h=a[d],h=c[d].c(d<g-1?a[d+1]:a[0]).sub(h),b[d].c(h).m().normalize()};n.prototype.getAABB=function(){for(var a=this.calcPoints,e=a.length,b=a[0].x,h=a[0].y,f=a[0].x,k=a[0].y,g=1;g<e;g++){var d=a[g];d.x<b?b=d.x:d.x>f&&(f=d.x);d.y<h?h=d.y:d.y>k&&(k=d.y)}return(new q(this.pos.clone().add(new c(b,h)),f-b,k-h)).l()};f.Box=q;q.prototype.toPolygon=q.prototype.l= | ||
function(){var a=this.pos,e=this.w,b=this.h;return new n(new c(a.x,a.y),[new c,new c(e,0),new c(e,b),new c(0,b)])};f.Response=w;w.prototype.clear=w.prototype.clear=function(){this.bInA=this.aInB=!0;this.overlap=Number.MAX_VALUE;return this};for(var m=[],t=0;10>t;t++)m.push(new c);for(var r=[],t=0;5>t;t++)r.push([]);var A=new w,F=(new q(new c,1E-6,1E-6)).l();f.isSeparatingAxis=y;f.pointInCircle=function(a,c){var b=m.pop().c(a).sub(c.pos),h=c.r*c.r,f=b.g();m.push(b);return f<=h};f.pointInPolygon=function(a, | ||
c){F.pos.c(a);A.clear();var b=E(F,c,A);b&&(b=A.aInB);return b};f.testCircleCircle=function(a,c,b){var f=m.pop().c(c.pos).sub(a.pos),l=a.r+c.r,k=f.g();if(k>l*l)return m.push(f),!1;b&&(k=Math.sqrt(k),b.a=a,b.b=c,b.overlap=l-k,b.overlapN.c(f.normalize()),b.overlapV.c(f).scale(b.overlap),b.aInB=a.r<=c.r&&k<=c.r-a.r,b.bInA=c.r<=a.r&&k<=a.r-c.r);m.push(f);return!0};f.testPolygonCircle=D;f.testCirclePolygon=function(a,c,b){if((a=D(c,a,b))&&b){c=b.a;var f=b.aInB;b.overlapN.reverse();b.overlapV.reverse(); | ||
b.a=b.b;b.b=c;b.aInB=b.bInA;b.bInA=f}return a};f.testPolygonPolygon=E;return f}"function"===typeof define&&define.amd?define(x):"object"===typeof exports?module.exports=x():this.SAT=x(); |
69223
11
1204
293
1