Collisions of physical circles arising and sliding against borders

In Java, I am writing a mobile application for Android to interact with some dynamic balls with some classes that I wrote myself. Gravity is determined by the tilt of the phone.

I noticed when I have a bunch of balls grouped in a corner that some of them will start to tremble or sometimes slip, while colliding with other balls. Could this be because I'm following the steps in the wrong order?

Right now I have one loop going through each ball:

  • Sim iteration
  • Check for collisions with other balls
  • Check for conflicts with scene boundaries

I must add that I have friction with boundaries and when a ball collides with a ball, just to lose energy.

This is part of the code for how the collision occurs:

// Sim an iteration for (Ball ball : balls) { ball.gravity.set(gravity.x, gravity.y); if (ball.active) { ball.sim(); // Collide against other balls for (Ball otherBall : balls) { if (ball != otherBall) { double dist = ball.pos.distance(otherBall.pos); boolean isColliding = dist < ball.radius + otherBall.radius; if (isColliding) { // Offset so they aren't touching anymore MVector dif = otherBall.pos.copy(); dif.sub(ball.pos); dif.normalize(); double difValue = dist - (ball.radius + otherBall.radius); dif.mult(difValue); ball.pos.add(dif); // Change this velocity double mag = ball.vel.mag(); MVector newVel = ball.pos.copy(); newVel.sub(otherBall.pos); newVel.normalize(); newVel.mult(mag * 0.9); ball.vel = newVel; // Change other velocity double otherMag = otherBall.vel.mag(); MVector newOtherVel = otherBall.pos.copy(); newOtherVel.sub(ball.pos); newOtherVel.normalize(); newOtherVel.mult(otherMag * 0.9); otherBall.vel = newOtherVel; } } } } } 
+5
source share
4 answers

If this is the only code that checks the interaction between the balls, the problem seems pretty clear. It is impossible for the ball to remain in balance on the other ball.

Say you have one ball right on top of another. When you calculate the acceleration of the upper ball due to gravity, you should also do a collision check similar to the one you posted, except for this time to check dist <= ball.radius + otherBall.radius . If so, then you must accept the normal force between the balls equal to the mass of gravity and deny the component of gravity in accordance with the vector connecting the centers of the two balls. If you do not, the upper ball will accelerate at the bottom, causing the conflict code that you posted, and you will get inconvenience.

Similar logic should be used when the ball is in contact with a related scene.

+2
source

Since I experimented with my own Phys2D engine (just for fun), I know what you're saying. (Just in case - you can check my demo here: http://gwt-dynamic-host.appspot.com/ - select "Circle Collisions Demo" there and the corresponding code here: https://github.com/domax/gwt -dynamic-plugins / tree / master / gwt-dynamic-main / gwt-dynamic-module-bar ).

The problem is the nature of the iterations and the endless loop of colliding consequences. When, for example, the ball reaches the corner of the stage, it experiences at least 3 force vectors: the rebound impulse from the wall, the rebound impulse from the floor and the gravity impulse - after you sum all 3 impulses, reduce it in accordance with the energy loss algorithm you have to have a new vector where your ball should be. But, for example, this impulse directs it to the wall - then you need to again count the set of vectors for all things: bounce energy, momenta, gravity, etc. Even if all these impulses are small, you will never get them all 0, because of the accuracy of doubling and tolerance comparison constants - because you have the effects of “jitter” and “slip”.

In fact, most existing 2D engines have these effects in one form or another: you can see them here: http://brm.io/matter-js/demo/#wreckingBall or here: http: // box2d-js .sourceforge.net / index2.html - in fact, they simply absorb small impulses and stop the iteration when the whole system becomes more or less stable, but this is not always possible.

In any case, I would just recommend not reinventing your own wheel, unless it's just for your pleasure - or for a better understanding of this material.

For the latter (JFF) - here is a good tutorial: http://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev -6331

For real things, I would recommend using existing engines, for example. Unity ( https://unity3d.com/learn/tutorials/modules/beginner/2d/physics2d ) or Box2d ( http://box2d.org/ )

Hope this helps.

+1
source

Iterating through all the balls and changing the position of the balls for each iteration is probably the cause of instability, you move the ball to the left to avoid a collision to the right, and then you pushed the ball into another ball on the left and then the left ball tries to get it back.

From head to toe, I could recommend trying to summarize all the forces on each ball before doing anything with positioning. And if you go over the ball “from above” (farthest from the source / direction of gravity), you can probably achieve a stable situation.

Basically, the top ball must first calculate the forces between itself and the ball under it, as well as the force of gravity, then the ball under it will know how much force comes from the top ball and is added with gravity, this also add to the force in which it pushes balls under it. When all the balls know the forces with which they push, you can turn this force into motion.

+1
source

The way you simulate the physics of balls inevitably causes instability. Your collision resolution tries to separate the balls by projecting one of them in the opposite direction to the depth of the collision. This can fix the overlap for these two balls, but there is a chance (especially when the balls are stacked) that the ball now overlaps with another ball.

There are many ways to fix penetration. One of the easiest ways is to add an “offset” or a little push to both bodies to make them split into the next two frames. This allows you to spread this energy and displace all bodies. The problem is that the bias is often overestimated and causes some rebound. To fix this problem, I would recommend reading on a sequential pulse.

Physics is not as realistic as it may seem. If you do not mind instability, I would recommend spending some time reading using various techniques or using an engine such as Box2D.

+1
source

Source: https://habr.com/ru/post/1244012/


All Articles