SAT.js

repository·master·Indexed 21 days ago

https://github.com/jriecken/sat-js

A lightweight 2D collision detection library implementing the Separating Axis Theorem. Version 0.9.0 supports collision detection and response for circles, convex polygons, and axis-aligned boxes, as well as point-in-shape hit testing. It includes a 2D vector math utility (SAT.Vector) and provides detailed collision data via the SAT.Response object, including overlap magnitude and vectors.

Tokens
3.3K
Snippets
12
Records
15
Agent score
24%

What's inside sat-js

  1. How SAT.js works: Collision detection and response

    master

    SAT.js is a 2D collision detection library based on the Separating Axis Theorem. It supports detecting collisions between:

    • Circles (using Voronoi Regions)
    • Convex Polygons (including Axis-Aligned Boxes)

    It can also perform hit testing to check if a point is inside a circle or a polygon. The library supports both simple detection (returning a boolean) and collision response (calculating overlap magnitude and vectors).

  2. Install SAT.js via npm

    master

    To use SAT.js in a Node.js environment, install the sat package using npm and require it in your project.

    npm install sat
    var SAT = require('sat');
  3. Handle collision results with SAT.Response

    master

    The SAT.Response object stores the results of an intersection test. If a response object is passed into a collision test function, it will be populated with details about the collision.

    const response = new SAT.Response();
    // ... perform collision test ...
    
    console.log(response.overlap);    // Magnitude of overlap
    console.log(response.overlapN);   // Unit vector of overlap direction
    console.log(response.overlapV);   // Vector representing minimum change to extract A from B
    console.log(response.aInB);       // true if object A is entirely inside B
    console.log(response.bInA);       // true if object B is entirely inside A
    
    // Reuse the response object to avoid memory allocation
    response.clear();
  4. Perform collision tests between shapes

    master

    Use the following static methods to test for collisions. To get collision response data (like overlap), pass a cleared SAT.Response object as the third argument.

    Point Tests:

    • SAT.pointInCircle(p, c): Returns true if point p is inside circle c.
    • SAT.pointInPolygon(p, poly): Returns true if point p is inside convex polygon poly.

    Shape Tests:

    • SAT.testCircleCircle(a, b, response): Collision between two circles.
    • SAT.testPolygonCircle(polygon, circle, response): Collision between a polygon and a circle.
    • SAT.testCirclePolygon(circle, polygon, response): Collision between a circle and a polygon (calls testPolygonCircle internally).
    • SAT.testPolygonPolygon(a, b, response): Collision between two polygons. (To test boxes, use box.toPolygon()).
  5. Perform collision tests

    master

    SAT.js provides several functions for testing intersections between different shapes. Most functions accept an optional response object to provide detailed collision data.

    const circleA = new SAT.Circle(new SAT.Vector(0, 0), 10);
    const circleB = new SAT.Circle(new SAT.Vector(15, 0), 10);
    const poly = new SAT.Polygon(new SAT.Vector(5, 5), [...]);
    const response = new SAT.Response();
    
    // Point vs Circle
    const isInside = SAT.pointInCircle(new SAT.Vector(0, 0), circleA);
    
    // Point vs Polygon
    const isInsidePoly = SAT.pointInPolygon(new SAT.Vector(5, 5), poly);
    
    // Circle vs Circle
    const circlesCollide = SAT.testCircleCircle(circleA, circleB, response);
    
    // Polygon vs Circle
    const polyCircleCollide = SAT.testPolygonCircle(poly, circleA, response);
    
    // Circle vs Polygon (Note: slightly less efficient than Polygon vs Circle)
    const circlePolyCollide = SAT.testCirclePolygon(circleA, poly, response);
  6. Vector API Reference

    master

    Methods available on SAT.Vector (or SAT.V):

    • copy(other): Copies x and y from other into this vector.
    • clone(): Returns a new Vector with the same coordinates.
    • perp(): Rotates the vector 90 degrees clockwise.
    • rotate(angle): Rotates the vector counter-clockwise by angle (radians).
    • reverse(): Negates x and y.
    • normalize(): Scales the vector to a length of 1.
    • add(other): Adds other vector to this one.
    • sub(other): Subtracts other vector from this one.
    • scale(x, [y]): Scales x and y. If y is omitted, x is used for both.
    • project(other): Projects this vector onto other.
    • projectN(other): Projects this vector onto a unit vector other (more efficient).
    • reflect(axis): Reflects this vector on an arbitrary axis.
    • reflectN(axis): Reflects this vector on a unit vector axis (more efficient).
    • dot(other): Returns the dot product.
    • len(): Returns the length.
    • len2(): Returns the squared length.
  7. Use SAT.Polygon for convex polygon shapes

    master

    The SAT.Polygon class represents a convex polygon. Points should be provided in counter-clockwise order. Note that pos can be changed directly, but other properties like angle and offset must be updated via setters to ensure internal calculations (edges, normals) are refreshed.

    const pos = new SAT.Vector(0, 0);
    const points = [
      new SAT.Vector(0, 0),
      new SAT.Vector(10, 0),
      new SAT.Vector(10, 10),
      new SAT.Vector(0, 10)
    ];
    const poly = new SAT.Polygon(pos, points);
    
    poly.setAngle(Math.PI / 4); // Rotate 45 degrees
    poly.setOffset(new SAT.Vector(5, 5)); // Apply offset to points
    
    const centroid = poly.getCentroid(); // Returns a Vector
    const aabb = poly.getAABB(); // Returns a Polygon
  8. Use SAT.Circle for circular collision shapes

    master

    The SAT.Circle class represents a circle with a position (pos) and a radius (r). You can also set an offset vector that is applied to the radius during collision tests.

    const pos = new SAT.Vector(100, 100);
    const circle = new SAT.Circle(pos, 50);
    
    // Get the Axis-Aligned Bounding Box (AABB) as a Box object
    const aabbBox = circle.getAABBAsBox();
    
    // Get the AABB as a Polygon object
    const aabbPolygon = circle.getAABB();
  9. Test collision between two polygons with testPolygonPolygon()

    master

    Use testPolygonPolygon(a, b, response) to determine if two Polygon objects intersect.

    If a response object is provided, it will be populated with collision details if an intersection is detected. The response includes:

    • a: The first polygon.
    • b: The second polygon.
    • overlapV: A vector representing the final overlap vector (calculated as the overlap normal scaled by the overlap amount).

    Returns true if the polygons intersect, and false otherwise.

    // Assuming a and b are SAT.Polygon instances and response is a SAT.Response instance
    const collided = SAT.testPolygonPolygon(polyA, polyB, collisionResponse);
    
    if (collided) {
      console.log('Collision detected!');
      console.log('Overlap vector:', collisionResponse.overlapV);
    }
  10. Use SAT.Vector for 2D vector math

    master

    The SAT.Vector class (aliased as SAT.V) represents a 2D vector with x and y properties. Most methods support method chaining by returning this.

    const v1 = new SAT.Vector(10, 20);
    const v2 = v1.clone().add(new SAT.Vector(5, 5)); // v2 is (15, 25)
    
    v1.normalize().scale(2); // Scales the unit vector by 2
    
    const dot = v1.dot(v2);
    const length = v1.len();
    const lengthSq = v1.len2();
  11. Use SAT.Box for axis-aligned rectangles

    master

    The SAT.Box class represents a simple box with a position, width, and height.

    Creation:

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

    Properties:

    • pos: The bottom-left coordinate (smallest x and y).
    • w: Width.
    • h: Height.

    Methods:

    • toPolygon(): Returns a new SAT.Polygon representing the box's edges. Use this if you need to test a box against other polygons using testPolygonPolygon.
    var b = new SAT.Box(new SAT.Vector(10,10), 20, 40);
  12. Handle collision results with SAT.Response

    master

    The SAT.Response object stores the results of a collision test, including overlap data.

    Properties:

    • a, b: The two objects involved in the collision.
    • overlap: Magnitude of the overlap on the shortest colliding axis.
    • overlapN: The shortest colliding axis (unit vector).
    • overlapV: The overlap vector (overlapN.scale(overlap, overlap)). Subtracting this from object a's position will resolve the collision.
    • aInB: Boolean, true if a is completely inside b.
    • bInA: Boolean, true if b is completely inside a.

    Important: If a collision test returns false, do not examine the values in the response. Always call response.clear() before reusing a response object for a new test.

    var response = new SAT.Response();