Toxiclibs how to remove particles

edited December 2013 in Library Questions

Hi Karsten and everybody!

I am trying to use Toxilibs with this example: http://www.openprocessing.org/sketch/17191

Where can i find an example about how to remove particles of a system? I am having an error trying the removeParticle method.

For example, to make a system that grows in particles until a limit and after that, kill them.

I really appreciate your help.

Thanks in advance and warm regards.

Patricio

Tagged:

Comments

  • What is the error you are getting?

  • edited December 2013

    Hi Colour! Im having a java.util.ConcurrentModificationException error.

    The code i am trying (look at mousePressed function):

    import toxi.geom.*;
    import toxi.physics2d.*;
    import toxi.physics2d.behaviors.*;
    
    int NUM_PARTICLES = 750;
    
    VerletPhysics2D physics;
    AttractionBehavior mouseAttractor;
    
    Vec2D mousePos;
    
    void setup() {
      size(680, 382,P3D);
      // setup physics with 10% drag
      physics = new VerletPhysics2D();
      physics.setDrag(0.05f);
      physics.setWorldBounds(new Rect(0, 0, width, height));
      // the NEW way to add gravity to the simulation, using behaviors
      physics.addBehavior(new GravityBehavior(new Vec2D(0, 0.15f)));
    }
    
    void addParticle() {
      VerletParticle2D p = new VerletParticle2D(Vec2D.randomVector().scale(5).addSelf(width / 2, 0));
      physics.addParticle(p);
      // add a negative attraction force field around the new particle
      physics.addBehavior(new AttractionBehavior(p, 20, -1.2f, 0.01f));
    }
    
    void draw() {
      background(255,0,0);
      noStroke();
      fill(255);
      if (physics.particles.size() < NUM_PARTICLES) {
        addParticle();
      }
      physics.update();
      for (VerletParticle2D p : physics.particles) {
        ellipse(p.x, p.y, 5, 5);
      }
    }
    
    void mousePressed() {
      for (VerletParticle2D p : physics.particles) {
        physics.removeParticle(p);
      }
    }
    
  • edited December 2013

    Ahh, that's an annoying error. It means that there are multiple threads, one is displaying the particles, the other is removing a particle. Both happen at the same time, so a particle is removed when Processing tries to display it. This gives the error. I'm not entirely sure what the best way to handle this is, but my solution is to add a boolean that turns true when the removeParticle() is activated.

    I can't make much of your code (please format it with ctrl+t in Processing before pasting it in the forum and then select the code and press the C button), but this is the idea:

    boolean removing = false;
    void draw()
    {
      //blah blah
    
      if (!removing)
      {
        physics.update();
        for(VerletParticle2D p : physics.particles)
        {
          ellipse(p.x, p.y, 5, 5);
        }
      }
    }
    
    void mousePressed()
    {
      removing = true;
      for(VerletParticle2D p : physics.particles)
      {
        physics.removeParticle(p);
      }
      removing = false;
    }
    

    I hope this solves it.

  • Thanks a lot for your help and sorry for the wrong copy&paste.

    I tried your code but im still having the error. Here is the code

    import toxi.geom.*;
    import toxi.physics2d.*;
    import toxi.physics2d.behaviors.*;
    
    int NUM_PARTICLES = 10;
    boolean removing = false;
    
    VerletPhysics2D physics;
    AttractionBehavior mouseAttractor;
    
    Vec2D mousePos;
    
    void setup() 
    {
      size(680, 382, P3D);
      // setup physics with 10% drag
      physics = new VerletPhysics2D();
      physics.setDrag(0.05f);
      physics.setWorldBounds(new Rect(0, 0, width, height));
      // the NEW way to add gravity to the simulation, using behaviors
      physics.addBehavior(new GravityBehavior(new Vec2D(0, 0.15f)));
    }
    
    void addParticle() 
    {
      VerletParticle2D p = new VerletParticle2D(Vec2D.randomVector().scale(5).addSelf(width / 2, 0));
      physics.addParticle(p);
      // add a negative attraction force field around the new particle
      physics.addBehavior(new AttractionBehavior(p, 20, -1.2f, 0.01f));
    }
    
    void draw() 
    {
      background(255, 0, 0);
      noStroke();
      fill(255);
    
      if (!removing)
      {  
        if (physics.particles.size() < NUM_PARTICLES) 
        {
          addParticle();
        }
        physics.update();
        for (VerletParticle2D p : physics.particles) 
        {
          ellipse(p.x, p.y, 5, 5);
        }
      }
    }
    
    void mousePressed()
    {
      removing = true;
      for (VerletParticle2D p : physics.particles)
      {
        physics.removeParticle(p);
      }
      removing = false;
    }
    
    

  • Oh! man sorry again!!!

  • I don't think this is a threading issue; rather, you're trying to iterate over an ArrayList (I assume?) while removing items from it. You might be able to avoid it by using a for loop iterating in reverse, e.g. something like this (untested) :

    for(int i=physics.particles.size()-1; i>=0; i--){
      VerletParticle2D p=  physics.particles.get(i);
      physics.removeParticle(p);
    }
    
  • edited December 2013

    I'm out of suggestions now... maybe also include the if(!removing) inside the addParticle() method? But if that doesn't solve it, I hope one of the experts sees this. Maybe something else is causing the error, but I don't see what.

    Edit, or what velvet said. Isn't there a better way to remove all particles, like physics.particles.clear()? Not sure about the syntax, you might want to look into the documentation.

  • edited December 2013

    You are getting the error because you are removing elements from the ArrayList while looping through it. This is a big no in Java. There are ways of getting around this, however.

    If you want to remove all items from an ArrayList, you can use ArrayList.clear(). So your mousePressed() function would be:

    void mousePressed() {
      physics.particles.clear();
    }
    

    If you want to remove individual items from an ArrayList, you should use an Iterator. I won't provide an example because this isn't necessarily what the OP asked... but it's worth mentioning.

Sign In or Register to comment.