Search code examples
javascriptprocessingp5.js

Multiple object intersection and removal problem [ processing/p5.js ]


I am new to stack and not quite sure how to use it. But here I am. I am working on a ecosystem project, and I have an animal class with 2 different genders(0 for female, 1 for male). When 2 different genders intersect each other than I want to remove those 2 objects and add a couple(different object, static) object on that position. I kinda did it but it only works for a couple of seconds. Then the code just breaks. In the console it says, “Uncaught TypeError: Cannot read property ‘intersects’ of undefined”

Here's the question on the processing forum in case I get a solution which might help others: https://discourse.processing.org/t/multiple-object-intersection-and-removal/22900/2

Here's the sketch.js file:

var animats = [];

var couples = [];

function setup() {
frameRate(30);
             
createCanvas(displayWidth, 470);
            
for(var i = 0; i < 50; i++) 
{
animats[i] = new Animat(random(0, width), random(0, height));

}

}

function draw() {

background(255,100,100);
        
for(var i = animats.length-1; i >= 0; i--) {    
             
animats[i].birth(); 
                
animats[i].grow();

 for(var j = i; j >= 0; j--) {
                                      
   if(j != i && animats[i].intersects(animats[j])) {
                                                        
   animats.splice(i, 1);
                                                              
   animats.splice(j, 1);
                            
                                                     
 }
                             
 }
 }  

 }

Here's the animat class file:

function Animat(x, y) {
            this.x = x;
            this.y = y;
            
            this.gender;
            var g = random(0,1);
            var c;
                            
                            if(g > 0.5) {
                                            c = 0;
                                this.gender = 0;
                            } else {
                                            c = 255;
                                this.gender = 1;
                            }
            
            this.speed = 1;

            this.age = 0;
            this.length = 0.5;
            
            this.birth = function() {
                            
                            //gender
                            
                            //create
                            noStroke();
                            fill(c);
                            text("n", this.x, this.y, this.length, this.length);
                            ellipse(this.x, this.y, this.length * 2, this.length * 2);
                            
                            
                            //move
                            
                            switch(floor(random(0,4))) {
                                            case 0:
                                                            this.x += this.speed;
                      break;
                                            case 1:
                                                            this.y += this.speed;
                      break;
                                            case 2:
                                                            this.x -= this.speed;
                      break;
                                            case 3:
                                                            this.y -= this.speed;
                      break;
                                            default:
                                                            this.x++;
                                                            this.y--;
                            }
                            
                //bounce
                            
                            if(this.x > width || this.x < 4){
                                            this.speed *= -1;
                            }
                            if(this.y > height || this.y < 4){
                                            this.speed *= -1;
                            }
                                            
            }

            this.grow = function() {
                            this.age += 0.01;
                            this.length += 0.05;
                            
                            //age checks
                            
                            if(this.age > 10) {
                                            this.speed + 5;
                            } else if(this.age > 21) {
                                            this.length = 25;
                                            this.speed = this.speed
                                            //console.log("max age:" + this.age)
                            } else if(this.age > 70) {
                                            //die
                            } else {
                                            
                            }
                            
                            //length checks 
                            
                            if(this.length > 25) {
                                            this.length = 25;
                                         //console.log("max length");
                            }
            }
            
            //relationship
            
            this.intersects = function(other) {
                            var d = dist(this.x, this.y, other.x, other.y);
                            var r = this.length + other.length;
                            
                            if(d < r) {
                                            if(((this.gender == 0) && (other.gender == 1)) || ((this.gender == 1) && (other.gender == 0))) {
                                                return true;
                                            } else {
                                                            this.speed *= -1;
                                            }
                                            
                            } else {
                                            return false;
                            }
            }
            
            //mate
            
         this.couple = function() {
                            if(((this.gender == 0) && (other.gender == 1)) || ((this.gender == 1) && (other.gender == 0))) {
                                                return true;
                                            } else {
                                                            this.speed *= -1;
                                            }
            }
            
            //die
            
         /*this.die = function() {
                    if(this.age > 50) {
                                            return true;
                            } else {
                                            return false;
                            }
   }*/
            

}

Here's the codepen link for results I am getting: https://codepen.io/AbrarShahriar/pen/XWXwLPM


Solution

  • Try changing your nested for loop to:

    for (var i = animats.length - 1; i >= 0; i--) {
      animats[i].birth();
      animats[i].grow();
      for (var j = i; j >= 0; j--) {
        if (j != i && animats[i].intersects(animats[j])) {
          animats.splice(i, 1);
          animats.splice(j, 1);
          break; //exit the inner loop after a match
        }
      }
    }
    

    In other words, add a break; after two animats have coupled and have been removed from the array. The error was probably caused by you trying to call the intersects method of an animat that had already been removed.