1
\$\begingroup\$

I'm making a billiard game and I have two questions:

How do I find the velocity of two balls when they collide with each other and how do I apply it to both balls?

I already know the angles that they're gonna move, I just need to find the velocity that they'll move in those directions.

My game is in 3D, and I'm using Unity. I don't want to use Unity's built-in physics to compute the result in this case, I'd like to know how to compute it myself.

\$\endgroup\$
5
  • \$\begingroup\$ You're not asking a Unity-specific question, you're asking how to calculate the result of an elastic collision between billiard balls. That's a standard, engine-agnostic math problem well explained at the link given in the answer. All you have to do is execute these steps with Unity's vector math classes. If you're stuck there, by all means, edit your question to ask for clarification of the particular step you need help with. \$\endgroup\$
    – DMGregory
    Sep 20, 2016 at 3:34
  • \$\begingroup\$ I agree with @DMGregory, there's nothing Unity-specific here. However the duplication target that was voted on had its only (link-only) answer removed in review, probably after four of the dupe votes were cast. In this case I think this question should be edited to tone down the Unity-specific nature and the duplicate relationship should be flipped. (I have done this.) \$\endgroup\$
    – user1430
    Oct 3, 2016 at 15:36
  • \$\begingroup\$ @JoshPetrie in that case, I'd like to write up a more full-fledged answer based on the linked resource from the other question, since it was fairly comprehensive. Do you happen to have the link handy so I can refer to it? I'd commented on the answer requesting more detail, but since it was deleted it looks like it's disappeared from my action history. \$\endgroup\$
    – DMGregory
    Oct 3, 2016 at 16:28
  • 2
    \$\begingroup\$ @DMGregory gamasutra.com/view/feature/3015/… \$\endgroup\$
    – user1430
    Oct 3, 2016 at 16:31
  • \$\begingroup\$ Are you looking for the impulse resulted of a collision? If you are it is not gonna be trivial. If you just want to prevent penetration it is simpler. If you want to calculate the impulse it is gonna be a long answer. \$\endgroup\$
    – Haruko
    Nov 3, 2016 at 19:41

2 Answers 2

2
\$\begingroup\$

What you are attempting is non trivial and using the internal Physics system is going to be a ton less problematic.

That said, if you really want to eek it out by hand then you need to first detect intersections between the relevant balls, then you need to resolve these out, then you need to update the velocities.

  1. To detect intersections between the balls

This is simply a sphere / sphere intersection test. Iterate through all pairs and check the distance. Distance = (sphere1.transform.position - sphere2.transform.position).Length()

If Length < sphere1.radius + sphere2.radius then you have an intersection and you should resolve them

  1. Resolution of intersection

You first calculate the normal of collision. This is simply

NormalOfCollision = sphere1.transform.position - sphere2.transform.position;
NormalOfCollision.Normalise();

You calculated the sphere distance in (1) so the resolutionDistance is totalRadius - sphereDistance. You then apply this to the bodies.

sphere1.transform.position += NormalOfCollision * resolutionDistance
sphere2.transform.position -= NormalOfCollision * resolutionDistance

If you are going to have spheres of different masses colliding then you should scale the impulse so that the smaller mass is moved more than the larger mass. I.e.

sphere1Impulse = sphere2Mass / (Sphere1Mass + Sphere2Mass);
sphere2Impulse = sphere1Mass / (sphere1Mass + Sphere2Mass);
sphere1.transform.position += NormalOfCollision * resolutionDistance * sphere1Impulse 
sphere2.transform.position -= NormalOfCollision * resolutionDistance * sphere2Impulse 
  1. Calculation of velocity after impact

You need to use the conservation of linear momentumm law. The wikipedia page gives a worked example.

NB

  1. The above is pseudo code, I've not run it, so I may have some of the +ve / -ve signs around the wrong way - butit's the right direction
  2. This just handles the linear effects NOT angular (so won't simulate spin shots etc)
  3. If you have larger time steps, or multiple balls interpenertating you should resolve until you have no more contacts (ObjectA may push ObjectB into ObjectC so you need to resolveagain)
  4. There is no optimisation in this (islanding / broadphase collision etc)
  5. There is no restitution in this with different objects being more bouncy than others
  6. Using PhysX is going to be a ton easier than doing everything yourself
\$\endgroup\$
0
\$\begingroup\$

This question is more about an approach rather than the actual physics.

In this case all your balls should have or contain a component describing the relevant information that you require.

i.e.:

public class Balls
{
    public Vector3 Vector {get; private set;}
    public float Speed {get; private set;}
}

And when the balls meet you can then use this information to do whatever physics you need to perform. For example, depending on your implementation, you may choose to make each ball calculate its own trajectory after colliding with the other, in the OnCollisionEnter function.

\$\endgroup\$
2
  • \$\begingroup\$ Note that if you're moving your balls using your own manual velocity rather than the native physics engine, the accuracy & repeatability of the collisions you get from OnCollisionEnter may be affected. When the physics engine knows exactly how objects are moving, then for spheres it can analytically detect the exact sub-frame moment when they come in contact. If you're moving them manually, then as far as the physics engine is concerned they're just teleporting from place to place, and it won't spot a pending collision until one teleports partway into the other. \$\endgroup\$
    – DMGregory
    Sep 20, 2016 at 12:27
  • \$\begingroup\$ I see. And when the balls do collide they tend to move a little bit which affects the direction that the balls will move on making it look "wrong". Is there any way to fix this ? \$\endgroup\$
    – Ssiro
    Oct 3, 2016 at 20:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .