Archived

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

Collision impulse

This topic is 5142 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have another perheps newbie question for all you math and physics gurus . I have tried to implement Chris Heckers impulse formulas from http://www.d6.com/users/checker/pdfs/gdmphys3.pdf . But no sucess. I want to make collision respons for a bonding box against static world; I use these formula: j =(-(1+e)v1ab.n )/(n.n(1/ma + 1/mb)+(rap.n)^2/Ia+(rbp.n)^2/Ib) I have reduced this to the following because object ''b'' is the static world. j =(-(1+e)v1.n )/(n.n(1/m)+(rp.n)^2/I) Then i use: v2 = v1 + (j/m)*n //linear velocity W2 = W1 + (rp.jn/I) //angular velocity But i get real strange values with the linear velocity. Is the collision point, rp, supposed to be relative to the center of the mass ? The inertias, I, i store in a Vector with the inertia for the thre axis. Same with the collision normal, n, and the angular velocity, w. For exampel when i have the following values i get the folliwing answer. n = {0,0,1} e = 1 ma= 1472 I = {2000, 2500, 500} v1= {0,0,-10} rp= {0,0,10} v2 = {0. ,0. , -9.973 } I find this a bit strange. How can the box still travel in the same direction ? The collision point ( rp ) is right on the Z-axis of the collision box. So there wouldn''t be any change in rotation, the box would just bounce back with {0,0,10} as velocity vector. What am I doing wrong ? I am very confused here and would gladly receive som help . /Niklas

Share this post


Link to post
Share on other sites
rp should be relative to the centre of mass of the body, and if your body hits it head on, rp should be {0, 0, -10}

your change in velocity looks OK; you loose momentum, so the impulse is directed the right way. How do you calculate the inertia? It''s got to be consistent with your body''s mass (the inertia matrix looks nice and big, but the inverse inertia should be tiny) and the collision point should also be consistent with the size of your body. If you have a box-shaped body, the collision point has to be on the body surface. If it is too much forward (not on the box surface), rp.n will be massive (it is even squared), which will weaken the impulse. Remember, the inertia calculations rely on the box''s size, so size and distances matter.

I think V2 = V1 + (n * j / ma), so j should be well in the range of 1,000s

Have a look at my rigid body demo if you like, I did a similar algorithm.



- Oli.




Home

rigid body demo

Simple Z-fail Stencil shadows demo

Sphere/cube/Triangle Collision And Physics demo




Share this post


Link to post
Share on other sites
Okej, I don't think I'm with you on the inertia bit. I only have the Inertia calculated for the three different axis and store it in a Vector. How should you store it in a matrix ? And should it be the inverse of that matrix when put in the above formulas ?

/Niklas

[edited by - Niklas2k2 on November 12, 2003 11:39:51 AM]

Share this post


Link to post
Share on other sites
usually, inertia matrices for simple, well balanced shapes, are diagonal matrices, so your vector components would be the diagonal of a 3x3 matrix. I''m not sure how you calculate your inertia matrix, but storing it in a vector is definitely wrong

Anyway, you can''t divide a vector by a vector.

AFAIK, an inertia matrix for an axis aligned box of size (x, y, z) is calculated as follow


x2 = Box.Size.x * Box.Size.x;
y2 = Box.Size.y * Box.Size.y;
z2 = Box.Size.z * Box.Size.z;

ix = (y2 + z2) / 12;
iy = (x2 + z2) / 12;
iz = (x2 + y2) / 12;

Box.InertiaTensor = [ix 0 0]
[ 0 iy 0]
[ 0 0 iz]

Box.LocalInertia = Box.InertiaTensor * Box.Mass;
Box.LocalInvInertia = Box.InertiaTensor.Transpose() / Box.Mass;

Box.WorldInvInertia = Box.Orientation * Box.InvInertiaTensor.Transpose() * Box.InvOrientation.Transpose();



Box.WorldInvInertia is the inertia matrix you use in the collision impulse equation.

The inertia Tensor (not sure if the term is right), is the inertia matrix for an axis aligned box of mass 1.

The local inertia is the inertia of the axis aligned weighted box.

the world inertia is the inertia of the oriented box in world space (that is when you calculate the collision impulse and the rotational velocity and acceleration).

The inverse is, well, ...the inverse . Since the matrix is orthogonal, the inverse can be simplified with a transpose.

Share this post


Link to post
Share on other sites
Okej, thanks for taking the time :D

Iv''e looked at your rigid body demo a bit and seen your calculations.

the

ix = (y2 + z2) / 12;
iy = (x2 + z2) / 12;
iz = (x2 + y2) / 12;

are the same formulas that I use.

But when you inverse it I do not quite follow.

How can transposing
[ix 0 0]
[ 0 iy 0]
[ 0 0 iz]
be the same as inversing it ? Transposing this matrix does nothing if im not mistaking ?

/Niklas

Share this post


Link to post
Share on other sites
I got my knickers in a twist. Transpose = inverse only for orthogonal matrices, like orientation matrices, not inertia matrices. Inverse do mean inverse unfortunately. D'oh.

to be on the safe side...


Box.LocalInertia = Box.InertiaTensor * Box.Mass;
Box.LocalInvInertia = Box.LocalInertia.Inverse();
Box.WorldInvInertia = Box.Orientation * Box.LocalInvInertia * Box.Orientation.Transpose();


Some kind of a brain fart. working too hard I suppose.

[edited by - oliii on November 13, 2003 6:43:08 PM]

Share this post


Link to post
Share on other sites