Sign in to follow this  
shahmirj

Rotation after Collision

Recommended Posts

Any one here can help me or point me to the right Direction would be nice I have collided and solved the impulse of 2 polygon objects now i want to do the last and hard part which is rotate them according to the collision. I need to basically figure out the Angular Velocity of the objects. My program can rotate objects clockwise and anti clockwise using positive or negative angular velocity. Any body here can even post a link to somebody who has explained this would be nice. Thanks

Share this post


Link to post
Share on other sites
Depends, if you want a 'true to life' example, you will need to consider momentum of inertia, mass, copute the points of contact, apply collision impulse at the points of contact, that will change your linear and angular momentum.

Look at Chris Hecker's article on physics for a full explanation, and I have a rigid body demo as well.

Share this post


Link to post
Share on other sites

int FindSupportPoints(const Vector& N, float t,
const Vector* A, int Anum,
const Vector& PA, const Vector& VA,
const Matrix& OA, Vector* S)
{
Vector Norm = N ^ OA;
float d[32];
float dmin;
dmin = d[0] = A[0] * Norm;

for(int i = 1; i < Anum; i ++)
{
d[i] = A[i] * Norm;

if (d[i] < dmin)
{
dmin = d[i];
}
}

int Snum = 0;

const float threshold = 1.0E-3f;

for(int i = 0; i < Anum; i ++)
{
if (d[i] < dmin + threshold)
{
S[Snum++] = Transform(A[i], PA, VA, OA, t);

if (Snum == 2)
return Snum;
}
}
return Snum;
}



Thats from the doc in that link you gave me ollii. Here is what i dont understand

The parameter Vector A, Should be one entity of a vector and not a whole list. Is A donating all the points in the polygon.

Also N is that the minimun Interval Axis or is that each axis we go by.

OA is another concept that completely flies over my head.

You see in my code the objects are rotated by changing each of the points of the polygon from the center point of the polygon. Therefore i dont understand the concept of OriginalA, Is that part to do with rotating the point on an angle.

The whole conecpt of that function is just going straight over from my head.

Im sorry any ideas?

Share this post


Link to post
Share on other sites
The function gives you the supporting vertices along a given direction. That is, if you imagine a box sitting flat on a table, and the supporting axis vertical, (vector(0, 1)), the function will give you the two vertices at the bottom of the box. in 2D, there is only a maximum of two vertices that can support a convex object.

OA is the orientation matrix, and it is derived from the orientation angle.


OA = ( cos(a) sin(a) )
(-sin(a) cos(a) )


PA is the centre of the object A. VA its velocity. the array S[] is the support opint of the polygon, transformed by the polygon's orientation, position and velocity. Basically the position of the supporting vertex at time t.

All this support point malarkey it to compute the contact points on an object.

If you have a sphere, it's much simpler, since there will always be one.

BTW, that code would be simpler if the contact points stored in the collision report were all relative to the bodies's space. So there would not be any transforms until the collision is resolve. I'll sort it out later.

EDIT : You've been looking at the docs. Ignore them, they are old stuff that's been deprecated. The code in example 7 should make more sense.

Share this post


Link to post
Share on other sites
Quote:
PA is the centre of the object A. VA its velocity. the array S[]


I have all that i have also calculated the S[]

Obviously as i understand it. Before i can even begin about rotation i need the support points or in other words exactly where are the polygons colliding

Thats is the part that is confusing me beyond repair

Cause i look at the Tutorial 7 and i find we need pa and pb


Vector pa = m_contacts.m_contact[i].m_position[0];
Vector pb = m_contacts.m_contact[i].m_position[1];
Vector ra = pa - a->m_position;
Vector rb = pb - b->m_position;


If i can get pa and pb i can get ra and rb, and if i can get ra and rb i can do

a->m_angvelocity += (ra ^ impulse) * a->m_invinertia;
b->m_angvelocity -= (rb ^ impulse) * b->m_invinertia;

lets just leave the impulse and m_invinertia alone for now.

So if you can simplify this for me.. The contact points. how do i get that projection.

Please let me show you my code so you understand at what point have i gotton

bool pPhysics::PolyCollision(int index){

float Interval;
float minInterval = 0.0;
Vector translationAxis;
Vector axis;
Vector Vab, Vn, Vc, Vt;

//Return the Object
cObjects* obj = getObjects();

//calculate the min interval and the translation axis using the seperation axis theorm

//Push Back the Object using the Translation Axis
//Round the the Values so we dont end up inside again
ov.position.x += floorf((minInterval * translationAxis.x) * 0.5f);
ov.position.y += floorf((minInterval * translationAxis.y) * 0.5f);

//os.v = os.v - Vc;

Vab = os.v - obj->poly[index]->os.v;
float dot = Vab.DotProduct(translationAxis);
Vn = translationAxis * dot;
Vt = Vab - Vn;

Vc = (Vt * -1) + (Vn * -2);

float MassA = os.mass / (os.mass + obj->poly[index]->os.mass);
float MassB = obj->poly[index]->os.mass / (os.mass + obj->poly[index]->os.mass);

if (!obj->poly[index]->isStatic) { obj->poly[index]->os.v = obj->poly[index]->os.v - (Vc * MassA); }
os.v = os.v + (Vc * MassB);

os.v.Round();


//Return true to say there has been a collision
return true;
}




Note: it dosent show the objects being tranlated to their new angles. But it does it in another function so therefore imagine if they are. The actual loops do the SAT but they are left out as we are not discussing about that, so the minInterval and translationAxis are calculated using that theorm, Also elacticiyt and Friction is left at constant for now

Share this post


Link to post
Share on other sites
There is a difference between the support points and the contact points.

I use the support points to derive the contact points.

in 2D, there are three main cases for finding out the contact points.

1) vertex on A vs edge on B.
2) edge on A vs vertex on B.
3) edge on A vs edge on B.

the other case (vertex on vertex) should never occur, but what the hell, it's handled as well.

finding the support points will give you one of the three cases. You will find that the supports will either be an edge (2 points) or just a vertex (one point).

So, given the support point configuration, you can derive the contact points (which is what example 6 is about).

to derive the contacts from the supports, it's relatively straight forward in 2D, and quite intuitive.

see picture below.



case 1), it is vertex [C] against an edge [AB].

[A] and [B] will be the support points on polygon 1, [C] will be the support point on polygon 2.

contacts work by pairs. You need one point on contact on each polygon. Therefore, from the case 1), contact on polygon 2 will be the vertex [C] itself, and the contact on polygon 1 will be the point on edge [AB] closest to [C].

for case 2), both support are edges (respectively [AB] for poly 1, and [CD] for poly 2). There are several methods to find the contact points (vertices [C] and [B], paired with their projections on the opposite edges).

I used a rather simplistic approach, by finding all possible 4 contacts pairs for [A], [B], [C] and [D], pairing them with the closest points on the opposite edge, and sorting the contacts by distance between the points in the pairs. The obvious choices would be the two contact pairs with the minimum distance.

This 'closest point' method isn't the fastest, but it's very simple. All you need to know is the three possible cases you can be confronted with, and what support vertices converts to what contact points in the three cases.

so, the principle is this.

1) perform the SAT test.
2) find the MTD vector.
3) the MTD will give you the normal of collision and distance of intersection.
4) find the support vertices on both polygons along the normal of collision. You will have either one, or two support vertices for each polygon.
5) from the support point configuration, derive the contact pairs. You will have a maximum of two contact pairs.
6) compute the impulse at the contacts. that impulse will generate linear change in momentum, and a angular change on momentum.

Hope that helps

Share this post


Link to post
Share on other sites
Thanks man starting to make alot more scence

Let me first try to rig up the contact points and then figure out the support points.

Its alot clearer when i understood the difference between the two.

I think i might have a problem later in actually figuring out the rotation velocity after this step. But we will see when we get there.

Il post if i have further problems, And post the final result if it works

Thanks ollii you are the best

Share this post


Link to post
Share on other sites
you're welcome. Do look at Chris Hecker's articles on physics. It's basic Newtonian A level physics, or about. It uses the conservation of momentum to derive the equations.

Share this post


Link to post
Share on other sites
On the Third Post

Is "A[0] * Norm;" is equall to A.DotProduct(Norm)

Or are you multiplying

If you are multiplying how are you getting a float number by multiplying two vectors together?

Share this post


Link to post
Share on other sites
Ok so i have done it and i get 4 contact points

However in your code you did

SupportPoints asup = m_poly[0].getSupports(m_ncoll);
SupportPoints bsup = m_poly[1].getSupports(-m_ncoll);

my m_ncoll are the other way around



SupportPoints findSupportPoints(Polygon *A, Vector Axis);

int main(){

Polygon A;
A += Vector(-25, -25);
A += Vector(-25, 25);
A += Vector(25, 25);
A += Vector(25, -25);

A.Center = Vector(0, 0);

A.printPoints();

Polygon B = A;

B.MoveNextPosition(Vector(50, 0));

B.printPoints();

CollInfo result;

if (A.Collision(&B, &result)){
cout << "A and B are Colliding\n";
}

cout << "\n\nSupport Points\n";
SupportPoints asup = findSupportPoints(&A, -result.axis);
SupportPoints bsup = findSupportPoints(&B, result.axis);

for (int x = 0; x < asup.points.size(); x++){

cout << asup.points[x].x << ", " << asup.points[x].y << "\n";
}

for (int x = 0; x < bsup.points.size(); x++){

cout << bsup.points[x].x << ", " << bsup.points[x].y << "\n";
}

return 0;
}

SupportPoints findSupportPoints(Polygon *A, Vector Axis){

SupportPoints support;

float min = -1.0f;
const float threshold = 1.0E-1f;

for (int x = 0; x < A->points.size(); x++){

float t = Axis.DotProduct(A->points[x]);
if (t < min || x == 0){ min = t; }
}

for (int x = 0; x < A->points.size(); x++){

float t = Axis.DotProduct(A->points[x]);

if (t < min + threshold){
support.points.push_back(A->points[x]);
if (support.points.size() == 2){ break; }
}
}

return support;

}




The Answer i get is:

Polygon...A
-25, -25
-25, 25
25, 25
25, -25
Center: 0, 0

Polygon...B
25, -25
25, 25
75, 25
75, -25
Center: 50, 0
A and B are Colliding

A Support Points
25, 25
25, -25

B Support Points
25, -25
25, 25
Press any key to continue . . .

Share this post


Link to post
Share on other sites
it depends what you consider support points (maximas or minimas?), what way your normal is pointing (towards body A or B?)... All in all, it doesn't matter, it's just personal preference and conventions.

Share this post


Link to post
Share on other sites
Here is one for you

Why the for loop?


for(int i = 0; i < m_contacts.m_count; i ++)
{
Vector pa = m_contacts.m_contact[i].m_position[0];
Vector pb = m_contacts.m_contact[i].m_position[1];
Vector ra = pa - a->m_position;
Vector rb = pb - b->m_position;
Vector va = a->m_velocity + ra.perp() * a->m_angvelocity;
Vector vb = b->m_velocity + rb.perp() * b->m_angvelocity;

float vn = ((va - vb) * m_ncoll);
if(vn > 0.0f) continue;

float ta = (ra ^ m_ncoll) * (ra ^ m_ncoll) * a->m_invinertia;
float tb = (rb ^ m_ncoll) * (rb ^ m_ncoll) * b->m_invinertia;
float m = a->m_invmass + b->m_invmass;
float denom = m + ta + tb;
float j = -(1.0f + CoR) * vn / denom;

Vector impulse = m_ncoll * j;

a->m_velocity += impulse * a->m_invmass;
b->m_velocity -= impulse * b->m_invmass;

a->m_angvelocity += (ra ^ impulse) * a->m_invinertia;
b->m_angvelocity -= (rb ^ impulse) * b->m_invinertia;
}


I mean i know why the for loop, It's because of the contact pairs. If there is an edge vs edge collision then we have to do this.

But surely if we can determine Pa and Pb as the middle of the contact edges couldn't we skip the for loop.

I mean when i look at Chris Heckers (Figure 1 Object A and B Colliding, Physics Part 3: Collision Response) P-A is easy to calculate as its the Vector returned by the supportPoint function, but P-B is on an edge.

Isn't there a way to calculate P-B without pairing, and obviously as i think i understand it if we have P-A and P-B we can completely get rid of the for loop.

Share this post


Link to post
Share on other sites
I suppose you could. What you propose is basically reducing the contact manifold (here, two contact pairs) to a single contact. It's an approximation but it should work.

However, the procedure to resolve simultaneous contacts is different than resolving unique contacts. You'll have to keep in mind that reducing the contact manifold to a single contact could introduce stability issues.

Similarly, the way I resolve the intersection (by pushing along the mtd vector), is also crude. If you really want to get down to it, then you'd have to consider constraints and then it gets ugly.

EDIT : I tried reducing it to a single contact pair, and it's behaving good. So I'll amend the code.

here it is.

[Edited by - oliii on September 21, 2008 9:48:01 AM]

Share this post


Link to post
Share on other sites
Interesting.. Ive breezed it but il post comments if i have any more question

BTW: Olii you are going on my Final Report listen is there a website link you can provide for your work so i can citate it?

And once again you is the best

Share this post


Link to post
Share on other sites
you're welcome. I don't have a website, just my posting here. All I have is a link to the packed files I'm afraid :)

If you want more citations and references for your report, you can link Chris Hecker's website. The physics I have is basically derived from his. My main focus in the examples is about the SAT / swept SAT algorithm, not really the physics in itself (which as I said, is a direct transposition of what is on C.H.'s website).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this