2d balls do not collide properly

I'm just trying to code a beautiful physical game.

A collision with a ball looks good, but if the balls collide too slowly, they β€œstick” to each other. I don’t know why they do it.

Here is my collision function:

private void checkForCollision(ArrayList<Ball> balls) { for (int i = 0; i < balls.size(); i++) { Ball ball = balls.get(i); if (ball != this && ball.intersects(this)) { this.collide(ball, false); } } } public boolean intersects(Ball b) { double dx = Math.abs(b.posX - posX); double dy = Math.abs(b.posY - posY); double d = Math.sqrt(dx * dx + dy * dy); return d <= (radius + b.radius); } private void collide(Ball ball, boolean b) { double m1 = this.radius; double m2 = ball.radius; double v1 = this.motionX; double v2 = ball.motionX; double vx = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2); v1 = this.motionY; v2 = ball.motionY; double vy = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2); if (!b) ball.collide(this, true); System.out.println(vx + " " + vy); motionX = vx * BOUNCEOBJECT; motionY = vy * BOUNCEOBJECT; } 

But this is what happens when they encounter low speed: enter image description here

Do you have an idea?

EDIT:

Alnitak's update works very well ... but one problem still exists ... if I add gravity as follows:

 public void physic() { motionY += GRAVITY; // <= this part (GRAVITY is set to 0.3D) checkForCollision(screen.balls); keyMove(); bounceWalls(); posX += motionX; posY += motionY; } 

They are still moving into each other. I think this is the wrong way to add gravity, or is it not?

And I think I did something wrong with the collision formula, because they do not fall correctly:

! falling balls

and then they slowly sink into the ground.

EDIT: found the AMAZING tutorial: http://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html

+7
source share
3 answers
 (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2); 

This has an integer value of 2. Please do 2.0f or 2.0d, then check it. This should be a problem for low speeds. Becuse whole constant autocastes multiply doublings.

If that doesn't work, Alnitak's answer will be helpful.

If you need real glorious physics, you must use force , and then convert it to speed , and then convert it to displacement . Look at integrator methods like Runge Kutta strong> and Euler Integration

 Force-->acceleration-->velocity-->displacement 

if a collision occurs, just refresh the force, then the rest will flow.

----> http://codeflow.org/entries/2010/aug/28/integration-by-example-euler-vs-verlet-vs-runge-kutta/ <-----

http://www.forums.evilmana.com/game-programming-theory/euler-vs-verlet-vs-rk4-physics/

http://www.newagepublishers.com/samplechapter/001579.pdf

http://cwx.prenhall.com/bookbind/pubbooks/walker2/

Integration of ropes is the point between Runge-Kutta-4 and Euler Integral , preferably for molecular dynamics (a good example for bouncing balls if you omit electric fields and bonds)

+1
source

This is a common problem that happens because sometimes the delta-v of the bouncing ball is not enough to get it out of the collision zone.

Thus, the collision procedure again changes direction, returning it back to another ball, ad-infinitum.

You must add sufficient displacement (in the direction of the collision force) to the position of the ball to make sure that the newly calculated positions no longer collide.

Alternatively, check if the balls will collide after adding new motion values:

 public boolean intersects(Ball b) { double dx = b.posX - (posX + motionX); // no need for Math.abs() double dy = b.posY - (posY - motionY); double d = dx * dx + dy * dy; // no need for Math.sqrt() return d < (radius + b.radius) * (radius + b.radius); } 

but you must also change ball.intersects(this) to intersects(ball) .

They may collide too soon, but they probably won't be visible on a fast-moving ball.

+8
source
0
source

All Articles