2D physics Object rotation collision reaction engine

I am writing my own main physics engine, and now I come to a problem that I cannot solve. Probably because I don’t understand how to solve this problem.

So here is my problem. I hope this image can explain this:

Collision response

I have two objects. Gray is fixed and does not move, and green is on top. The green object has three vectors: force, acceleration and speed. He collides with a fixed gray object.

The real question is: how can I get the rotation of a green object when it falls?

+4
source share
2 answers

It seems that you may not have an understanding of the fundamental physics underlying the dynamics of a rigid body. I say this only because you are not mentioning a single terminology commonly used when talking about this issue. You will need to present the idea of ​​angular orientation and speed (rotational analogs of position and linear velocity) to each dynamic body in the system and calculate all kinds of intermediate quantities, such as moment of inertia, angular acceleration and torque.

Perhaps the best introductory link for this is the Chris Hecker series of articles for Game Developer Magazine. Assuming you already have non-rotational dynamics (see Part 1) and collision detection (not covered by this series), you should start from part 2 and go to part 3. They will give you a solid foundation in physics and the mathematics you need to perform rotational collision.

+9
source

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); // negative val = moving towards each other if (vp_p >= 0) { // do they move apart? return false; } // normal impulse var j = - e * vp_p / ( 1/a.mass + cross(r,n)^2 / ai ); var jn = j * n; // a.vel = a.vel + jn / a.mass; a.r_vel = a.r_vel + cross(r,jn) / ai; 

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); // negative val = moving towards each other if (vp_p >= 0) { // do they move apart? return false; } // normal impulse var j = - e * vp_p / ( 1/a.mass + cross(ar,n)^2 / ai + 1/b.mass + cross(br,n)^2 / bi ); var jn = j * n; // a.vel = a.vel + jp / a.mass; a.r_vel = a.r_vel + cross(ar,jn) / ai; b.vel = b.vel - jp / b.mass; b.r_vel = b.r_vel - cross(br,jn) / bi; 

How formulas / sources work:

http://www.myphysicslab.com/collision.html#resting_contact

+7
source

All Articles