Follow the steps below when objects collide.
Call the green rectangle “a” and the other “b”.
1.
First you need the “rotational mass” rectangles, the mass of inertia.
ai = 4/3 * width * height * (width ^ 2 + height ^ 2) * a.density
2.
Then you need a vector pointing from the center of the mass rectangle (the middle position of all angles) to the contact position (where the rectangles collide), let's call it "r".
3.
Then you need to find the collision is normal. This normal is the direction of the momentum applied to a from b. A 1 unit vector is normal. In your example, normal would probably point up. We call the normal vector "n".
4.
Now you need the speed of the contact point on a. If a does not rotate, the formula will be:
vp = a.vel
If a rotates, the formula will be:
vp = a.vel + cross (a.r_vel, r)
a.r_vel is the rotation speed specified in radians, and the positive direction is counterclockwise.
cross () means cross product, function:
cross (v, i) = [-i * vy, i * vx]
Extended formula:
vp = av + [-r * a.r_vel.y, r * a.r_vel.x]
5.
Now you need to calculate whether the objects are moving towards each other. Project vp onto n.
vp_p = dot (vp, n)
point (v1, v2) = v1.x * v2.x + v1.y * v2.y
vp_p is a scalar (value, not a vector).
If vp_p is negative, the monkeys move towards each other, if it is> 0, they move apart.
6.
Now you need to calculate the momentum to stop a from moving to b, the momentum:
j = -vp_p / (1 / a.mass + cross (r, n) ^ 2 / ai)
Cross product between two vectors:
cross (v1, v2) = v1.x * v2.y - v1.y * v2.x
It returns a scalar.
Multiply the momentum with the normal to get the momentum vector:
jn = j * n
7.
Now you need to apply momentum to:
a.new_vel = a.old_vel + jn / a.mass;
a.new_r_vel = a.old_r_vel + cross (r, jn) / ai;
If you want the collision to be fully elastic, you must multiply the momentum by 2. We call this factor "e". e must be between 1 and 2. 1 means that energy is not conserved, 2 means that all energy is conserved.
Code example:
var vp = a.vel + cross(a.r_vel, r); var vp_p = dot(vp,n);
If b is not static, the algorithm will be slightly different:
ar = vector pointing from the center of mass to the contact position
var vp = a.vel + cross(a.r_vel, ar) - b.vel - cross(b.r_vel, br); var vp_p = dot(vp,n);
How formulas / sources work:
http://www.myphysicslab.com/collision.html#resting_contact