Collision Response Question

Member
Posts: 208
Joined: 2005.04
Post: #16
here's a quicker way:

newDirectionOfBall = (2 * angleOfCollision) + 180Ëš - directionOfBall

where angleOfCollision is the angle which describes the point where the ball hit the circle
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #17
... I don't see how that's less complicated. I still would have to calculate all the angles, and then convert them back into vectors. I'm open to being convinced, though...
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #18
... And it gets even cooler!

Press return to spawn new balls. My machine can handle about 80 without dipping beneath 30FPS.

Now they bounce off of each other! Way cool!

Link: http://www.owlnet.rice.edu/~ajm4979/BG0.01.zip
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #19
blobbo Wrote:... I don't see how that's less complicated. I still would have to calculate all the angles, and then convert them back into vectors. I'm open to being convinced, though...

Don't your vectors already contain angles? For example, I'd probably make a C struct like this...

typedef struct Vector {
double angle;
double magnitude;
} Vector;

So where are these conversion calculations you're talking about?
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #20
hes probably using cartesian instead of polar coordinates, i.e. x and y instead of r and theta, so the conversion involes arc tangent from c->p and sine and cosine for p->c.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #21
unknown is correct. My struct contains simply an x and a y coordinate which I normalise for calculations.
Quote this message in a reply
Member
Posts: 78
Joined: 2002.06
Post: #22
looks very cool, what kind of goal do you have in mind? take a look at this pinball game:http://www.secretlevel.de/RapidMotion.swf

also you might want to only bounce balls if their respective velocities are moving them closer together, it's a simple way of stopping them getting stuck together
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #23
I recommend you use bounding box collision before circle - circle detection to make it run faster, and also you need to do one of two things to avoid sticking,
either move the balls apart from eachother (ball A moves normalised direction from A-B * disatnce/2 and B moves the negative of that) then decrease the velocity slightly to compensate, because you create and destroy energy by just moving objects which is unrealisttic,

or a much better way is to check if there is a collision, step back a frame and subdivide the time, basically play numguess until you get the balls almost perfectly touching each other instead of intersecting, then calculate their new velocites and animate by the rest of the time for that frame, and continue animating as usual afterwards.

actually I could write a tutorial on timestep subdivision, if that would be useful for people?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 78
Joined: 2002.06
Post: #24
unknown Wrote:I recommend you use bounding box collision before circle - circle detection to make it run faster
Actually I believe sphere/circle collision detection is faster in general and definitely in this case.
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #25
Unknown:
- Bounding box will save processor cycles by avoiding sqrt, right? I think that's what you're saying
- Timestepping is the next implementation project I have. Would be nice to have some nice commented code to work from, but this is heavily documented already

Will: I've got a general idea in mind where 1-4 players each occupy a section of the circle's circumference. Each player has a "cannon" that can pitch back and forth, and fire balls into the circle. The idea is that you have to hit the other player's cannon. Think of it like reverse pong.

There's lots of ideas here, notably powerups and assorted obstacles. Ideally this is a multiplayer game, but networking scares the bejeezes out of me, so I'll program an AI first and maybe allow for two players on a single mac.

To avoid making a super-AI, I think that I'd have some sort of "mission" mode where you have to collect objects in the ring while fighting away foes.

In the long, long, long range I see this being a really neat 3D game, with debris in the ring that the ball picks up, much like in Katamari. But the debris alters the balls trajectory, making it complicated.

I think it's a neat idea that shouldn't be too hard to implement. Might give me time to make a working game for once! That's why I'm using Quartz - I want to work comfortably in order to hopefully be able to finish this stupid project!
Quote this message in a reply
Member
Posts: 78
Joined: 2002.06
Post: #26
sqrt(a) < sqrt(b) === a < b
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #27
dx = (a.x-b.x)
dy = (a.y-b.y)
if dx*dx+dy*dy < a.r*b.r

is slower than

if a.x+a.r > b.x-b.r || if a.x-a.r < b.x+b.r
if a.y+a.r > b.y-b.r || if a.y-a.r < b.y+b.r

dx = (a.x-b.x)
dy = (a.y-b.y)
if dx*dx+dy*dy < a.r*b.r

for lots of circles

There was a cool circular pong game called vortex or somthing I think, pre OS X.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #28
Ok, so I've tried to implement timestepping by iterating back from my ball's current position to a point where it just is touching the surface of the collision object. Occasionally this doesn't work, however, and it causes these nasty hangs on occasion. I'm posting the full function for reference.

PHP Code:
- (void)collideBallWithOtherBalls:(BGBall *)ball
{
    
id collisionBall;
    
    
NSEnumerator *ballsEnumerator = [balls objectEnumerator];
    while (
collisionBall = [ballsEnumerator nextObject])
    {
        if (
collisionBall != ball)
        {
            
// Collision Detection
            
if (vectorDistance([collisionBall position], [ball position]) <
                                ([
collisionBall radius] + [ball radius]))
            {
                
// COLLISION RESPONSE
                
                /* Adjust position of balls to be in a pixel-perfect collision, store the remainder
                to be added afterwards */
                
                
float remainder 0;
                while (
vectorDistance([collisionBall position], [ball position]) <
                                ([
collisionBall radius] + [ball radius]))
                {
                    [
collisionBall moveDistance:-TIMESTEP_AMOUNT];
                    [
ball moveDistance:-TIMESTEP_AMOUNT];
                    
remainder += TIMESTEP_AMOUNT;
                }
                
                
vector normal vectorNormalise(vectorSubtract([collisionBall position], [ball position]));
                
vector approachVel vectorSubtract([ball direction], [collisionBall direction]);
                
float projectedApproachSpeed vectorDotProduct(normalapproachVel);
                
vector velocityChange vectorMultiply(normalprojectedApproachSpeed);

                [
collisionBall setDirection:vectorAdd([collisionBall direction], velocityChange)];
                [
ball setDirection:vectorSubtract([ball direction], velocityChange)];
                
                
// Animate both balsl the remaining distance following collision
                
[collisionBall moveDistance:remainder];
                [
ball moveDistance:remainder];
            }
        }
    }


TIMESTEP_AMOUNT is currently defined as 0.1 - I figured that was accurate enough.

Any ideas?
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #29
change
if (vectorDistance([collisionBall position], [ball position]) < ([collisionBall radius] + [ball radius]))

You need to track back an entire frame before doing the while loop with
[collisionBall moveDistance:-TIMESTEP_AMOUNT];
[ball moveDistance:-TIMESTEP_AMOUNT];
inside it and then divide the timestep by two and check which side the perfect case is on, then subdivide that and so on,
looping with a variable is a very inefficient way, you can much much higher accuracy with bisection method than that way.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #30
Woah, I found this by total coincidence
http://homepage.mac.com/felinegames/game...suals.html
its on KittyMac's homepage, the vortex game I mentioned earler.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Collision Response merrill541 7 3,656 Nov 8, 2008 09:14 PM
Last Post: merrill541
  Edge Collision Response Problem Bachus 9 6,247 Mar 21, 2008 03:34 PM
Last Post: Skorche
  Simple 2D collision response Wowbagger 1 4,627 Jul 30, 2007 03:02 PM
Last Post: Skorche
  Collision Response With Circles Nick 8 3,518 Nov 3, 2006 04:11 PM
Last Post: Skorche
  Yet Another Collision Detection Question t3knomanser 1 2,161 Apr 14, 2006 06:46 AM
Last Post: codemattic