3
\$\begingroup\$

I'm trying to implement basic inelastic ball collision.

The example on the link above is for one dimension. It explains that it's the same for 2D but where the velocities are the components in the direction of the normal in the point of collision. I have tried calculating these components by projecting on the normal vector, and then calculating the new velocities. But then I got stuck. How do I get the new velocity vectors? My attempt below does not produce any good result. Can you help me out? (The two balls are intersecting in one common point when I run the code below)

UPDATE: I have edited the code now so that the two last lines is more correct I think. The thing is I have to combine the new velocity vector component with the old velocity vector component that was first subtracted in the projection operation, to get the complete new velocity vector. Now the animation looks a lot better. I still get occasional ball merging and popping but that could be some other part of my code thats wrong.

var m = this.Mass + other.Mass;
// normal in the point of collision
var n = (this.Position - other.Position).Normalized;
// velocity component perpendicular to the tangent in the point of collision for ball A
var ua = (float)(this.Velocity.Magnitude * Math.Cos(this.Velocity.Angle(n)));
// velocity component perpendicular to the tangent in the point of collision for ball B
var ub = (float)(other.Velocity.Magnitude * Math.Cos(other.Velocity.Angle(n)));
// the new velocity for ball A
var va = (0.9f * other.Mass * (ub - ua) + this.Mass * ua + other.Mass * ub) / m;
// the new velocity for ball B
var vb = (0.9f * this.Mass * (ua - ub) + this.Mass * ua + other.Mass * ub) / m;

// the new velocity vector for ball A
this.Velocity -= n * (ua - va);

// the new velocity vector for ball B
other.Velocity -= n * (ub - vb);
\$\endgroup\$
1
\$\begingroup\$

From a physical point of view, you need to apply not only the law conservation of energy (with actually a little dissipation represented by the restituctuon factor), but also the conservation of momentum.

Energy this case is the kinetic one, mv^2/2 for each body. Momentum is mv/2 for each body.

See this physics webpage for more detail:

https://isaacphysics.org/concepts/cp_collisions

\$\endgroup\$
0
\$\begingroup\$

Here's a function for the change in momentum and it works in 1D, 2D, 3D, you name it!

// Applies momentum with the given object
public void ApplyImpulse(PhysObj objHit, Vector2 n)
{
    // Calculate change in momentum
    Vector2 pHat = (((Vector2.Dot((v - objHit.v), n)) / (1f / M + 1f / objHit.M)) * (1f + E)) * n;

    // Calculate final velocities
    v = v - (pHat / M);
    objHit.v = objHit.v + (pHat / objHit.M);
}

Here it is in mathematical notation:

\$p=(1+e)\frac{(v_1-v_2)\cdot n}{\frac{1}{m_1}+\frac{1}{m_2}}*n \$

Also note that * is the component product not the dot product. Produces a vector like so:

a * b = (a.x * b.x, a.y * b.y)

Oh and n is the normal at the point of contact. That is:

enter image description here

And e is the elasticity. In the range of [0, 1]

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.