Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solving Billiard Shot Impulse Trajectory

I'm using bullet to make a pool simulator and need to accurately simulate shots that are humanly possible. To find the impulse to apply to the cue ball I use the locations of the object ball, pocket center and cue ball.

Common shot scenario
(source: poolplayers.com)

In situations where the motion path of the cue ball is similar to the object ball (a hit angle near 180 degrees), everything works fine and the object ball sinks in the pocket. But it seems that the more angular the shot path is, the greater the margin of error is for the impulse I'm generating. I've tried many things to fix this: adjust the ball's collision margin, scaling the world larger, turning off friction and restitution and lots of others but nothing seems to changes this behavior.

Here are the relevant bits of my code:

//assume p = pocket center, b = object ball center, c = cue ball center

//first find the position of the ghost ball, ie the target point of collision for the cue ball
btVector3 ghostPos = b+(b-p).normalize()*(2.0f*BALL_RADIUS);

//then use the normal between the ghostball and cue ball as the impulse, scaled by the shots total distance
btVector3 cueImpulse = (ghostPos-c).normalize()*((p.distance(b)+ghostPos.distance(c))*HIT_RATIO);

//finally apply the impulse to the cueball's center of mass (using general form of applyImpulse to later use rel_pos for english
cueBallBody->applyImpulse(cueImpulse,btVector3());

Hopefully that's enough info. I've been struggling with this bug for a looong time and now this very large project I've been working on for almost two years is contingent on solving this problem! Even if you don't see what's wrong with my code, but have an alternative strategy for finding the impulse - I would LOVE to hear it because I'm afraid I don't have anymore ideas.

like image 367
uno_1_herman Avatar asked Oct 16 '13 17:10

uno_1_herman


Video Answer


1 Answers

If you want to do complex physics that include rotation of the ball, then I recommend Billiards type of physics:

Example:

http://www.real-world-physics-problems.com/physics-of-billiards.html

http://archive.ncsa.illinois.edu/Classes/MATH198/townsend/math.html

If you want simpler physics I recommend rather "Ball to Ball Collision" for 2D or "Sphere to Sphere collision" for 3D. A quick search in Google, you will find a lot of examples of how to implement it.

Examples:

http://www.hoomanr.com/Demos/Elastic2/

Ball to Ball Collision - Detection and Handling

Time:

I recommend calculating the timestamp the collision occurred. Calculate all your physics to that time point (pre-collision). That will be your ghostball position. Calculate the collision, including the new speeds of the balls. Then then calculate all your physics for the rest of the time period (post-collision).

Direction:

What you describe actually make sense (physics wise) for me. If the ball is moving upwards (if you look at your diagram), then the transfer of momentum will be more upwards, and you have to do a small compensation in direction for it. The correct way is to write out the formula for the 2D speed at collision and position with the direction, and work it out that way.

Update: Easy way: Rotate the ghost ball around the colliding ball in the opposite direction of the error, the degrees to rotate it is relative to the degrees in fault / distance.

like image 79
Gerhard Powell Avatar answered Oct 03 '22 18:10

Gerhard Powell