Need tips on collision response for a 2D ball hitting another 2D ball that is controlled by an accelerometer

Started by
10 comments, last by tom_mai78101 11 years, 8 months ago
Not sure why everyone is so fascinated by working with angles. It usually makes things more complicated. Anyway a simple collision resolution for this case is to simply offset each ball by half the penetration. void resolveCollision(Ball &a, Ball &b) { vec2 diff = a.position-b.position; double dist = length(diff); double penetration = max(0, a.radius + b.radius - dist); a.position += 0.5*penetration*diff/length; b.position -= 0.5*penetration*diff/length; } Then you just apply that iteratively to all colliding pairs of balls and either have "multi collision" being sorted out over multiple time steps, or iterate this until there is no collisions anymore. This doesn't handle velocity yet but I didn't really get how you want that resolved anyway? just cancel out relative movement? elastic collision


This. You are God! Well, actually, I have never thought about penetration and try to re-offset (or "onset") the position back. It just didn't pop into my mind until your post showed up. Deeply grateful, indeed.

Is there a reason you don't want to use a physics library for this?


Well yes. This is my assignment. We have to learn how the physics behind collision crash courses work and we need ot fully grasp the concepts of it. If I were to rely on a physics library, it would destroy the main purpose of my assignment, even if everything in my program works flawlessly. Another factor is I'm more biased on technique rather than reliance on libraries and avoiding "reinventing the wheel."

All of that is of another topic, I guess. I hoped this answers your question. :D

I'm not really experienced programmer but heres' what I would do: 1. I would find the center of the ball and the radius 2. When a ball move I would loop through all balls and check if the ball 1's radius + ball 2's radius < magnitute(ball 2's pos - ball 1's pos) 3. If the balls are moving with speed higher than ball 1's diameter + ball 2's diameter, I would make the same checks like in 2 but this time with half the current speed (creating temp location and then checking for collisions... also this is bad idea to be hard coded. I mean divide ur speed by the diameter to find out how many checks u need and use loop to check all needed positions so u are sure u won't miss the ball) 4. if collision occurs ( 2. returns true ), get the reverse vector and find out the best position so they don't overlap. f834487711105b9d.gif Lame try to show u whats in my mind..


Your GIF work actually helped me out more than you think; Along with japro's algorithm, his theory, and your GIF, when combined, it really taught me a lot more. Without your GIF, I wouldn't be able to think up on what japro's meaning of "penetration" and what is its usefulness.

In short, your GIF taught me what penetration really means. Japro's algorithm is what taught me how I should execute it. Combined, on my Android phone, it tells me how objects react to the cue ball with the accelerometer, and noticed that the effects seen is the same as how Mario uses the backward long jump to glitch through most of the stages. The effect is basically pushing two overlapping objects apart.

I learned a lot from you guys. Thank you! Deeply appreciated.
Advertisement
Not necessarily a bump, but it's worth this post.

I have found another solution on Google by chance, and I decided to help others who are also looking for collision responses by linking directly and save time Googling for one.

The link is here.

The alternate solution (Author: eBusiness):


public void handleCollisions(){
double xDist, yDist;
for(int i = 0; i < balls.size(); i++){
Ball A = balls.get(i);
for(int j = i+1; j < balls.size(); j++){
Ball B = balls.get(j);
xDist = A.getCenterX() - B.getCenterX();
yDist = A.getCenterY() - B.getCenterY();
double distSquared = xDist*xDist + yDist*yDist;
//Check the squared distances instead of the the distances, same result, but avoids a square root.
if(distSquared <= (A.radius + B.radius)*(A.radius + B.radius)){
double xVelocity = B.xVel - A.xVel;
double yVelocity = B.yVel - A.yVel;
double dotProduct = xDist*xVelocity + yDist*yVelocity;
//Neat vector maths, used for checking if the objects moves towards one another.
if(dotProduct > 0){
double collisionScale = dotProduct / distSquared;
double xCollision = xDist * collisionScale;
double yCollision = yDist * collisionScale;
//The Collision vector is the speed difference projected on the Dist vector,
//thus it is the component of the speed difference needed for the collision.
double combinedMass = A.mass + B.mass;
double collisionWeightA = 2 * B.mass / combinedMass;
double collisionWeightB = 2 * A.mass / combinedMass;
A.xVel += collisionWeightA * xCollision;
A.yVel += collisionWeightA * yCollision;
B.xVel -= collisionWeightB * xCollision;
B.yVel -= collisionWeightB * yCollision;
}
}
}
}
}

This topic is closed to new replies.

Advertisement