Why are my balls disappearing?

JavascriptCanvasGeometryPhysicsCollision

Javascript Problem Overview


Pardon the funny title. I've created a little graphic demo of 200 balls bouncing and colliding, both against the walls and each other. You can see what I have currently here: http://www.exeneva.com/html5/multipleBallsBouncingAndColliding/

The problem is that whenever they collide with each other, they disappear. I'm not sure why. Can someone take a look and help me out?

UPDATE: Apparently the balls array has balls with coordinates of NaN. Below is the code where I push balls to the array. I'm not entirely sure how the coordinates are getting NaN.

// Variables
var numBalls = 200;  // number of balls
var maxSize = 15;
var minSize = 5;
var maxSpeed = maxSize + 5;
var balls = new Array();
var tempBall;
var tempX;
var tempY;
var tempSpeed;
var tempAngle;
var tempRadius;
var tempRadians;
var tempVelocityX;
var tempVelocityY;

// Find spots to place each ball so none start on top of each other
for (var i = 0; i < numBalls; i += 1) {
  tempRadius = 5;
  var placeOK = false;
  while (!placeOK) {
    tempX = tempRadius * 3 + (Math.floor(Math.random() * theCanvas.width) - tempRadius * 3);
    tempY = tempRadius * 3 + (Math.floor(Math.random() * theCanvas.height) - tempRadius * 3);
    tempSpeed = 4;
    tempAngle = Math.floor(Math.random() * 360);
    tempRadians = tempAngle * Math.PI/180;
    tempVelocityX = Math.cos(tempRadians) * tempSpeed;
    tempVelocityY = Math.sin(tempRadians) * tempSpeed;
    
    tempBall = {
      x: tempX, 
      y: tempY, 
      nextX: tempX, 
      nextY: tempY, 
      radius: tempRadius, 
      speed: tempSpeed,
      angle: tempAngle,
      velocityX: tempVelocityX,
      velocityY: tempVelocityY,
      mass: tempRadius
    };
    placeOK = canStartHere(tempBall);
  }
  balls.push(tempBall);
}

Javascript Solutions


Solution 1 - Javascript

Your error comes from this line initially:

var direction1 = Math.atan2(ball1.velocitY, ball1.velocityX);

You have ball1.velocitY (which is undefined) instead of ball1.velocityY. So Math.atan2 is giving you NaN, and that NaN value is propagating through all your calculations.

This is not the source of your error, but there is something else that you might want to change on these four lines:

ball1.nextX = (ball1.nextX += ball1.velocityX);
ball1.nextY = (ball1.nextY += ball1.velocityY);
ball2.nextX = (ball2.nextX += ball2.velocityX);
ball2.nextY = (ball2.nextY += ball2.velocityY);

You don't need the extra assignments, and can just use the += operator alone:

ball1.nextX += ball1.velocityX;
ball1.nextY += ball1.velocityY;
ball2.nextX += ball2.velocityX;
ball2.nextY += ball2.velocityY;

Solution 2 - Javascript

There's an error in the collideBalls function:

var direction1 = Math.atan2(ball1.velocitY, ball1.velocityX);

It should be:

var direction1 = Math.atan2(ball1.velocityY, ball1.velocityX);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYang PulseView Question on Stackoverflow
Solution 1 - JavascriptPaulView Answer on Stackoverflow
Solution 2 - JavascriptalfView Answer on Stackoverflow