Loading...
Logo
Processing Forum

Repulsion Issue

in Programming Questions  •  2 years ago  
I can't seem to get repulsion to work in my code. I have bubbles that bounce around and I just want them to move away when the mouse pointer gets close to them. Any help would be much appreciated, thanks  !

int numBalls = 12;
float spring = 0.05;
float friction = -0.9;
Ball[] balls = new Ball[numBalls];

void setup() 
{
  size(600, 600);
  noStroke();
  smooth();
  for (int i = 0; i < numBalls; i++) {
    balls[i] = new Ball(random(width), random(height), random(20, 40), i, balls);
  }
}

void draw() 
{
  background(0,0,150);
  for (int i = 0; i < numBalls; i++) {
    balls[i].collide();
    balls[i].move();
    balls[i].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() {
    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;
    }
  float vx = mouseX - x;
  float vy = mouseY - y;
  stroke(255,0,0);
  float distance = dist(x,y,mouseX,mouseY);
  vx = (vx / distance) * 100;
  vy = (vy / distance) * 100;
  line(x,y,x+vx,y+vy);
  }
  
  void display() {
    fill(255, 204);
    ellipse(x, y, diameter, diameter);
  }
}

Replies(2)

Re: Repulsion Issue

2 years ago
One of the problems is that in move() you have declared 2 local variables vx and vy and these mask the two attributes of the same name in the Ball class, in other words there are two variables called vx and another two called vy. I have modified the last part of the move() method to provide repulsion to the mouse position.

Copy code
  1.   void move() {
  2.     x += vx;
  3.     y += vy;
  4.     if (x + diameter/2 > width) {
  5.       x = width - diameter/2;
  6.       vx *= friction;
  7.     }
  8.     else if (x - diameter/2 < 0) {
  9.       x = diameter/2;
  10.       vx *= friction;
  11.     }
  12.     if (y + diameter/2 > height) {
  13.       y = height - diameter/2;
  14.       vy *= friction;
  15.     }
  16.     else if (y - diameter/2 < 0) {
  17.       y = diameter/2;
  18.       vy *= friction;
  19.     }
  20.     float dvx = x - mouseX;
  21.     float dvy = y - mouseY;
  22.     stroke(255,0,0);
  23.     float distance = dist(x,y,mouseX,mouseY) + 0.0001;
  24.     vx += (dvx / distance)*0.2;
  25.     vy += (dvy / distance)*0.2;
  26.     line(x,y,x+vx,y+vy);
  27.   }

Re: Repulsion Issue

2 years ago
That's what was giving me issues, thanks so much for your help!!!