View on GitHub

Sat-js

A simple JavaScript library for performing 2D collision detection

Download this project as a .zip file Download this project as a tar.gz file

SAT.js

About

SAT.js is a simple JavaScript library for performing collision detection (and projection-based collision response) of simple 2D shapes. It uses the Separating Axis Theorem (hence the name)

It supports detecting collisions between:

It also supports checking whether a point is inside a circle or polygon.

It’s released under the MIT license.

Current version: 0.7.0. Annotated source code is available.

Nicely compresses with the Google 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');

Classes

SAT.js contains the following JavaScript classes:

SAT.Vector (aliased as SAT.V)

This is a simple 2D vector/point class. It is created by calling:

// Create the vector (10,10) - If (x,y) not specified, defaults to (0,0).
var v = new SAT.Vector(10, 10)

It has the following properties:

It contains the following methods:

SAT.Circle

This is a simple circle with a center position and a radius. It is created by calling:

// Create a circle whose center is (10,10) with radius of 20
var c = new SAT.Circle(new SAT.Vector(10,10), 20);

It has the following properties:

SAT.Polygon

This is a convex polygon, whose points are specified in a counter-clockwise fashion. It is created by calling:

// Create a triangle at (0,0)
var p = new SAT.Polygon(new SAT.Vector(), [
  new SAT.Vector(),
  new SAT.Vector(100,0),
  new SAT.Vector(50,75)
]);

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:

You should not manually change any of the properties except pos - use the setPoints, setAngle, and setOffset methods to ensure that the calculated properties are updated correctly.

It has the following methods:

SAT.Box

This is a simple Box with a position, width, and height. It is created by calling:

// Create a box at (10,10) with width 20 and height 40.
var b = new SAT.Box(new SAT.Vector(10,10), 20, 40);

It has the following properties:

It has the following methods:

SAT.Response

This is the object representing the result of a collision between two objects. It just has a simple new Response() constructor.

It has the following properties:

It has the following methods:

Collision Tests

SAT.js contains the following collision tests:

SAT.pointInCircle(p, c)

Checks whether a given point is inside the specified circle.

SAT.pointInPolygon(p, poly)

Checks whether a given point is inside a specified convex polygon.

SAT.testCircleCircle(a, b, response)

Tests for a collision between two Circles, a, and b. If a response is to be calculated in the event of collision, pass in a cleared Response object.

Returns true if the circles collide, false otherwise.

SAT.testPolygonCircle(polygon, circle, response)

Tests for a collision between a Polygon and a Circle. If a response is to be calculated in the event of a collision, pass in a cleared Response object.

Returns true if there is a collision, false otherwise.

SAT.testCirclePolygon(circle, polygon, response)

The same thing as SAT.testPolygonCircle, but in the other direction.

Returns true if there is a collision, false otherwise.

NOTE: This is slightly slower than SAT.testPolygonCircle as it just calls that and reverses the result

SAT.testPolygonPolygon(a, b, response)

Tests whether two polygons a and b collide. If a response is to be calculated in the event of collision, pass in a cleared Response object.

Returns true if there is a collision, false otherwise.

NOTE: If you want to detect a collision between Boxes, use the toPolygon() method

Examples

Test two circles

var V = SAT.Vector;
var C = SAT.Circle;

var circle1 = new C(new V(0,0), 20);
var circle2 = new C(new V(30,0), 20);
var response = new SAT.Response();
var collided = SAT.testCircleCircle(circle1, circle2, response);

// collided => true
// response.overlap => 10
// response.overlapV => (10, 0)

Test a circle and a polygon

var V = SAT.Vector;
var C = SAT.Circle;
var P = SAT.Polygon;

var circle = new C(new V(50,50), 20);
// A square
var polygon = new P(new V(0,0), [
  new V(0,0), new V(40,0), new V(40,40), new V(0,40)
]);
var response = new SAT.Response();
var collided = SAT.testPolygonCircle(polygon, circle, response);

// collided => true
// response.overlap ~> 5.86
// response.overlapV ~> (4.14, 4.14) - i.e. on a diagonal

Test two polygons

var V = SAT.Vector;
var P = SAT.Polygon;

// A square
var polygon1 = new P(new V(0,0), [
  new V(0,0), new V(40,0), new V(40,40), new V(0,40)
]);
// A triangle
var polygon2 = new P(new V(30,0), [
  new V(0,0), new V(30, 0), new V(0, 30)
]);
var response = new SAT.Response();
var collided = SAT.testPolygonPolygon(polygon1, polygon2, response);

// collided => true
// response.overlap => 10
// response.overlapV => (10, 0)

No collision between two Boxes

var V = SAT.Vector;
var B = SAT.Box;

var box1 = new B(new V(0,0), 20, 20).toPolygon();
var box2 = new B(new V(100,100), 20, 20).toPolygon();
var collided = SAT.testPolygonPolygon(box1, box2);

// collided => false

Hit testing a circle and polygon

var V = SAT.Vector;
var C = SAT.Circle;
var P = SAT.Polygon;

var triangle = new P(new V(30,0), [
  new V(0,0), new V(30, 0), new V(0, 30)
]);
var circle = new C(new V(100,100), 20);

SAT.pointInPolygon(new V(0,0), triangle); // false
SAT.pointInPolygon(new V(35, 5), triangle); // true
SAT.pointInCircle(new V(0,0), circle); // false
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.