Need help to remove shapes touchings (sort of collision detection)

Hello! I'm quite new to programming and I have a problem with sketch. I've made a class of pyramids and trying to make it not to touch each other, but it doesn't work well... The mistake is 99% in void collision_det() method. I would be so grateful if anyone helps me.

import processing.opengl.*;
   Pyramid[] piramide;
   float[] n= new float [150];
   float[] m= new float [150];

void setup() {
  piramide = new Pyramid[150];
  size(900, 600, OPENGL);
for (int i=0; i<piramide.length;i++) {
  n[i]=random(width);
  m[i]=random(height);
    piramide[i] = new Pyramid(n[i], m[i], random(20), random(5,15),(random(5,30)*0.001));

}
}

void draw() {
  smooth();
  lights();
  background(30,25,30);
for (int i=0; i<piramide.length;i++) {
    Pyramid thisPyr = piramide[i];
    thisPyr.collision_det();
    thisPyr.rotacion();
  }
}


class Pyramid {
  float x, y, z, t, s;
  float theta=0.0;
  float alph;

  Pyramid(float tempX, float tempY, float tempZ, float tempT, float tempS) {
    x= tempX;
    y= tempY;
    z= tempZ;
    t= tempT;
    s= tempS;
  }

  void drawPiramide() {
    pushMatrix();

    translate(x, y);

    beginShape(TRIANGLES);
    noStroke();


   fill(220,220,220);
   vertex(0, t*2, 0); 
   vertex(0, 0, -t);
   vertex(-t, 0, 0);

   fill(250,250,250);
   vertex(0, t*2, 0);
   vertex(0, 0, -t);
   vertex(t, 0, 0);

   fill(220,220,220);
   vertex(0, t*2, 0);
   vertex(t, 0, 0);
   vertex(0, 0, t);

   fill(250,250,250);
   vertex(0, t*2, 0);
   vertex(0, 0, t);
   vertex(-t, 0, 0);

   fill(250,250,250);
   vertex(0, -t*2, 0);
   vertex(0, 0, -t);
   vertex(-t, 0, 0);

   fill(220,220,220);
   vertex(0, -t*2, 0);
   vertex(0, 0, -t);
   vertex(t, 0, 0);


   fill(250,250,250);
   vertex(0, -t*2, 0);
   vertex(t, 0, 0);
   vertex(0, 0, t);

   fill(220,220,220);
   vertex(0, -t*2, 0);
   vertex(0, 0, t);
   vertex(-t, 0, 0);

    rotateY(theta); 

    endShape();

    popMatrix();
  }

  void rotacion() { 
    theta+=0.002+s;
  }


  void collision_det() {
     boolean touching = false;


for (int i=0; i<piramide.length;i++) {
Pyramid thisPyr = piramide[i];
for (int k=1; k<piramide.length; k++)
{
Pyramid otherPyr = piramide[k];
float dis = dist(thisPyr.x, thisPyr.y, otherPyr.x, otherPyr.y);
if ((dis - 0.1) < t*4) {
touching = true;
break;
}

if (touching == false) {
piramide[i].drawPiramide();
 }
 }
  }
}

}

Answers

  • I'm not sure about the math you do for collision detection, but the structure is strange. At the moment you compare each shape to all other shapes inside of "collision_det()". You should only comapare the current shape to the others and make sure that you do not compare it to itself.

    void collision_det() {
        boolean touching = false;
    
        for (int k=0; k<piramide.length; k++)
        {
          // do not compare with self
          if (piramide[k] != this) {
            Pyramid otherPyr = piramide[k];
            // i did not check if the next two lines are correct ...
            float dis = dist(this.x, this.y, otherPyr.x, otherPyr.y);
            if ((dis - 0.1) < t*4) {
              touching = true;
              break;
            }
    
            if (touching == false) {
              this.drawPiramide();
            }
          }
        }
      }
    
  • Thanks, it's more correct, indeed. But it still works the same. I found out that the dis is calculated wrong: for some reason this.x and this.y don't give the coordinates of a pyramid. How can I get the coordinates?

  • Answer ✓

    First, this.x and this.y should be alright. If they do not in your sketch, please post an example.

    For the collision-detection, there was a mistake in my code, of course one has to check for collision with all other pyramids and then draw the pyramid when none of them touches. So the drawPiramide() has to be outside of the loop.

    void collision_det() {
        boolean touching = false;
    
        for (int k=0; k<piramide.length; k++)
        {
          if (piramide[k] != this) {
            Pyramid otherPyr = piramide[k];
            // these lines could still be optimized ...
            float dis = dist(this.x, this.y, otherPyr.x, otherPyr.y);
            if ((dis - 0.1) < t*4) {
              touching = true;
              break;
            }
          }
        }  
    
        if (!touching) {
          this.drawPiramide();
        }
    
      }
    

    The formula for your collision-detection could still be optimized. For testing it could be a good idea to link the position of one pyramid to your mouse. Something like this in draw():

      piramide[0].x = mouseX;
      piramide[0].y = mouseY;
    
  • Fantactic, it works! Thank you a lot

Sign In or Register to comment.