Canvas ball collision motion

problem description

online found a section of canvas ball collision code, the code is great, but there is a problem is that when two small balls are crossed at the beginning, their trajectories are the same, supposed to be random, I don"t know why they run together?

related codes

window.onload = function () {
  var canvas = document.getElementById("ball");
  var cxt = canvas.getContext("2d");
  var r = 20;
  var maxNum = 5;
  var ballArray = new Array();
  var maxX = canvas.width;
  var maxY = canvas.height;
  for (var n = 0; n < maxNum; nPP) {
    var x = {
      x: getRandomNumber(r, maxX - r),
      y: getRandomNumber(r, maxY - r),
      r: r,
      vX: getRandomNumber(0.5, 1),
      vY: getRandomNumber(0.5, 1),
      color: getRandomColor(),
    }
    ballArray.push(x);
  }

  function getRandomColor() {
    return (function (m, s, c) {
      return (c ? arguments.callee(m, s, c - 1) : "-sharp") +
        s[m.floor(m.random() * 16)]
    })(Math, "0123456789abcdef", 5)
  }

  draw();

  function draw() {
    cxt.fillStyle = "-sharp000";
    cxt.fillRect(0, 0, canvas.width, canvas.height);
    for (i in ballArray) {
      var x = i;

      ballArray[i].x += ballArray[i].vX /2;
      ballArray[i].y += ballArray[i].vY/2;

      if (ballArray[i].x >= maxX - r) {
        ballArray[i].x = maxX - r;
        ballArray[i].vX = -ballArray[i].vX;
      }
      if (ballArray[i].x <= r) {
        ballArray[i].x = r;
        ballArray[i].vX = -ballArray[i].vX;
      }
      if (ballArray[i].y >= maxY - r) {
        ballArray[i].y = maxY - r;
        ballArray[i].vY = -ballArray[i].vY;
      }
      if (ballArray[i].y <= r) {
        ballArray[i].y = r;
        ballArray[i].vY = -ballArray[i].vY;
      }

      for (var j = 0; j < maxNum; jPP)
        if (j !== x) {
          if (Math.round(Math.pow(ballArray[x].x - ballArray[j].x, 2) +
              Math.pow(ballArray[x].y - ballArray[j].y, 2)) <=
            Math.round(Math.pow(r + r, 2))) {

            var tempX = ballArray[x].vX;
            var tempY = ballArray[x].vY;
            ballArray[x].vX = ballArray[j].vX;
            ballArray[j].vX = tempX;
            ballArray[x].vY = ballArray[j].vY;
            ballArray[j].vY = tempY;
          }
        }
      cxt.beginPath();

      cxt.fillStyle = ballArray[i].color;
      cxt.arc(ballArray[i].x, ballArray[i].y, ballArray[i].r, 0, Math.PI * 2, true);
      cxt.closePath();
      cxt.fill();
    }
    setTimeout(function () {
      draw();
    }, 10);
  }

  function getRandomNumber(min, max) {
    return (min + Math.floor(Math.random() * (max - min + 1)))
  }
}

what result do you expect? What is the error message actually seen?

the trajectories are supposed to be random and independent of each other.

Apr.20,2021

can be seen from the source code

there is a loop that traverses all the balls and offsets him at the beginning of the loop according to the speed of the ball.

according to the screenshot below, the function is to make a collision check between this ball and all other balls in each cycle, and if the two balls overlap, then exchange the speed of the two balls (you can see that this program does not achieve elastic collision, but a simple exchange speed).

however, this cycle occurs for all balls, that is to say, if the two balls do not overlap, then it does not matter, in which the ball traversed first will change the speed of the two balls in the opposite direction, and then when the next ball is cycled to, the two balls will be far away, because the speed is the same, so it will be corrected to the distance before the collision, and the modification will not be triggered a second time.

however, if there is a lot of overlap between the two balls at the beginning, after the first modification, when traversing to the second ball, it is still not fast enough to leave the first ball, thus triggering the second speed exchange. Then the two of them returned to their previous speed (equivalent to the failure of the collision test)

clipboard.png

this also explains why their trajectories are the same.

the above statement is a little roundabout. Let me sort it out.
their motion displacement is handled by cyclic time, and the flow is as follows:

  1. the first ball moves according to the speed of the first ball
  2. the first ball performs collision detection and overlaps with the second ball, so the exchange speed
  3. the second ball moves according to the speed of the original first ball (its speed is swapped by the first ball)
  4. (due to the large overlap area, the end of the displacement is still overlapping), the collision detection of the second ball is found to overlap with the first ball, and the speed is exchanged again.
  5. at the end of the cycle, the first and second balls are displaced according to the speed of the first ball, but the relative distance and speed do not change
Menu