Skip to main content
gamedev.net
🔒 Locked

Pool collision detection

Started by tieTYT Apr 29, 2004 at 11:42 PM 9 replies 1k views
Original Post
tieTYT
tieTYT
I found an algorithm online at the gamasutra website. Here''s the link http://www.gamasutra.com/features/20020118/vandenhuevel_01.htm I think it''s pretty well known, i''ve seen it suggested here a few times. It''s the article about how to do proper collision detection with circles and spheres and it uses pool as an example. What i want to know is... is this article truly correct? I''m starting to have my doubts. I implimented it as best as i could according to the examples and the first thing i noticed is that it automatically considers it a failure if "A isn''t moving towards B". But when i implimented this, it meant it wouldn''t recognize a collision if an object was moving left and another object was moving left but they run into each other. I''ve found that this type of situation constantly messes up the algorithm given on the web site. I was forced to comment out that early escape and now i find that if i hit an object from "behind" (we''re moving in the same direction but i''m moving faster so i can catch up to it) my resultant direction when i collide with it is not back the other direction, but actually across the object i collided with. So with these types of problems i was wondering if anyone could figure out if i did something incorrectly or if they actually already know that this algorithm is incorrect. Thanks. I''ll post my code on request.
OmniBrain
OmniBrain
As I remember that article they consider one sphere being stationary, so the effective speed of object 2 just is v2-v1.
in your case if sphere 1 is moveing left with 1 m/s and the other is moving left with 2 m/s, the effective speed would be 1m/s toward left.

now you also have to put in where your spheres are located, but the right sphere moving with 2m/s (effective 1m/s) will move toward the one on left side...

hope this will answer your question

-----The scheduled downtime is omitted cause of technical problems.
tieTYT
tieTYT
quote:
Original post by OmniBrain
As I remember that article they consider one sphere being stationary, so the effective speed of object 2 just is v2-v1.
in your case if sphere 1 is moveing left with 1 m/s and the other is moving left with 2 m/s, the effective speed would be 1m/s toward left.

now you also have to put in where your spheres are located, but the right sphere moving with 2m/s (effective 1m/s) will move toward the one on left side...

hope this will answer your question




hm it seems to make sense. Now that i think about it, i think i forgot to subtract the vectors when i was noticing this problem.

Now does this totally explain the weird problems i would have like going through an object at the wrong direction when i hit it while we're going the same direction?

ALSO: The article gives a suggestion of how to move the objects the right amount of space when you've figured out that they have collided. You take (v2-v1)/v1 * distance and move the owner of v1 that far and you take (v2-v1)/v2 * distance and move the owner of v2 that far (if i understand correctly, this is at the bottom of page 2). Now, does that take into account the size of the objects, or will i have to move that far, and subtract by the size of the radius of the two objects?

[edited by - tieTYT on April 30, 2004 3:05:31 AM]
OmniBrain
OmniBrain
At least some of your problems should been solved by this (maybe there are some other bugs in your code )

About moving the spheres to new locations:
Basically it is calculate the time until the collision happens, then move the object for that timeframe (position object1 = position object1 + v1*time of frame, same with object 2)
but somehow
(v2-v1)/v1 * distance
doesn''t look right to me...
(pos1 - pos2) / (v1-v2) = time to collision;
so
newPos1 = oldPos1 + ((oldPos1 - oldPos2) / (v1-v2)) * v1;

(bringing all into multiple dimensions is some more fun, too )

after a collision your spheres should been moving away from each other, so the next timeslice a collision wouldn''t been considered between them at all. (make sure you have small slices and not 100s of objects in a bulk, or this will mess your code too and you have to take care about it).
-----The scheduled downtime is omitted cause of technical problems.
SpaceDude
SpaceDude
I haven''t read the article... but it sounds like what they are saying is, if you have balls A and B with velocity Va and Vb at positions Pa and Pb.

if (DotProduct(Pb-Pa, Va-Vb) < 0)
{
// No collision
}

This means if the balls are moving away from each other (relatively), then don''t collide. Otherwise you may get your balls stuck into each other, if for example the balls come in to collision and you reflect the velocities. Then on the next frame if the balls haven''t had time to move apart yet, you may detect another colision and reflect the velocities again. And so your balls will just stick together and vibrate, reflecting velocity each frame.

tieTYT
tieTYT
quote:
Original post by SpaceDude
I haven''t read the article... but it sounds like what they are saying is, if you have balls A and B with velocity Va and Vb at positions Pa and Pb.

if (DotProduct(Pb-Pa, Va-Vb) < 0)
{
// No collision
}

This means if the balls are moving away from each other (relatively), then don''t collide. Otherwise you may get your balls stuck into each other, if for example the balls come in to collision and you reflect the velocities. Then on the next frame if the balls haven''t had time to move apart yet, you may detect another colision and reflect the velocities again. And so your balls will just stick together and vibrate, reflecting velocity each frame.




Yeah, i think that''s what that is for too. And i fixed it so that works for me. The problem was that i was setting the B''s Y velocity to it''s X velocity on accident.

tieTYT
tieTYT
Alright, now collision detection is fine, i fixed a little error and now it will detect collision detection if we''re going in the same direction.

But i still have the same problem that if i hit something that''s going in the same direction as me, my resultant vector is in a direction THROUGH the object i hit... probably the exact opposite direction i should go. I figure i might as well just post my code here since this may be as specific as that. I hope nobody minds:


// First, find the normalized vector n from the center of

// circle1 to the center of circle2

Vector *player1pos = player1->turnPositionIntoVector();
Vector *cometpos = comet->turnPositionIntoVector();

Vector *n = vectorBetweenTwoPoints(player1pos, cometpos);
//source of possible errors if this is in the wrong order


normalize(n);


// Find the length of the component of each of the movement

// vectors along n.

// a1 = v1 . n

// a2 = v2 . n


//get v1 and v2

Vector *v1 = new Vector();
v1->x = player1->getDirection()->x;
v1->y = player1->getDirection()->y;

Vector *v2 = new Vector();
v2->x = comet->getDirection()->x;
v2->y = comet->getDirection()->y;

GLdouble a1 = dot(v1, n);
GLdouble a2 = dot(v2, n);

// Using the optimized version,

// optimizedP = 2(a1 - a2)

// -----------

// m1 + m2

GLdouble optimizedP = (2.0 * (a1 - a2)) / (player1->getMass() + comet->getMass());

// Calculate v1'', the new movement vector of circle1

// v1'' = v1 - optimizedP * m2 * n

Vector *v1prime = new Vector();
v1prime->x = v1->x - optimizedP * comet->getMass() * n->x;
v1prime->y = v1->y - optimizedP * comet->getMass() * n->y;

// Calculate v1'', the new movement vector of circle1

// v2'' = v2 + optimizedP * m1 * n

Vector *v2prime = new Vector();
v2prime->x = v2->x + optimizedP * player1->getMass() * n->x;
v2prime->y = v2->y + optimizedP * player1->getMass() * n->y;

//this is where i set the player''s resultant

//direction. This keeps on pushing me across the comet

//if i hit the comet from "behind"


xPushBack = v1prime->x * player1->getSpeed();
yPushBack = v1prime->y * player1->getSpeed();

//this is where i set the comet''s resultant

//direction

comet->setDirection(*v2prime);
grekster
grekster
Not all collisions result in a change of direction for both balls. Say ball A and ball B are both moving in the same direction and ball A collides with B, ball A could continue in the same direction but just be travelling slower.
Quote: Original post by BosskIn Soviet Russia, you STFU WITH THOSE LAME JOKES!
tieTYT
tieTYT
quote:
Original post by grekster
Not all collisions result in a change of direction for both balls. Say ball A and ball B are both moving in the same direction and ball A collides with B, ball A could continue in the same direction but just be travelling slower.



ohhhh, well then that would explain it! Because i''m using some unrealistic physics in my game. I want the player to be pushed back noticably when he hits the comet but i don''t want the comet to be slowed down ever. Have any suggestions on how i could mimic this?
oliii
oliii
the classic way of doing it is


Vector Vel = pObj2->Vel() - pObj1->Vel();
float m1 = pObj1->InverseMass();
float m2 = pObj2->InverseMass();
float m = m1+m2;

const float restitution = 0.3f;

Vector dV = Normal * -((1.0f + restitution) * Vel.Dot(Normal));

pObj1->Vel() -= dV * (m1 / m);
pObj2->Vel() += dV * (m2 / m);

Everything is better with Metal.
Airo
Airo
give the comet a large mass, or just do not change it''s velocity in your code.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.