0
votes

I'm trying to make a simple ball physics simulator where balls collide with eachother and the walls. The former is the one I'm struggling with. I want the balls to collide with eachother but not bounce off, I just want to make it so that they don't go inside of eachother.

More relevant bits of the code:

class Particle {
     constructor(x, y) {
          this.pos = createVector(x, y);
          this.vel = p5.Vector.random2D();
          this.vel.setMag(4)
          this.r = 20
     }
     collide() {
          for (let p of particles) {
               if (p5.Vector.dist(this.pos, p.pos) < this.r + p.r && this != p) {
                      //Collide
               }
          }
     }
}

JSFIDDLE: https://jsfiddle.net/7oh3p4ku/1/

1
What do you want them to do instead of bounce off? Really the only two options are bouncing (either elastically or inelastically) or sticking. If you want them to stick then do you care about the rotation which would be induced due to conservation of angular momentum, or do you just want the balls to stick and move together but not rotate about the new center of mass?William Miller

1 Answers

2
votes

Like William Miller says, What do you want them to do instead of bounce off? You could simply keep them apart by the radius + the other radius.

https://jsfiddle.net/EthanHermsey/n906fdmh/21/

    collide() {
          for (let p of particles) {
               if (this != p && p5.Vector.dist(this.pos, p.pos) < this.r + p.r) {

                  //a vector pointing from the other point to this point
                  let directionVector = p5.Vector.sub( this.pos, p.pos ); 

                   //set the magnitude of the vector to the length of both radiusses
                  directionVector.setMag( this.r + p.r );

                  //now set this.pos at a fixed distance from p.pos. In the same direction as it was before.
                  this.pos = p.pos.copy();
                  this.pos.add( directionVector );

               }
          }
     }


Also I moved the 'this != p' to the front, that's a little bit faster because the distance calculation doesn't have to be done first.

That distance function is pretty slow anyway because of the square root calculation, you could try and use the magSq() function, like this;

    collide() {
      for (let p of particles) {
            if ( p == this ) continue; //go to the next particle

          //a vector pointing from the other point to this point
          let directionVector = p5.Vector.sub( this.pos, p.pos ); 

          //pow( this.r + p.r, 2 ) is the same as ( this.r + p.r ) * ( this.r + p.r )

          if ( this != p && directionVector.magSq() < pow( this.r + p.r, 2 ) ) {

               //set the magnitude of the vector to the length of both radiusses
              directionVector.setMag( this.r + p.r );

              //now set this.pos at a fixed distance from p.pos. In the same direction as it was before.
              this.pos = p.pos.copy();
              this.pos.add( directionVector );

           }
      }
 }