Ball to Ball Collision - Gets significant speed in a collision

I have implemented the code from the Ball to Ball Collision - Detection and Handling question in Objective-C. However, when the balls collide at an angle, their speed increases sharply. All vector math is done using cocos2d-iphone with the title CGPointExtension.h. What is the reason for this unwanted acceleration?

The following is an example of increasing speed:

Input:
mass == 12.56637
speed.x == 1.73199439
speed.y == -10.5695238

ball.mass == 12.56637
ball.velocity.x == 6.04341078
ball.velocity.y == 14.2686739

Output:
mass == 12.56637
speed.x == 110.004326
speed.y == -10.5695238

ball.mass == 12.56637
ball.velocity.x == -102.22892
ball.velocity.y == -72.4030228

#import "CGPointExtension.h" #define RESTITUTION_CONSTANT (0.75) //elasticity of the system - (void) resolveCollision:(Ball*) ball { // get the mtd (minimum translation distance) CGPoint delta = ccpSub(position, ball.position); float d = ccpLength(delta); // minimum translation distance to push balls apart after intersecting CGPoint mtd = ccpMult(delta, (((radius + ball.radius)-d)/d)); // resolve intersection -- // inverse mass quantities float im1 = 1 / [self mass]; float im2 = 1 / [ball mass]; // push-pull them apart based off their mass position = ccpAdd(position, ccpMult(mtd, (im1 / (im1 + im2)))); ball.position = ccpSub(ball.position, ccpMult(mtd, (im2 / (im1 + im2)))); // impact speed CGPoint v = ccpSub(velocity, ball.velocity); float vn = ccpDot(v,ccpNormalize(mtd)); // sphere intersecting but moving away from each other already if (vn > 0.0f) return; // collision impulse float i = (-(1.0f + RESTITUTION_CONSTANT) * vn) / ([self mass] + [ball mass]); CGPoint impulse = ccpMult(mtd, i); // change in momentum velocity = ccpAdd(velocity, ccpMult(impulse, im1)); ball.velocity = ccpSub(ball.velocity, ccpMult(impulse, im2)); } 
+4
source share
3 answers

I am the one who wrote the source code for the return ball that you referenced. If you download and try this code, you will see that it works fine.

The following code is correct (the way you originally used it):

 // collision impulse float i = (-(1.0f + RESTITUTION_CONSTANT) * vn) / (im1 + im2); CGPoint impulse = ccpMult(mtd, i); 

This is a very common physical code, and you can see it in almost exactly the same way in the following examples:

This is correct, and it is ~ not ~ creating CoR over 1.0, like others. It calculates the relative momentum vector based on mass and Restitution Factor.

Ignoring friction, a simple example of 1d is as follows:

 J = -Vr(1+e) / {1/m1 + 1/m2} 

Where e is your CoR, Vr is your normalized velocity, J is the scalar value of the pulse velocity.

If you plan to do something more advanced, I suggest you use one of the many existing physics libraries. When I used the code above, it was good for a few balls, but when I increased it to several hundred, he began to choke. I used the Box2D physics engine, and its solver could handle more balls, and that is much more accurate.

In any case, I looked at your code and at first glance it looked beautiful (this is a fairly correct translation). This is probably a small and subtle error with the wrong value passed in or the mathematical problem of the vector.

I don’t know anything about iPhone development, but I would suggest setting a breakpoint at the top of this method and follow every step resulting from it and find where the bloat happens. Make sure the MTD is correctly calculated, impact speeds, etc. Etc., until you see where a large increase is introduced.

Send back the values ​​of each step in this method, and we will see what we have.

+3
source

Having studied the source code and comments of the original poster, the code seems the same, so if the original is the correct implementation, I would suspect a bad vector library or some kind of uninitialized variable.

Why are you adding 1.0 to the restitution ratio?

From: http://en.wikipedia.org/wiki/Coefficient_of_restitution

COR is usually a number in the range [0,1]. Qualitatively, 1 is a completely elastic collision, and 0 is a completely inelastic collision. It is theoretically possible for COR to be more than one, which is a collision that generates kinetic energy, such as land mines thrown together and exploding.

Another problem is the following:

 / (im1 + im2) 

You divide by the sum of the reciprocal masses to get an impulse along the contact vector - you probably should divide the sum of the masses themselves. This increases your momentum ("what she said").

+5
source

In this line:

 CGPoint impulse = ccpMult(mtd, i); 

mtd should be normalized. The error occurred because in the source code mtd was normalized in the previous line, but not in your code. You can fix this by doing something like this:

 CGPoint impulse = ccpMult(ccpNormalize(mtd), i); 
0
source

All Articles