From d3124e80bb42ef0351550076d9635feafb89bb56 Mon Sep 17 00:00:00 2001 From: Jay H Date: Thu, 24 Oct 2013 15:12:40 -0500 Subject: [PATCH] circlecollision expanded to work for n balls rather than just two --- learning/topic/circlecollision/index.html | 464 ++++------------------ 1 file changed, 86 insertions(+), 378 deletions(-) diff --git a/learning/topic/circlecollision/index.html b/learning/topic/circlecollision/index.html index e3a3d30..56aa457 100644 --- a/learning/topic/circlecollision/index.html +++ b/learning/topic/circlecollision/index.html @@ -23,314 +23,168 @@

CircleCollision

@@ -342,316 +196,170 @@

CircleCollision

// All Examples Written by Casey Reas and Ben Fry
 
 // unless otherwise stated.
+int width = 200;
+int height = 200;
+int nBalls = 5;
 
-Ball[] balls =  { 
-
-  new Ball(100, 400, 10), 
-
-  new Ball(700, 400, 40) 
-
-  };
-
-
-
-Vect2D[] vels = { 
-
-  new Vect2D(2.15, -1.35), 
-
-  new Vect2D(-1.65, .42) 
-
-  };
-
-
+Ball[] balls = new Ball[nBalls];
+Vect2D[] vels = new Vect2D[nBalls];
 
 void setup(){
-
-  size(200, 200);
-
+  size(width, height);
   smooth();
-
   noStroke();
-
+  initBalls();
 }
 
-
+void initBalls(){
+  for (int i = 0; i < nBalls; i++) {
+    balls[i] = new Ball(30*i, 30*i, random(5, 15));
+    vels[i] = new Vect2D(1, 1);
+  }
+}
 
 void draw(){
-
   background(51);
-
   fill(204);
-
-  for (int i=0; i< 2; i++){
-
+  for (int i = 0; i < nBalls; i++){
     balls[i].x += vels[i].vx;
-
     balls[i].y += vels[i].vy;
-
     ellipse(balls[i].x, balls[i].y, balls[i].r*2, balls[i].r*2);
-
     checkBoundaryCollision(balls[i], vels[i]);
-
+    // check all ball pairs for collisions
+    for (int j = i+1; j < nBalls; j++){
+      checkObjectCollision(balls[i], vels[i], balls[j], vels[j]);
+    }
   }
-
-  checkObjectCollision(balls, vels);
-
 }
 
-
-
-void checkObjectCollision(Ball[] b, Vect2D[] v){
-
-
+void checkObjectCollision(Ball b1, Vect2D v1, Ball b2, Vect2D v2){
 
   // get distances between the balls components
-
   Vect2D bVect = new Vect2D();
-
-  bVect.vx = b[1].x - b[0].x;
-
-  bVect.vy = b[1].y - b[0].y;
-
-
+  bVect.vx = b2.x - b1.x;
+  bVect.vy = b2.y - b1.y;
 
   // calculate magnitude of the vector separating the balls
-
   float bVectMag = sqrt(bVect.vx * bVect.vx + bVect.vy * bVect.vy);
-
-  if (bVectMag < b[0].r + b[1].r){
-
+  if (bVectMag < b1.r + b2.r){
     // get angle of bVect
-
     float theta  = atan2(bVect.vy, bVect.vx);
-
     // precalculate trig values
-
     float sine = sin(theta);
-
     float cosine = cos(theta);
 
-
-
     /* bTemp will hold rotated ball positions. You 
-
      just need to worry about bTemp[1] position*/
-
     Ball[] bTemp = {  
-
       new Ball(), new Ball()      };
-
-    /* b[1]'s position is relative to b[0]'s
-
+    /* b2's position is relative to b1's
      so you can use the vector between them (bVect) as the 
-
      reference point in the rotation expressions.
-
      bTemp[0].x and bTemp[0].y will initialize
-
      automatically to 0.0, which is what you want
-
-     since b[1] will rotate around b[0] */
-
+     since b2 will rotate around b1 */
     bTemp[1].x  = cosine * bVect.vx + sine * bVect.vy;
-
     bTemp[1].y  = cosine * bVect.vy - sine * bVect.vx;
 
-
-
     // rotate Temporary velocities
-
     Vect2D[] vTemp = { 
-
       new Vect2D(), new Vect2D()     };
-
-    vTemp[0].vx  = cosine * v[0].vx + sine * v[0].vy;
-
-    vTemp[0].vy  = cosine * v[0].vy - sine * v[0].vx;
-
-    vTemp[1].vx  = cosine * v[1].vx + sine * v[1].vy;
-
-    vTemp[1].vy  = cosine * v[1].vy - sine * v[1].vx;
-
-
+    vTemp[0].vx  = cosine * v1.vx + sine * v1.vy;
+    vTemp[0].vy  = cosine * v1.vy - sine * v1.vx;
+    vTemp[1].vx  = cosine * v2.vx + sine * v2.vy;
+    vTemp[1].vy  = cosine * v2.vy - sine * v2.vx;
 
     /* Now that velocities are rotated, you can use 1D
-
      conservation of momentum equations to calculate 
-
      the final velocity along the x-axis. */
-
     Vect2D[] vFinal = {  
-
       new Vect2D(), new Vect2D()      };
-
-    // final rotated velocity for b[0]
-
-    vFinal[0].vx = ((b[0].m - b[1].m) * vTemp[0].vx + 2 * b[1].m * 
-
-      vTemp[1].vx) / (b[0].m + b[1].m);
-
+    // final rotated velocity for b1
+    vFinal[0].vx = ((b1.m - b2.m) * vTemp[0].vx + 2 * b2.m * 
+      vTemp[1].vx) / (b1.m + b2.m);
     vFinal[0].vy = vTemp[0].vy;
-
-    // final rotated velocity for b[0]
-
-    vFinal[1].vx = ((b[1].m - b[0].m) * vTemp[1].vx + 2 * b[0].m * 
-
-      vTemp[0].vx) / (b[0].m + b[1].m);
-
+    // final rotated velocity for b1
+    vFinal[1].vx = ((b2.m - b1.m) * vTemp[1].vx + 2 * b1.m * 
+      vTemp[0].vx) / (b1.m + b2.m);
     vFinal[1].vy = vTemp[1].vy;
 
-
-
     // hack to avoid clumping
-
     bTemp[0].x += vFinal[0].vx;
-
     bTemp[1].x += vFinal[1].vx;
 
-
-
     /* Rotate ball positions and velocities back
-
      Reverse signs in trig expressions to rotate 
-
      in the opposite direction */
-
     // rotate balls
-
     Ball[] bFinal = { 
-
       new Ball(), new Ball()     };
-
     bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
-
     bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
-
     bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
-
     bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
 
-
-
     // update balls to screen position
-
-    b[1].x = b[0].x + bFinal[1].x;
-
-    b[1].y = b[0].y + bFinal[1].y;
-
-    b[0].x = b[0].x + bFinal[0].x;
-
-    b[0].y = b[0].y + bFinal[0].y;
-
-
+    b2.x = b1.x + bFinal[1].x;
+    b2.y = b1.y + bFinal[1].y;
+    b1.x = b1.x + bFinal[0].x;
+    b1.y = b1.y + bFinal[0].y;
 
     // update velocities
-
-    v[0].vx = cosine * vFinal[0].vx - sine * vFinal[0].vy;
-
-    v[0].vy = cosine * vFinal[0].vy + sine * vFinal[0].vx;
-
-    v[1].vx = cosine * vFinal[1].vx - sine * vFinal[1].vy;
-
-    v[1].vy = cosine * vFinal[1].vy + sine * vFinal[1].vx;
-
+    v1.vx = cosine * vFinal[0].vx - sine * vFinal[0].vy;
+    v1.vy = cosine * vFinal[0].vy + sine * vFinal[0].vx;
+    v2.vx = cosine * vFinal[1].vx - sine * vFinal[1].vy;
+    v2.vy = cosine * vFinal[1].vy + sine * vFinal[1].vx;
   }
-
 }
 
-
-
 class Ball{
-
   float x, y, r, m;
 
-
-
   // default constructor
-
   Ball() {
-
   }
 
-
-
   Ball(float x, float y, float r) {
-
     this.x = x;
-
     this.y = y;
-
     this.r = r;
-
     m = r*.1;
-
   }
-
 }
 
-
-
 class Vect2D{
-
   float vx, vy;
 
-
-
   // default constructor
-
   Vect2D() {
-
   }
 
-
-
   Vect2D(float vx, float vy) {
-
     this.vx = vx;
-
     this.vy = vy;
-
   }
-
 }
 
-
-
 // checkBoundaryCollision() function:
-
 void checkBoundaryCollision(Ball ball, Vect2D vel){
-
   if (ball.x > width-ball.r){
-
     ball.x = width-ball.r;
-
     vel.vx *= -1;
-
   } 
-
   else if (ball.x < ball.r){
-
     ball.x = ball.r;
-
     vel.vx *= -1;
-
   } 
-
   else if (ball.y > height-ball.r){
-
     ball.y = height-ball.r;
-
     vel.vy *= -1;
-
   } 
-
   else if (ball.y < ball.r){
-
     ball.y = ball.r;
-
     vel.vy *= -1;
-
   }
-
-}
+} +