Skip to main content
gamedev.net
🔒 Locked

Bouncing Collision Response.

Started by mrKablamo Mar 12, 2007 at 5:45 PM 5 replies 1.9k views
Original Post
mrKablamo
mrKablamo
I just have a quick question that I was wondering if someone could help me with. So I have my collision function working for a point on triangle collision. But I want to expand this to have the object bounce off the triangle. I'm trying to write a function that takes in these parameters: Vec3 &InitialPos, Vec3 &InitialVel, float DeltaTime, Triangle &Tri, Vec3 &FinalPos, and Vec3& FinalVel. I need to insert the final position and velocity into the last to params. I figure its something like get the triangles surface normal, and normalize the initialVel, then crossproduct those to get the new velocity is this right? If someone could help me I would greatly appreciate it
Cowboy Coder
Cowboy Coder
To reflect a vector V in a plane with normal N, it's

2*N*(N dot V)-V

That's projecting V onto N, then doubling it in size, and subtracting it from itself, then negated, equivalent to:

-(V-2*N*(N dot V))

The signs are a little confusing, just draw a diagram.
mrKablamo
mrKablamo
That makes perfect sence thank you.
squidlarkin
squidlarkin
I need to solve the same problem but with an added twist. My game's in 2D and the objects being collided with are simply lines, not necessarily polygons. Since having a normal implies that you know which side of the line you're going to be bouncing off of, am I going to have one-sided lines that can be passed through going the other way?
iMalc
iMalc
Quote:
Original post by squidlarkin
I need to solve the same problem but with an added twist. My game's in 2D and the objects being collided with are simply lines, not necessarily polygons. Since having a normal implies that you know which side of the line you're going to be bouncing off of, am I going to have one-sided lines that can be passed through going the other way?
2D, 3D, 4D, the math is the same.

If you want both sides to cause bounce-off, then you can first do a dot product of the velocity with the normal, and if that is negative, then use the reverse of the normal instead.
intrest86
intrest86
Quote:
Original post by iMalc
Quote:
Original post by squidlarkin
I need to solve the same problem but with an added twist. My game's in 2D and the objects being collided with are simply lines, not necessarily polygons. Since having a normal implies that you know which side of the line you're going to be bouncing off of, am I going to have one-sided lines that can be passed through going the other way?
2D, 3D, 4D, the math is the same.

If you want both sides to cause bounce-off, then you can first do a dot product of the velocity with the normal, and if that is negative, then use the reverse of the normal instead.

You don't need to reverse anything, the formula works using just one normal for either direction of movement. You can test this for yourself by plugging '-N' into the equation in place of N. You end up getting the very same equation.
Turring Machines are better than C++ any day ^_~
oliii
oliii
Yeah, but you do need to check if the dot prodcut (V . N) is negative (the ball is going towards the plane). Else sometimes, the sphere will get stuck on the plane.

If you are doing it in 2D, with line segments, you can generalise the problem by using the 'Closest point' algo. You find the closest point of te sphere centre on the segment. If that point is within the sphere radius, then you have an intersection. Then you need to push the sphere back so that it just touches that closest point, and reflect along the same 'push back' vector (which is (Sphere.Centre - Position).

To find the closest point on a segment, you first find the closest point on the infinite line, and clamp the result within the segment end points.

bool SphereSegmentCollide(C_Sphere& sphere, const C_Segment& segment){    Vector E = segment.EndPoint - segment.StartPoint;    Vector D = sphere.Centre    - segment.StartPoint;    // find parametric postion of the closest point on the infinite line    float de = E.Dot(E);    float e2 = E.Dot(E);    float t = de / e2;    // clamp within segment range    if (t < 0.0f) t = 0.0f;    if (t > 1.0f) t = 1.0f;        // closest point on segment to sphere centre    Vector Q = segment.StartPoint + E * t;    // Check if closest point intersects the sphere    Vector H = sphere.Centre - Q;    float h2 = H.Dot(H);    float r  = sphere.m_Radius + segment.m_Radius;    float r2 = r * r;    // nope. no collision    if (h2 > r2) return false;    // yes. Push the sphere back. Calculate normal and depth of collision    float h      = sqrt(h2);    Vector Ncoll = H / h;    float  dcoll = r - h;    Vector PushBack = Ncoll * dcoll;    sphere.Centre += PushBack;     // reflect the sphere on the collision plane.       float vn = sphere.Velocity.Dot(Ncoll);   // impact velocity    if (vn > 0.0f) return true;              // sphere is escaping from the plane. dont reflect.    sphere.Velocity += (-2.0f * vn) * Ncoll; // reflect    return true;}


That's about it really, to have a ball bouncing around a bunch of segments. The ball may pass through segments, and to fix that, you slice the ball motion into smaller steps (say, no more than 1/3 of teh radius of the sphere), and check each of those steps along the way.
Everything is better with Metal.

Topic Locked

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

Sign in to reply to this topic.