Using a PVector

Looking to adapt the code below

1 Like

and where you got this code from?

https://processing.org/examples/bouncybubbles.html

I think

1 Like

Yeh it’s from the processing examples

you mean, you can copy and use it,
without credit from where you take it?

even you see that processing example site say:

Bouncy Bubbles based on code from Keith Peters.

and you not need to mention where you got it from?



/*
int numBalls = 10;
float spring = 0.05;
float gravity = 0.06;
float friction = -0.9;
Ball[] balls = new Ball[numBalls];

void setup() {
  size(640, 360);
  for (int i = 0; i < numBalls; i++) {
    balls[i] = new Ball(random(width), random(height), random(30, 32), i, balls);
  }
  stroke(0, 0, 255);
  fill(135, 206, 250);
}

void draw() {
  background(255);
  for (Ball ball : balls) {
    ball.collide();
    ball.move();
    ball.display();  
  }
}

class Ball {
  
  float x, y;
  float diameter;
  float vx = 0;
  float vy = 0;
  int id;
  Ball[] others;
 
  Ball(float xin, float yin, float din, int idin, Ball[] oin) {
    x = xin;
    y = yin;
    diameter = din;
    id = idin;
    others = oin;
  } 
  
  void collide() {
    for (int i = id + 1; i < numBalls; i++) {
      float dx = others[i].x - x;
      float dy = others[i].y - y;
      float distance = sqrt(dx*dx + dy*dy);
      float minDist = others[i].diameter/2 + diameter/2;
      if (distance < minDist) { 
        float angle = atan2(dy, dx);
        float targetX = x + cos(angle) * minDist;
        float targetY = y + sin(angle) * minDist;
        float ax = (targetX - others[i].x) * spring;
        float ay = (targetY - others[i].y) * spring;
        vx -= ax;
        vy -= ay;
        others[i].vx += ax;
        others[i].vy += ay;
      }
    }   
  }
  
  void move() {
    vy += gravity;
    x += vx;
    y += vy;
    if (x + diameter/2 > width) {
      x = width - diameter/2;
      vx *= friction; 
    }
    else if (x - diameter/2 < 0) {
      x = diameter/2;
      vx *= friction;
    }
    if (y + diameter/2 > height) {
      y = height - diameter/2;
      vy *= friction; 
    } 
    else if (y - diameter/2 < 0) {
      y = diameter/2;
      vy *= friction;
    }
  }
  
  void display() {
    ellipse(x, y, diameter, diameter);
  }
}
*/

// Bouncy Bubbles based on code from Keith Peters. 
// https://processing.org/examples/bouncybubbles.html
// try a PVector version

int numBalls = 10;
float spring = 0.05;
float gravity = 0.06;
float friction = -0.9;
Ball[] balls = new Ball[numBalls];
PVector ballpos = new PVector(0, 0);

void setup() {
  size(640, 360);
  for (int i = 0; i < numBalls; i++) {
    float bx = random(width);
    float by = random(height);
    ballpos.set( bx, by );
    //println("i "+i+" x "+(int)bx+" y "+(int)by);
    balls[i] = new Ball(ballpos, random(30, 32), i, balls);
  }
  stroke(0, 0, 255);
  fill(135, 206, 250);
}

void draw() {
  background(255);
  for (Ball ball : balls) {
    ball.collide();
    ball.move();
    ball.display();
  }
}

class Ball {
  //float x, y;
  PVector pos = new PVector(0 , 0);
  float diam;
//  float vx = 0;
//  float vy = 0;
  PVector v = new PVector(0 , 0);
  int id;
  Ball[] others;

  Ball(PVector posin, float diamin, int idin, Ball[] othersin) {
    pos = posin.copy();                          // important, not assign, use copy
    diam = diamin;
    id = idin;
    others = othersin;
  } 

  void collide() {
    for (int i = id + 1; i < numBalls; i++) {
      float dx = others[i].pos.x - pos.x;
      float dy = others[i].pos.y - pos.y;
      float distance = sqrt(sq(dx) + sq(dy));
      float minDist = others[i].diam/2 + diam/2;
      if (distance <= minDist) { 
        float angle = atan2(dy, dx);
        float targetX = pos.x + cos(angle) * minDist;
        float targetY = pos.y + sin(angle) * minDist;
        float ax = (targetX - others[i].pos.x) * spring;
        float ay = (targetY - others[i].pos.y) * spring;
        v.x -= ax;
        v.y -= ay;
        others[i].v.x += ax;
        others[i].v.y += ay;
      }
    }
  }

  void move() {
    v.y += gravity;
    pos.x += v.x;
    pos.y += v.y;
    if (pos.x + diam/2 > width) {
      pos.x = width - diam/2;
      v.x *= friction;
    } else if (pos.x - diam/2 < 0) {
      pos.x = diam/2;
      v.x *= friction;
    }
    if (pos.y + diam/2 > height) {
      pos.y = height - diam/2;
      v.y *= friction;
    } else if (pos.y - diam/2 < 0) {
      pos.y = diam/2;
      v.y *= friction;
    }
  }

  void display() {
    ellipse(pos.x, pos.y, diam, diam);
  }
}


Thank you so much for the help :slight_smile:

All codes I use and adapt will be referenced accordingly - I’m only playing about with various codes at the moment, trying to learn how processing works.

good, and learn coding means also learn documenting it
and that only works if you do it right at the beginning,
as 5 min later you forget from what webpage you take something…

and not forget the legal issues

I’ll be sure to do so!

Is there anything in the adapted code you made that would only work in Processing 3, as I am currently using Processing 2.2.1, and it doesn’t seem to want to run the code (gives me a grey display)?

I appreciate your time and the help, thank you!

i test under:

win 7 / 64 bit /
processing 3.5.3

besides PVector no other “tricks” used
ok,
your error description is very poor, the processing 2.2.1 not show a white screen,
it give a error about a unknown command

PVector.copy();

change to

    pos = new PVector(posin.x,posin.y); //posin.copy();                          // important, not assign, use copy

and it runs here.

1 Like

Method PVector::copy() is merely a silly alias of the original method PVector::get(): :clown_face:
ProcessingJS.org/reference/PVector_get_/

1 Like

yes, there might be many ways, but NOT

pos = posin;

try what happens!

I have incorporated this into my updated code, however there seems to still be a slight issue. My code runs, however the balls do not seem to be moving. Any help with fixing my issue would be amazing, thank you!

I have attached my code below (apologies for the length).

References of code used and adapted:
https://processing.org/examples/bouncybubbles.html - by Keith Peters
https://processing.org/examples/reflection1.html - by Ira Greenberg

you say it runs?
that code does not run, and after get it running still pictures missing,
so you are on your own.

By runs I mean it produces a display, showing a dam and a background - the issue is that the balls do not appear or move

When I cut and paste your code above into a new PDE window, it says:

The variable “spring” does not exist

…?

1 Like

Hmm sorry about that - there should be ‘float spring = 0.05;’ under the ‘class Balls {’ section

I should also note I am using Version 2.2.1

Go ahead and edit your code post above – fix it, and add the comment. Please don’t post code as “running” that you haven’t press the “Run” button and confirmed that it actually runs!

The fact that you are using 2.2.1 is very important for people trying to help you – any particular reason why you are using that and not 3.x?

I think you have just found the problem! Thanks!

My computer did run it, but never gave me the ’ ‘spring’ does not exist’ comment

Perhaps your sketch had multiple tabs, and spring was defined in another tab. It isn’t possible for the code you posted to run alone, without that variable being defined – it could never compile.