Circle/Circle collision response.

Started by
3 comments, last by oliii 16 years, 1 month ago
Hey all. I am in need of some help with getting something that, at least looks to be, a realistic rebound reaction when a circle hits another circle. Here is the situation; I am making a simple 2D Air Hockey game in J2ME (so complex maths operations are not my friend) and I need to simulate the puck bouncing off the players bat. The players bat itself is controlled directly by the player and as such, has no velocity of its own so for the sake of the calculation it can be thought of as a stationary object. The puck has a velocity and a direction which is specified by two floats (one for X and one for Y). I was wondering if someone knew of a relatively cheap method of calculating the direction that the puck should be moving in after it hits the players bat. (J2ME has a function to detect if two sprites are colliding, but I’m not sure if that will be a help here or not). As ever, any help is appreciated.
Advertisement
Quote:Original post by MrDoom
Hey all. I am in need of some help with getting something that, at least looks to be, a realistic rebound reaction when a circle hits another circle.

Here is the situation; I am making a simple 2D Air Hockey game in J2ME (so complex maths operations are not my friend) and I need to simulate the puck bouncing off the players bat. The players bat itself is controlled directly by the player and as such, has no velocity of its own so for the sake of the calculation it can be thought of as a stationary object. The puck has a velocity and a direction which is specified by two floats (one for X and one for Y).

I was wondering if someone knew of a relatively cheap method of calculating the direction that the puck should be moving in after it hits the players bat. (J2ME has a function to detect if two sprites are colliding, but I’m not sure if that will be a help here or not).

As ever, any help is appreciated.



Hi,

ok. .what you want to do is calculate the tangent to your circle where the puck hits the bat. this tangent is now your 2D plane ( line )... what you want to do now is reflect the direction that the puck came in using the normal to that line. This of course only applys when the bats don't move. Same rule for when hitting fixed objects like walls or other stuff.

hope this helps,
Peter Wraae Marino
http://osghelp.com - great place to get OpenScenGraph help
Yes, you should be able to do this without using any trig. You need to mirror the puck's velocity vector about the line which passes through the centers of both circles. You should be able to get the equation of this line in general form (ax + by = c).

Then, you must find a line perpendicular to this mirror line which also passes through the location of your puck. The point at which this line intersects the mirror line will be the midpoint of the segment between the puck's oldvelocity and what the puck's velocity should be... Draw a picture if this doesn't make sense.

I'm not sure if nonmoving paddles are the best strategy; the paddle's velocity could be used to give the puck more force. If you decide you want to have moving paddles, all you have to do is consider the movement of the puck relative to the movement of the paddle, then translate that back into absolute velocity.
-- Paul Kernfeld
Quote:Original post by kernylicious
Draw a picture if this doesn't make sense.


Right, I tried drawing a picture but I got a bit confused after the first paragraph.



I don't suppose you could elaborate a bit more? (The annoying thing is, I'm sure I did this in GCSE maths, that, was a few years ago now though.)

[Edited by - MrDoom on March 25, 2008 9:51:25 PM]
That's been discussed 100's of time :)

circle [pos, vel, rad, mass] (position, velocity, radius, mass).

bool collide(Circle& a, Circle& b){    // separation vector    Vector d(b.pos - a.pos);    // distance between circle centres, squared    float distance_squared = d.DotProduct(d);    // combined radius squared    float radius = b.rad + a.rad;    float radius_squared = radius * radius;     // circles too far apart    if(distance_squared > radius_squared)         return false;    // distance between circle centres    float distance = (float) sqrt(distance_squared);    // normal of collision    Vector ncoll = (d / distance);    // penetration distance    float dcoll = (radius - d);    // inverse masses (0 means, infinite mass, object is static).    float ima = (a.mass > 0.0f)? 1.0f / a.mass : 0.0f;    float imb = (b.mass > 0.0f)? 1.0f / b.mass : 0.0f;    // separation vector    Vector separation_vector = ncoll * (dcoll / (ima + imb));    // separate the circles    a.pos -= separation_vector * ima;    b.pos += separation_vector * imb;    // combines velocity    Vector vcoll = (b.vel - a.vel);       // impact speed     vector vn = vcoll.DotProduct(ncoll);        // obejcts are moving away. dont reflect velocity    if(vn > 0.0f)         return true; // we did collide    // coefficient of restitution in range [0, 1].    const float cor = 0.95f; // air hockey -> high cor    // collision impulse    float j = -(1.0f + cor) * (vn) / (ima + imb);    // collision impusle vector    Vector impulse = j * ncoll;    // change momentum of the circles    a.vel -= impulse * ima;    b.vel += impulse * imb;    // collision reported    return true;}

Everything is better with Metal.

This topic is closed to new replies.

Advertisement