Collision impulse

Started by
4 comments, last by Niklas2k2 20 years, 5 months ago
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
Advertisement
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



Everything is better with Metal.

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]
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.

Everything is better with Metal.

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
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]

Everything is better with Metal.

This topic is closed to new replies.

Advertisement