Problem with overlapping balls

Hello all,

I’m kinda new to processing and I’m doing some exercises to get the hang of it. Right now I’m writing a little script which draws balls to the screen. If the balls overlap, I want the color of the current ball to change to red. Some of the overlapping balls do change to red but others don’t. I think it’s because not all balls are compared to each other. But I don’t know how to fix this.

This is my overlapping_balls code:

Ball balls[] = new Ball[20];

void setup() {
    size(400,200);
    for(int i = 0; i < balls.length; i++) {
        balls[i] = new Ball();
  }
}

void draw() {
    background(0);
    for(int i = 0; i < (balls.length); i++) {
        for(int j = 0; j < i; j++) {
        if (balls[i].overlaps(balls[j])) {
        balls[i].changeColor();
      }
    }
    balls[i].display();
  }
}


**This is my ball class:**

class Ball {
    float x, y;
    float r;
    int[] colored = {255, 255, 255};
  
  Ball() {
      x = random(width);
      y = random(height);
      r = random(2, 10);
  }
  
  boolean overlaps(Ball other) {
      float distance = dist(x,y,other.x,other.y);
      if (distance < (r + other.r)) {
          return true;
      } else {
          return false;
    }
  }
  
  void changeColor() {
      colored[0] = 255;
      colored[1] = 0;
      colored[2] = 0;
  }
    
  void display() {
      noStroke();
      fill(colored[0], colored[1], colored[2],100);
      ellipse(x,y,r*4,r*4);
    }
  }

Does anyone have an idea of how I can construct the for loop in the overlapping_balls.pde file?
Thanks in advance!

Bente

1 Like

understand you want to do the inner loop smarter,
as a unlimited inner loop would do about double search as needed, right?
but i think the logic was little bit different ( untested idea: )

for(int i = 0; i < balls.length-1; i++) {
for(int j = i+1; j < balls.length; j++) {

in words:

  • the last one must have been checked already

  • you not need to check on yourself and

  • not the one prior, as that have been checked already

1 Like

Hello kll, thanks for your reply!

I just tried it and unfortunately it didn’t work. What you described in words is exactly what I’d expected your loop to do but I can’t get my head around why it’s not working.

I just thought of the idea that ball[0] needs to check if it overlaps ball[1], ball[2] … ball[19]. Ball[1] needs to check if it overlaps ball[2], ball[3] … ball[19] and so on. I thought your loop would do so. I’ve been thinking it over and over all morning… It seems kinda ‘‘easy’’. But anyways thanks very much for you help!

well, it works here,
after i see a other problem in your posted code:

for posting code pls use the

</>

formatter, not the “”
because it some times damage code like yours:

ellipse(x,y,r 4,r 4);

ellipse(x,y,r * 4,r * 4);

and that is very wrong:

ellipse(x,y,r * 2 ,r * 2 );

is correct and fits to your

distance < (r + other.r)
1 Like

Oh I’m sorry.
Thanks very much, it works indeed!!

good, so now you can post the working version here,

  • after format in IDE with [ctrl][t]
  • using the correct way </> to post code.

so others who read this can start from your working version.

Alright, so here is the working version. (Properly formatted).
First,
overlapping_balls.pde

Ball balls[] = new Ball[1000];

void setup() {
  size(1000,800);
  for(int i = 0; i < balls.length; i++) {
    balls[i] = new Ball();
  }
}

void draw() {
  background(0);
  for(int i = 0; i < (balls.length - 1); i++) {
    for(int j = i + 1; j < balls.length; j++) {
      if (balls[i].overlaps(balls[j])) {
        balls[i].changeColor();
      }
    }
    balls[i].display();
  }
}

And the ball class:

class Ball {
  float x, y;
  float r;
  int[] colored = {255, 255, 255};
  
  Ball() {
    x = random(width);
    y = random(height);
    r = random(2, 10);
  }
  
  boolean overlaps(Ball other) {
    float distance = dist(x,y,other.x,other.y);
    if (distance < (r + other.r)) {
      return true;
    } else {
      return false;
    }
  }
  
  void changeColor() {
    colored[0] = 255;
    colored[1] = 0;
    colored[2] = 0;
  }
    
  void display() {
    noStroke();
    fill(colored[0], colored[1], colored[2],100);
    ellipse(x,y,r*2,r*2);
  }
}
2 Likes