Skip to content

Instantly share code, notes, and snippets.

@gyopiazza
Forked from christopher4lis/util-elastic-collision.js
Last active November 8, 2019 20:48
Show Gist options
  • Save gyopiazza/c924f83087288fe429539b808bcbf94d to your computer and use it in GitHub Desktop.
Save gyopiazza/c924f83087288fe429539b808bcbf94d to your computer and use it in GitHub Desktop.

Revisions

  1. gyopiazza revised this gist Nov 8, 2019. 1 changed file with 16 additions and 0 deletions.
    16 changes: 16 additions & 0 deletions util-elastic-collision.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,19 @@
    /**
    * Check if 2 circles collide
    *
    * Takes velocities and alters them as if the coordinate system they're on was rotated
    *
    * @param Number | p1x | x coordinate of the first particle
    * @param Number | p1y | y coordinate of the first particle
    * @param Number | r1 | radius of the first particle
    * @param Number | p2x | x coordinate of the second particle
    * @param Number | p2y | y coordinate of the second particle
    * @param Number | r2 | radius of the second particle
    * @return Boolean | true if particles are in collision
    */
    const checkCollision = (p1x, p1y, r1, p2x, p2y, r2) =>
    ((r1 + r2) ** 2 > (p1x - p2x) ** 2 + (p1y - p2y) ** 2)

    /**
    * Rotates coordinate system for velocities
    *
  2. @christopher4lis christopher4lis revised this gist Oct 3, 2017. No changes.
  3. @christopher4lis christopher4lis renamed this gist Oct 3, 2017. 1 changed file with 0 additions and 0 deletions.
  4. @christopher4lis christopher4lis created this gist Oct 3, 2017.
    65 changes: 65 additions & 0 deletions Utility Functions for Elastic Collision
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    /**
    * Rotates coordinate system for velocities
    *
    * Takes velocities and alters them as if the coordinate system they're on was rotated
    *
    * @param Object | velocity | The velocity of an individual particle
    * @param Float | angle | The angle of collision between two objects in radians
    * @return Object | The altered x and y velocities after the coordinate system has been rotated
    */

    function rotate(velocity, angle) {
    const rotatedVelocities = {
    x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle),
    y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle)
    };

    return rotatedVelocities;
    }

    /**
    * Swaps out two colliding particles' x and y velocities after running through
    * an elastic collision reaction equation
    *
    * @param Object | particle | A particle object with x and y coordinates, plus velocity
    * @param Object | otherParticle | A particle object with x and y coordinates, plus velocity
    * @return Null | Does not return a value
    */

    function resolveCollision(particle, otherParticle) {
    const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x;
    const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y;

    const xDist = otherParticle.x - particle.x;
    const yDist = otherParticle.y - particle.y;

    // Prevent accidental overlap of particles
    if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {

    // Grab angle between the two colliding particles
    const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x);

    // Store mass in var for better readability in collision equation
    const m1 = particle.mass;
    const m2 = otherParticle.mass;

    // Velocity before equation
    const u1 = rotate(particle.velocity, angle);
    const u2 = rotate(otherParticle.velocity, angle);

    // Velocity after 1d collision equation
    const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
    const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y };

    // Final velocity after rotating axis back to original location
    const vFinal1 = rotate(v1, -angle);
    const vFinal2 = rotate(v2, -angle);

    // Swap particle velocities for realistic bounce effect
    particle.velocity.x = vFinal1.x;
    particle.velocity.y = vFinal1.y;

    otherParticle.velocity.x = vFinal2.x;
    otherParticle.velocity.y = vFinal2.y;
    }
    }