search

Class myphysicslab.lab.engine2D.ImpulseSim

Provided By
Extends
All Implemented Interfaces
All Known Direct Subclasses

Simulation of RigidBody movement with collisions. ImpulseSim adds methods for collision detection and collision handling to the super-class RigidBodySim.

The overall collision handling algorithm is implemented in myphysicslab.lab.model.CollisionAdvance. The two main methods that CollisionAdvance asks ImpulseSim to perform are:

  • #findCollisions Returns the current set of collisions and also contacts. Checks each corner and edge of each body to see if it is penetrating into another body (or nearby for a contact). Creates a myphysicslab.lab.engine2D.RigidBodyCollision corresponding to each collision (or contact) found and returns them in an array.

  • #handleCollisions For each collision, calculates and applies the appropriate impulse to handle the collision.

More information:

Parameters Created

Events Broadcast

Collision Handling Options

There are several different collision handling options available. See the section on Multiple Simultaneous Collisions and myphysicslab.lab.engine2D.CollisionHandling.

Contacts During Collision Handling

Resting contacts, joints, and imminent collisions are involved in the collision handling mechanism, as part of a multiple simultaneous collision. The handleCollisions method can calculate the impulse needed at each point, which can be a big performance win.

Consider for example a situation where there are 2 or more bodies in resting contact, and a third body collides into one of the resting bodies. The result will be a complex series of ricochet collisions back and forth until finally all the bodies are either separating or in resting contact.

If you calculate such a scenario by considering only one collision at a time, then after each collision we would step forward in time, find collisions, back up to where we were, handle the collision, and do that over and over for each ricochet. This would take far more compute time than doing the equivalent inside of handleCollisions.

Finding the Collision Impulse

This reviews some of the math involved in #handleCollisions.

Define these symbols

v_i = initial velocity (vector, length n)
v_f = final velocity (vector, length n)
A = n x n matrix giving change in velocity for impulse at each contact
j = impulses at each contact (vector, length n)
n = number of contacts
e = elasticity

Then we have

v_f = A j + v_i

We also have

v_f = -e v_i

therefore

0 = A j + (1+e) v_i

this corresponds to the equation in myphysicslab.lab.engine2D.ComputeForces

0 = A f + b

so we put the (1+e) v_i factor into the b vector when passing to ComputeForces.

If you look at the web page http://www.myphysicslab.com/collision.html you will see a derivation of the following equation giving the value of j for a single collision.

ma = mass of body A
n = normal vector pointing out from body A (length 1 here)
j = impulse scalar
jn = impulse vector
va = old linear velocity of cm for body A
va2 = new linear velocity of cm
wa = old angular velocity for body A
wa2 = new angular velocity
ra = vector from body A cm to point of impact = (rax, ray)
Ia = moment of inertia of body A about center of mass
vab = relative velocity of contact points (vpa, vpb) on bodies
vab = (vpa - vpb)
vpa = va + wa x ra = velocity of contact point
vab = va + wa x ra - vb - wb x rb
cross product: w x r = (0,0,w) x (rx, ry, 0) = (-w*ry, w*rx, 0)

              -(1 + elasticity) vab.n
j = -------------------------------------
      1     1     (ra x n)^2    (rb x n)^2
    (--- + ---) + ---------  + ---------
      Ma   Mb        Ia           Ib

In an earlier version of handleCollisions, the above equation was used directly. Now we use ComputeForces because there might be multiple simultaneous collisions, but it amounts to the same equation. If there is only a single collision, then the above equation still exists in the following pieces:

  • the (1+e) v_i factor is in the b vector (v_i is the same as vab above).

  • the denominator is the A matrix

This corresponds to solving for j as

0 = A j + (1+e) v_i
j = -(1 + e) v_i / A

This only works when A is a scalar value not a matrix. Otherwise you would left-multiply by the inverse of the A matrix.

new ImpulseSim( opt_name )

Parameters
opt_name(string|undefined)

name of this Subject

Instance Methods

Instance Properties

Static Properties