Detection of collision between elements from same array only works sometimes

Hello!

I’ve created a small program where circles stored in an array move through the window. They rebound when they hit the window’s limits and they’re supposed to rebound when they collide with each other, but thesse collisions are only detected sometimes. I couldn’t find what’s causing this, because they rebound in some collisions and overlap in others.

I’m using dist() and the radius values to do the detection. There is a rectangle appearing in the corner every time this happens. The collision is being detected even when they overlap instead of moving in the opposite direction.

Thanks in advance to anyone who tries to help. Here is the code with some notes in english:

Circulo[] circulos = new Circulo[3];

void setup() {
  size (320, 320, P2D);

  for (int i=0; i < circulos.length; i++) {
    circulos[i] = new Circulo(random(19, 58), color(random(170), random(120, 160), random(162, 222)));
  }
}

void draw() {
  background(248);
  for (int i=0; i < circulos.length; i++) {
    circulos[i].criar(); //creates
    circulos[i].mover(); //moves
    circulos[i].bordas(); //detection of collision with the edges
    for (int k=0; k < circulos.length; k++) { //once again it counts every array element
      if (circulos[i] != circulos[k]) { //don't detect collision of an element with itself
        circulos[i].colisoes(circulos[k]); //detection of collision with other array elements
      }
    }
  }
}

class Circulo {

  float posX, posY, velX, velY, diametro, raio;
  color cor;

  Circulo(float diam, color corTemp) {
    diametro=diam;
    raio=diam/2;
    cor=corTemp;
    posX=random(raio, width-raio);
    posY=random(raio, height-raio);
    velX = random(-3, 3);
    velY = random(-3, 3);
  }

  void criar() {
    noStroke();

    ellipse(posX, posY, diametro, diametro);
    fill(cor);
  }

  void mover() {

    posX=posX+velX;
    posY=posY+velY;
  }

  //detection of collision with the edges
  void bordas() {
    if (posX > width-raio || posX < raio) velX = -velX;
    if (posY > height-raio || posY < raio) velY=-velY;
  }

  //detection of collision with other array elements
  void colisoes(Circulo outro) {
    float d = dist(posX, posY, outro.posX, outro.posY);
    if (d < raio + outro.raio) {
      velX=-velX;
      velY=-velY;
      outro.velX=-outro.velX;
      outro.velY=-outro.velY;
      rect(0, 0, 40, 40);
    }
  }
}
1 Like

atm you compare every pair of circles double

instead use i+1 as start value

for (int k=i+1; k < circulos.length; k++) { //

This:

is not necessary then

2 Likes

Studio.ProcessingTogether.com/sp/pad/export/ro.9s0026dE7B8v-
Studio.ProcessingTogether.com/sp/pad/export/ro.989GaZC5t7EkE
2 Likes

Oh wow I think it is working now. So, as I suspected, what was happening was that the program was trying to do too many things at the same time and it wasn’t fast enough?

I think your solution didn’t come to mind because I was thinking that I had to have the circle 0 counted in the second loop, but just now I understood that if I’m comparing int=0 with k=1, comparing int=1 with k=0 would be the same, am I right?

EDIT: oh and with your solution 1 won’t be compared with 0 and 1, 2 with 0, 1 and 2, etc. cool!

Thank you so much!

1 Like

Looks like a useful website, thanks!

1 Like

No, that’s not the reason. It would just slow things down.

Reason was probably that each circle was compared to each other circle twice. So in case of a collision the changes were made in the if clause but then made again, reversing the values to their old state. Bad.

Oh, right! That makes sense. When that happens with the initial code, they move back and forth really fast while they’re superimposed.

1 Like