Archived

This topic is now archived and is closed to further replies.

nitzan

Angular Impulse

Recommended Posts

I am reading the book "Physics for Game Developers" and I am trying to implement linear and angular impulse response to a collision. Unfortunately I dont seem to understand the equation supplied in the book. I looked online but it only solved part of my problem. The book gives the following equation: J = -vr ( e+1 ) / {1/m1 + 1/m2 + n . [(r1 x n / I1] x r1 + n . [(r2 x n / I2] x r2} and then... v1+ = v1- + (Jn) / m1 v2+ = v2- + (-Jn) / m2 w1+ = w1- + (r1 x Jn) / Icg w2+ = w2- + (r2 x -Jn) / Icg Where... v1- and v2- are the velocity of object 1 and 2 before the collision. v1+ and v2+ are the velocities after the collision. Same for w1 and w2 except they are for angular velocities. Now my questions are... I1 and I2 are the Inertia Tensors for objects 1 and 2. But do I get their equation depending on what type of object I have ? (rectrangle, sphere, torus, etc...) ? What is Icg ? I found the same equation on line but it was missing Icg. What is this value ? Is it always 1 ? What is n ? The book claims its a unit vector along the line of action at the impact point pointing out from body l. Except there is no body l (thats L) and the line they draw is not perpendicular to either body. On the web it says n is the normal to the surface of contact. How do I calculate it ? Do I simply add the normals of all the faces at the collision point ? Well thats it for now. Thanks in advance to whomever can help or at least point me in the right direction. Nitzan ------------------------- www.geocities.com/nitzanw www.scorchedearth3d.net -------------------------

Share this post


Link to post
Share on other sites
Why have you not consulted the erratum on O'Reilly's website ?

Inertia tensors are defined by the geometry of your objects. See page 19.

Icg is a typo, should be I1 and I2
l (L) is a typo too, should be 1 (ONE).

Both the book and your website quote say the same thing. See figure page 97.

Determining the collision parameters (time and geometry) is the hard part. There is no easy answer. I doubt your solution will work.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on December 26, 2002 4:10:24 AM]

Share this post


Link to post
Share on other sites
Ok, I almost have this working, but I am sure these equations are incorrect:

v1+ = v1- + (Jn) / m1
v2+ = v2- + (-Jn) / m2


Unfortunatley the Erratum doesnt cover these. I definitely need to have r1 and r2 in there somewhere. Can anyone supply me with the correct equations ?

Nitzan

-------------------------
www.geocities.com/nitzanw
www.scorchedearth3d.net
-------------------------

Share this post


Link to post
Share on other sites
Actually let me rephrase my question, since its possible the equation is correct but my code for it is not....

This is my interpretation of the following equations:

v1+ = v1- + (Jn) / m1
v2+ = v2- + (-Jn) / m2
w1+ = w1- + (r1 x Jn) / I1
w2+ = w2- + (r2 x -Jn) / I2

v1f is v1+
model1->returnVelocity() is v1-
model1->returnMass() is m1
w1f is w1+
model1->returnAngularVelocity() is w1-
model1->returnInertia() is I1

Here is my code:

v1f.x = model1->returnVelocity().x + ((J*n.x) / model1->returnMass());
v1f.y = model1->returnVelocity().y + ((J*n.y) / model1->returnMass());
v1f.z = model1->returnVelocity().z + ((J*n.z) / model1->returnMass());

v2f.x = model2->returnVelocity().x + ((-J*n.x) / model2->returnMass());
v2f.y = model2->returnVelocity().y + ((-J*n.y) / model2->returnMass());
v2f.z = model2->returnVelocity().z + ((-J*n.z) / model2->returnMass());

w1f = crossProduct(r1, n);
w2f = crossProduct(r2, n);

w1f.x = w1f.x * J / model1->returnInertia().x + model1->returnAngularVelocity().x;
w1f.y = w1f.y * J / model1->returnInertia().y + model1->returnAngularVelocity().y;
w1f.z = w1f.z * J / model1->returnInertia().z + model1->returnAngularVelocity().z;

w2f.x = w2f.x * J / model2->returnInertia().x + model2->returnAngularVelocity().x;
w2f.y = w2f.y * J / model2->returnInertia().y + model2->returnAngularVelocity().y;
w2f.z = w2f.z * J / model2->returnInertia().z + model2->returnAngularVelocity().z;

Anyone know what I am doing wrong ? The rotation seems to be ok, but the velocities appear to be wrong. The values I am using is two cubes from 1, 1, 1 to -1, -1, -1.

Model1 is translated to 4.0, 0.9, 0.0 with velocity -0.1, 0.0, 0.0

and

Model2 is translated to -4.0, -0.9, 0.0 with velocity 0.1, 0.0, 0.0

The collision point I get is 0.0, 0.0, 0.0, and the normal is 1.0, 0.0, 0.0

My normal might be where I am going wrong. I understood its the normal of the colliding surface of Model1. Is this incorrect ?

Thanks for the help.

Nitzan

-------------------------
www.geocities.com/nitzanw
www.scorchedearth3d.net
-------------------------

Share this post


Link to post
Share on other sites
Hi,
I''m trying to improve my collision system. Currently my collisions work only if object colliding with static object. I''v been reading and searching for info how to do collisions between two rigid bodies and this seems to be what I''m lookig for.
quote:

J = -vr ( e+1 ) / {1/m1 + 1/m2 + n . [(r1 x n / I1] x r1 + n . [(r2 x n / I2] x r2}



I''d just like to know what is the ''vr'' in front there? (I don''t have the book) Otherwise it seems ok, so I''d like to try how it works

Share this post


Link to post
Share on other sites
Wow!! It seems to be working
Should the 'vr' be dotProduct(relative_velocity, contact_normal)?

About your code, I think you should apply negative angular values to model 2.
quote:
Original post by nitzan
v1f.x = model1->returnVelocity().x + ((J*n.x) / model1->returnMass());
v2f.x = model2->returnVelocity().x + ((-J*n.x) / model2->returnMass());

w1f.x = w1f.x * J / model1->returnInertia().x + model1->returnAngularVelocity().x;
w2f.x = w2f.x * (-J) / model2->returnInertia().x + model2->returnAngularVelocity().x; // <========== Should be (-J)????



[edited by - stefu on December 29, 2002 10:44:13 AM]

Share this post


Link to post
Share on other sites
I''ve always assumed that inertia was constant regardless of the axis, and it''s not such a bad approximation most of the time.

There are two types of collisions between polyhedras:

- Vertex/Face: In that case, N is the normal of the face

- Edge/edge: N is the cross-product of the vectors of the two edges

Baraff (use Google) uses the same equations. His papers are online.

HTH,

Cédric

Share this post


Link to post
Share on other sites
I finally realized that the equation I was using was correct and that I coded it correctly (except for that -J). The collision and response didnt look realistic because I am not accounting for friction or elasticity.

I thought that if an Edge collides with a Face then you take the average of the two normals. The cross product gives you a vector perpendicular to the two normals which seems to be, well... useless. Dont you want a vector between the two ?

Nitzan


-------------------------
www.geocities.com/nitzanw
www.scorchedearth3d.net
-------------------------

Share this post


Link to post
Share on other sites