What am I doing wrong? ( Closing Velocity )

Started by
19 comments, last by johnstanp 13 years, 6 months ago
Sorry John. But I missed your reply. And just saw your message.

Quote:There's a contradiction in your second sentence: if there exists a separating axis then the two bodies are not colliding. There's no collision when at least there exists a separating axis. So there's a collision when there doesn't exist a single separating axis.


Sorry, when I refer to the Sep-Axis there, I meant the axis where the collision has the least amount of penetration. I know I used the wrong term. What I meant here was the following

Image and video hosting by TinyPic

Frame 1 :

A Vel = (-6,0)
B Vel = (5,0)

Normal for use within closing vel test = (1,0) or (-1, 0)
pick (1,0) as its most opposite A's Vel

ClosVel = Dot( B-A, (1,0) );
= Dot( (11,0), (1,0) );
= positive, so closing

Frame 2 :

A Vel = ( 6,0)
B Vel = (-5,0)

Normal for use within closing vel test = (1,0) or (-1, 0)
pick (-1,0) as its most opposite A's Vel

ClosVel = Dot( B-A, (-1,0) );
= Dot( (-11,0), (-1,0) );
= positive, so closing

Advertisement
Well, if you have two bodies colliding what matters is: the normal is related to which body?
If it is related to the first body, then let's say that by definition, it points outside the first body. This is all we need to know. You could choose the normal that points ouside the second body: the choice is arbitrary.

//contact_normal points outside volume1
bool intersection( Bounding_volume const & volume1, Bounding_volume const & volume2, Vector3 & contact_normal );

If the contact_normal points outside volume1, then if body2 is traveling further inside body1, we know that they're not separating: that's the opposite.

if( intersection( volume1, volume2, contact_normal ) ){   Vector3 relative_velocity = substract( velocity2, velocity1 );   //relative velocity of body 2 to body 1    if( dot_product( relative_velocity, contact_normal ) < 0 )   {   //body 2 is going further inside body 1   }   else   {      //the two bodies are in contact, but are separating   }}


In short, the value stored in contact_normal should clearly respect a convention. I mean a convention: you should always return the value of the normal pointing outside volume1, if it is the convention you chose. Now apply that convention in the examples you provided, and see what I mean. Next change the convention (normal pointing outside volume2 and relative_velocity = substract(velocity1, velocity2)), and see what I mean.
Quote:Original post by johnstanp
Simply compute the closing velocity this way:
closing_velocity = dot( velocityB - velocityA, contact_normal )

You want to know if body B is moving away from body A. If the relative velocity of body B to body A has a positive component along the contact normal relative to body A, then body B is moving away from body A. Test that with your examples.
Are you sure your contact normal is always pointing outside of body A? And that your impulses make the two bodies reverse their components along the contact normal?


At the moment my SAT test method just returns the axis, and so the contact normal doesnt follow a convention. So I'll need to fix that.

I plan to have it so that the contact normal is always facing A, and that B will have an impulse of -Normal, such as in the following examples.

Image and video hosting by TinyPic

So now I need a way to look at the collision of A and B, and return the axis in the form of a normalized contact normal that is always facing A. This part doesnt need to take into consideration the velocities does it? I plan to do this by using the minimumX of A and B ( where the X axis is the SAT axis ) to first figure out if a is on the left or right of B, and then dot it with the current axis to see if it is pointing the right way. Any suggestions?
Quote:Original post by maya18222
At the moment my SAT test method just returns the axis, and so the contact normal doesnt follow a convention. So I'll need to fix that.

Which axis?
If the two bodies do collide, then there's no separating axis. If they do not collide, then there's no need of that kind of information.
You need a contact normal when a collision is detected: not an axis. Unless, by "axis", you meant "vector", which would imply all vectors are axes and only axes.
To do collision detection and response, you must be able to generate contact information ( normal and contact point(s)/segment/polygon) when there is a collision detected.
But why should we go further? You posted a figure with two possible normals: have you at least tested my algorithm with an arbitrary choice of contact normal between the two possibilities? Start there first.
When I refer to the axis from the Sat test, i mean the line marked in red. Which when a collision has occured, is the axis of minimum penetration of the objects. My sat test is defined to return a bool, and takes a reference as a parameter to a contactNormal which is set if a collision occurs.

bool Sat( object o1, object o2, Vector2& ContactNormal ){   if( collision ) {    // figure out which way axis is to point, ie        // ContactNormal = axis;        // or    // ContactNormal = -axis;    return 1;   }   else return 0;}


Now that line marked in red can point in 2 directions, when that line is set to the correct direction, i refer to that as the contact normal, which is the arrow marked in red.

Quote:
But why should we go further? You posted a figure with two possible normals: have you at least tested my algorithm with an arbitrary choice of contact normal between the two possibilities? Start there first.


I dont know what you mean. There is only one normal in those diagrams, marked by the red arrow. That is, to point towards A by convention, as in the diagram.

My problem at the moment is figuring out which way the axis should point when set for the contact normal. I've defined the fact that it needs to point towards A by convention, but I need a way to calculate this, as that red line ( which I refer to as the axis of collision ) when passed as the contact normal, could be -axis or +axis, shown above in the source code.

Doesnt this need to be calculated before moving onto the closing velocity test which I believe you're refering to in the following reply

Quote:have you at least tested my algorithm with an arbitrary choice of contact normal between the two possibilities? Start there first


What Im trying to say is that before I use the closing velocty test, provided there is a collision, I first need to get the contact normal for that collision, pointing towards A.

All I have at the moment is the axis, ( shown by the red line ). I need to now get a contact normal from that, which always points towards A.

That is, I need to figure out should the Contact Normal be

ContactNormal = axis;

or

ContactNormal = -axis;
Quote:Original post by maya18222
What Im trying to say is that before I use the closing velocty test, provided there is a collision, I first need to get the contact normal for that collision, pointing towards A.

All I have at the moment is the axis, ( shown by the red line ). I need to now get a contact normal from that, which always points towards A.

That is, I need to figure out should the Contact Normal be

ContactNormal = axis;

or

ContactNormal = -axis;


You know the position of the two boxes (I mean the value of their respective centers).
Choosing the orientation that points towards the inside of A (towards its center), is then easy (litterally).

if( dot_product( axis, centerA - centerB ) > 0 ) contact_normal = axis;
else contact_normal = -axis;
Yeah, that was my first thought, but then I figured it might not work for every shape. But I'll see how it goes.
Quote:Original post by maya18222
Yeah, that was my first thought, but then I figured it might not work for every shape. But I'll see how it goes.

The shapes must be convex, of course. Why should it work for every shape? Because it should work for every shape or is it because you do have some shapes that are not convex?

I have a question: how could you use SAT for a non-convex shape ("every shape") without decomposing it? What does an axis mean in that case?
If you want an algorithm that will work for every possible case, you'll need something more general and guess what, harder to understand and implement.
Unless you must take into account all possible cases, you'd better stick with simple cases, with convex shapes.
All my shapes will be convex, but I was thinking more objects where the CM might not be in the center of the object, for certain effects, and where the position would always be the CM. Unless of course that is not the case.

But anyway, forget all that. I'll get the simple case working first :)

This topic is closed to new replies.

Advertisement