title: Ball to Ball Collision - Detection and Handling
body: <p>With the help of the Stack Overflow community I've written a pretty basic-but fun physics simulator.</p>
  <p><img src="https://i.stack.imgur.com/EeqSP.png" alt="alt text" /></p>
  <p>You click and drag the mouse to launch a ball.  It will bounce around and eventually stop on the &quot;floor&quot;.</p>
  <p>My next big feature I want to add in is ball to ball collision.  The ball's movement is broken up into a x and y speed vector.  I have gravity (small reduction of the y vector each step), I have friction (small reduction of both vectors each collision with a wall). The balls honestly move around in a surprisingly realistic way.</p>
  <p>I guess my question has two parts:</p>
  <ol>
  <li><strong>What is the best method to detect ball to ball collision?</strong><br />
  Do I just have an O(n^2) loop that iterates over each ball and checks every other ball to see if it's radius overlaps?</li>
  <li><strong>What equations do I use to handle the ball to ball collisions? Physics 101</strong><br />
  How does it effect the two balls speed x/y vectors?  What is the resulting direction the two balls head off in?  How do I apply this to each ball?</li>
  </ol>
  <p><img src="https://upload.wikimedia.org/wikipedia/commons/2/2c/Elastischer_sto%C3%9F_2D.gif" alt="alt text" /></p>
  <p>Handling the collision detection of the &quot;walls&quot; and the resulting vector changes were easy but I see more complications with ball-ball collisions.  With walls I simply had to take the negative of the appropriate x or y vector and off it would go in the correct direction.  With balls I don't think it is that way.</p>
  <p>Some quick clarifications: for simplicity I'm ok with a perfectly elastic collision for now, also all my balls have the same mass right now, but I might change that in the future.</p>
  <hr />
  <p>Edit: Resources I have found useful</p>
  <p>2d Ball physics with vectors: <a href="https://www.vobarian.com/collisions/2dcollisions2.pdf" rel="nofollow noreferrer">2-Dimensional Collisions Without Trigonometry.pdf</a><br />
  2d Ball collision detection example: <a href="https://web.archive.org/web/20210125052930/http://geekswithblogs.net/robp/archive/2008/05/15/adding-collision-detection.aspx" rel="nofollow noreferrer">Adding Collision Detection</a></p>
  <hr />
  <h2>Success!</h2>
  <p>I have the ball collision detection and response working great!</p>
  <p>Relevant code:</p>
  <p>Collision Detection:</p>
  <pre><code>for (int i = 0; i &lt; ballCount; i++)  
  {  
      for (int j = i + 1; j &lt; ballCount; j++)  
      {  
          if (balls[i].colliding(balls[j]))  
          {
              balls[i].resolveCollision(balls[j]);
          }
      }
  }
  </code></pre>
  <p>This will check for collisions between every ball but skip redundant checks (if you have to check if ball 1 collides with ball 2 then you don't need to check if ball 2 collides with ball 1.  Also, it skips checking for collisions with itself).</p>
  <p>Then, in my ball class I have my colliding() and resolveCollision() methods:</p>
  <pre><code>public boolean colliding(Ball ball)
  {
      float xd = position.getX() - ball.position.getX();
      float yd = position.getY() - ball.position.getY();
  
      float sumRadius = getRadius() + ball.getRadius();
      float sqrRadius = sumRadius * sumRadius;
  
      float distSqr = (xd * xd) + (yd * yd);
  
      if (distSqr &lt;= sqrRadius)
      {
          return true;
      }
  
      return false;
  }
  
  public void resolveCollision(Ball ball)
  {
      // get the mtd
      Vector2d delta = (position.subtract(ball.position));
      float d = delta.getLength();
      // minimum translation distance to push balls apart after intersecting
      Vector2d mtd = delta.multiply(((getRadius() + ball.getRadius())-d)/d); 
  
  
      // resolve intersection --
      // inverse mass quantities
      float im1 = 1 / getMass(); 
      float im2 = 1 / ball.getMass();
  
      // push-pull them apart based off their mass
      position = position.add(mtd.multiply(im1 / (im1 + im2)));
      ball.position = ball.position.subtract(mtd.multiply(im2 / (im1 + im2)));
  
      // impact speed
      Vector2d v = (this.velocity.subtract(ball.velocity));
      float vn = v.dot(mtd.normalize());
  
      // sphere intersecting but moving away from each other already
      if (vn &gt; 0.0f) return;
  
      // collision impulse
      float i = (-(1.0f + Constants.restitution) * vn) / (im1 + im2);
      Vector2d impulse = mtd.normalize().multiply(i);
  
      // change in momentum
      this.velocity = this.velocity.add(impulse.multiply(im1));
      ball.velocity = ball.velocity.subtract(impulse.multiply(im2));
  
  }
  </code></pre>
  <p>Source Code: <a href="https://www.dropbox.com/s/1j4aiu2aahjc19p/ballbounce.zip?dl=0" rel="nofollow noreferrer">Complete source for ball to ball collider.</a></p>
  <p>If anyone has some suggestions for how to improve this basic physics simulator let me know!  One thing I have yet to add is angular momentum so the balls will roll more realistically.  Any other suggestions?  Leave a comment!</p>