daily pastebin goal
57%
SHARE
TWEET

code

a guest Mar 24th, 2019 79 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Ball[] balls =  {
  2.   new Ball(100, 400, 80),
  3.   new Ball(700, 400, 80),
  4.   new Ball(500, 400, 80),
  5.   new Ball(300, 400, 80),
  6.   new Ball(600, 400, 80)
  7. };
  8.  
  9. void setup() {
  10.   size(800, 800);
  11. }
  12.  
  13. void draw() {
  14.   background(0);
  15.  
  16.   for (Ball b : balls) {
  17.     b.update();
  18.     b.display();
  19.     b.checkBoundaryCollision();
  20.   }
  21.  
  22.   balls[0].checkCollision(balls[1]);
  23.  
  24. }
  25.  
  26.  
  27. class Ball {
  28.   PVector position;
  29.   PVector velocity;
  30.  
  31.   float radius, m;
  32.  
  33.   Ball(float x, float y, float r_) {
  34.     position = new PVector(x, y);
  35.     velocity = PVector.random2D();
  36.     velocity.mult(10);
  37.     radius = r_;
  38.     m = radius*.1;
  39.   }
  40.  
  41.   void update() {
  42.     position.add(velocity);
  43.   }
  44.  
  45.   void checkBoundaryCollision() {
  46.     if (position.x > width-radius) {
  47.       position.x = width-radius;
  48.       velocity.x *= -1;
  49.     } else if (position.x < radius) {
  50.       position.x = radius;
  51.       velocity.x *= -1;
  52.     } else if (position.y > height-radius) {
  53.       position.y = height-radius;
  54.       velocity.y *= -1;
  55.     } else if (position.y < radius) {
  56.       position.y = radius;
  57.       velocity.y *= -1;
  58.     }
  59.   }
  60.  
  61.   void checkCollision(Ball other) {
  62.  
  63.     // Get distances between the balls components
  64.     PVector distanceVect = PVector.sub(other.position, position);
  65.  
  66.     // Calculate magnitude of the vector separating the balls
  67.     float distanceVectMag = distanceVect.mag();
  68.  
  69.     // Minimum distance before they are touching
  70.     float minDistance = radius + other.radius;
  71.  
  72.     if (distanceVectMag < minDistance) {
  73.       float distanceCorrection = (minDistance-distanceVectMag)/2.0;
  74.       PVector d = distanceVect.copy();
  75.       PVector correctionVector = d.normalize().mult(distanceCorrection);
  76.       other.position.add(correctionVector);
  77.       position.sub(correctionVector);
  78.  
  79.       // get angle of distanceVect
  80.       float theta  = distanceVect.heading();
  81.       // precalculate trig values
  82.       float sine = sin(theta);
  83.       float cosine = cos(theta);
  84.  
  85.       /* bTemp will hold rotated ball positions. You
  86.        just need to worry about bTemp[1] position*/
  87.       PVector[] bTemp = {
  88.         new PVector(), new PVector()
  89.       };
  90.  
  91.       /* this ball's position is relative to the other
  92.        so you can use the vector between them (bVect) as the
  93.        reference point in the rotation expressions.
  94.        bTemp[0].position.x and bTemp[0].position.y will initialize
  95.        automatically to 0.0, which is what you want
  96.        since b[1] will rotate around b[0] */
  97.       bTemp[1].x  = cosine * distanceVect.x + sine * distanceVect.y;
  98.       bTemp[1].y  = cosine * distanceVect.y - sine * distanceVect.x;
  99.  
  100.       // rotate Temporary velocities
  101.       PVector[] vTemp = {
  102.         new PVector(), new PVector()
  103.       };
  104.  
  105.       vTemp[0].x  = cosine * velocity.x + sine * velocity.y;
  106.       vTemp[0].y  = cosine * velocity.y - sine * velocity.x;
  107.       vTemp[1].x  = cosine * other.velocity.x + sine * other.velocity.y;
  108.       vTemp[1].y  = cosine * other.velocity.y - sine * other.velocity.x;
  109.  
  110.       /* Now that velocities are rotated, you can use 1D
  111.        conservation of momentum equations to calculate
  112.        the final velocity along the x-axis. */
  113.       PVector[] vFinal = {  
  114.         new PVector(), new PVector()
  115.       };
  116.  
  117.       // final rotated velocity for b[0]
  118.       vFinal[0].x = ((m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / (m + other.m);
  119.       vFinal[0].y = vTemp[0].y;
  120.  
  121.       // final rotated velocity for b[0]
  122.       vFinal[1].x = ((other.m - m) * vTemp[1].x + 2 * m * vTemp[0].x) / (m + other.m);
  123.       vFinal[1].y = vTemp[1].y;
  124.  
  125.       // hack to avoid clumping
  126.       bTemp[0].x += vFinal[0].x;
  127.       bTemp[1].x += vFinal[1].x;
  128.  
  129.       /* Rotate ball positions and velocities back
  130.        Reverse signs in trig expressions to rotate
  131.        in the opposite direction */
  132.       // rotate balls
  133.       PVector[] bFinal = {
  134.         new PVector(), new PVector()
  135.       };
  136.  
  137.       bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
  138.       bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
  139.       bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
  140.       bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
  141.  
  142.       // update balls to screen position
  143.       other.position.x = position.x + bFinal[1].x;
  144.       other.position.y = position.y + bFinal[1].y;
  145.  
  146.       position.add(bFinal[0]);
  147.  
  148.       // update velocities
  149.       velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
  150.       velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
  151.       other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
  152.       other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
  153.     }
  154.   }
  155.  
  156.   void display() {
  157.     noStroke();
  158.     fill(204);
  159.     ellipse(position.x, position.y, radius*2, radius*2);
  160.   }
  161. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top