How to avoid particle teletransportation when deleting elements from a particles ArrayList

edited February 2015 in Questions about Code
import peasy.*;
import processing.opengl.*;
import java.util.Iterator;

PeasyCam cam;

vectorField vectorfield;

ArrayList particles;
ArrayList<ArrayList> arrays = new ArrayList<ArrayList>();

void setup()
{
  size(800, 600, OPENGL);
  smooth();

  cam = new PeasyCam(this, 600/2, 600/2, 600/2, 700);

  vectorfield = new vectorField();
  particles = new ArrayList();

  for (int i = 0; i < 5; i++) 
  {
    particles.add(new Particle(new PVector(random(0, 600), random(0, 600), random(0, 600)), random(2, 5), random(0.1f, 0.5f)));
    ArrayList<PVector> lines = new ArrayList<PVector>();
    arrays.add(lines);
  }
}

void draw()
{
  background(255);
  vectorfield.display();

  for (int i = 0; i < particles.size (); i++) 
  {
    Particle p = (Particle) particles.get(i);

    ArrayList lines = (ArrayList) arrays.get(i);
    lines.add(new PVector(p.loc.x, p.loc.y, p.loc.z));

    p.follow(vectorfield);
    p.run();
  }

  for (int i = 0; i < arrays.size (); i++)
  {
    ArrayList lines = (ArrayList) arrays.get(i);


    if (lines.size() > 0)
    {
      for (int j=1; j < lines.size (); j++) 
      {
        PVector a = (PVector) lines.get(j-1);
        PVector b = (PVector) lines.get(j);

        stroke(255, 0, 0);
        strokeWeight(1);
        line(a.x, a.y, a.z, b.x, b.y, b.z);
      }
    }
  }

  Iterator<Particle> it = particles.iterator();
  while (it.hasNext ()) 
  {
    Particle p = it.next();
    if (p.isDead()) 
    {
      it.remove();
    }
  }
}


class Particle 
{
  PVector loc;
  PVector vel;
  PVector acc;
  float r;
  float maxforce;    // Maximum steering force
  float maxspeed;    // Maximum speed

  Particle(PVector l, float ms, float mf) 
  {
    loc = l.get();
    r = 3.0f;
    maxspeed = ms;
    maxforce = mf;
    acc = new PVector(0, 0, 0);
    vel = new PVector(0, 0, 0);
  }

  public void run() 
  {
    render();
    update();
  }

  void follow(vectorField f) 
  {

    // Look ahead
    PVector ahead = vel.get();
    ahead.normalize(); 
    PVector lookup = PVector.add(loc, ahead);

    // What is the vector at that spot in the vector field?
    PVector desired = f.lookup(lookup);
    // Scale it up by maxspeed
    desired.mult(maxspeed);
    // Steering is desired minus velocity
    PVector steer = PVector.sub(desired, vel);
    steer.limit(maxforce);  // Limit to maximum steering force
    acc.add(steer);
  }

  void update() 
  {
    // Update velocity
    vel.add(acc);
    // Limit speed
    vel.limit(maxspeed);
    loc.add(vel);
    // Reset accelertion to 0 each cycle
    acc.mult(0);
  }

  void render() 
  {
    stroke(0);
    strokeWeight(1);

    stroke(255, 0, 0);
    strokeWeight(5);
    pushMatrix();
    point(loc.x, loc.y, loc.z);
    popMatrix();
  }

  boolean isDead() 
  {
    if (loc.x < -r) return true;
    if (loc.y < -r) return true;
    if (loc.z < -r) return true;
    if (loc.x > 600+r) return true;
    if (loc.y > 600+r) return true;
    if (loc.z > 600+r) return true;
    else return false;
  }
}


class vectorField
{
  PVector[][][] field;
  int cols, rows, surf;

  int resolution;

  vectorField()
  {
    resolution = 50;

    cols = 600/resolution;
    rows = 600/resolution;
    surf = 600/resolution;

    field = new PVector[cols][rows][surf];
    init();
  }
  void init()
  {
    for (int i = 0; i < cols; i++)
    {
      for (int j = 0; j < rows; j++)
      {
        for (int k = 0; k < surf; k++)
        {
         field[i][j][k] = new PVector(random(-100, 100), random(-100, 100), random(-100, 100));
        }
      }
    }
  }

  void display()
  {
    for (int i = 0; i < cols; i++)
    {
      for (int j = 0; j < rows; j++)
      {
        for (int k = 0; k < surf; k++)
        {
          drawVector(field[i][j][k], i*resolution, j*resolution, k*resolution);
        }
      }
    }
  }

  void drawVector (PVector v, float x, float y, float z)
  {
    pushMatrix();
    translate(x, y, z);
    stroke(0,10);
    strokeWeight(1);
    line(0, 0, 0, v.x, v.y, v.z);
    popMatrix();
  }

  PVector lookup(PVector lookup) 
  {
    int i = (int) constrain(lookup.x/resolution, 0, cols-1);
    int j = (int) constrain(lookup.y/resolution, 0, rows-1);
    int k = (int) constrain(lookup.z/resolution, 0, surf-1);
    return field[i][j][k].get();
  }
}

Hello world! This is my first post in processing forum and I hope it won't be the last :) My problem is that I have an ArrayList of particles and an ArrayList of each particles position, which I use to draw a line along the trajectory of the particles. When the particles leave the VectorField I kill them, and here comes the headache... I have particle_0, particle_1, particle_2, and particle_3, when I kill particle_2 particle_3 becomes particle_2, the last know position of particle_2 was before leaving the VectorField and beeing removed, but the new position of the new particle_2 is a completely different one so it just draws a straight line between the last know position and the new one... I can't get to figure this out, I hope someone out there has a solution for this! :) Thanks in advanced

Answers

  • edited February 2015

    This is another version of the same code in which the tracking function is inside the Particle class, but the problem with this one is that every time that i kill the particle I also destroy the arraylist that contains each location that i use to draw the line. That's why I decided to try to put the tracking function outside the Particle class (see the post above).

    import peasy.*;
    import processing.opengl.*;
    import java.util.Iterator;
    
    PeasyCam cam;
    
    vectorField vectorfield;
    
    ArrayList particles;
    //ArrayList<ArrayList> arrays = new ArrayList<ArrayList>();
    
    void setup()
    {
      size(800, 600, OPENGL);
      smooth();
    
      cam = new PeasyCam(this, 600/2, 600/2, 600/2, 700);
    
      vectorfield = new vectorField();
      particles = new ArrayList();
    
      for (int i = 0; i < 100; i++) 
      {
        particles.add(new Particle(new PVector(random(0, 600), random(0, 600), random(0, 600)), random(2, 5), random(0.1f, 0.5f)));
    //    ArrayList<PVector> lines = new ArrayList<PVector>();
    //    arrays.add(lines);
      }
    }
    
    void draw()
    {
      background(255);
      vectorfield.display();
    
      for (int i = 0; i < particles.size (); i++) 
      {
        Particle p = (Particle) particles.get(i);
    
    //    ArrayList lines = (ArrayList) arrays.get(i);
    //    lines.add(new PVector(p.loc.x, p.loc.y, p.loc.z));
    
        p.follow(vectorfield);
        p.run();
      }
    
    //  for (int i = 0; i < arrays.size (); i++)
    //  {
    //    ArrayList lines = (ArrayList) arrays.get(i);
    //
    //
    //    if (lines.size() > 0)
    //    {
    //      for (int j=1; j < lines.size (); j++) 
    //      {
    //        PVector a = (PVector) lines.get(j-1);
    //        PVector b = (PVector) lines.get(j);
    //
    //        stroke(255, 0, 0);
    //        strokeWeight(1);
    //        line(a.x, a.y, a.z, b.x, b.y, b.z);
    //      }
    //    }
    //  }
    
      Iterator<Particle> it = particles.iterator();
      while (it.hasNext ()) 
      {
        Particle p = it.next();
        if (p.isDead()) 
        {
          it.remove();
        }
      }
    }
    
    class Particle 
    {
      PVector loc;
      PVector vel;
      PVector acc;
      float r;
      float maxforce;    // Maximum steering force
      float maxspeed;    // Maximum speed
    
      ArrayList<PVector> hist;
    
      Particle(PVector l, float ms, float mf) 
      {
        loc = l.get();
        r = 3.0f;
        maxspeed = ms;
        maxforce = mf;
        acc = new PVector(0, 0, 0);
        vel = new PVector(0, 0, 0);
    
        hist = new ArrayList<PVector>();
      }
    
      public void run() 
      {
        render();
        update();
      }
    
      void follow(vectorField f) 
      {
    
        // Look ahead
        PVector ahead = vel.get();
        ahead.normalize(); 
        PVector lookup = PVector.add(loc, ahead);
    
        // What is the vector at that spot in the vector field?
        PVector desired = f.lookup(lookup);
        // Scale it up by maxspeed
        desired.mult(maxspeed);
        // Steering is desired minus velocity
        PVector steer = PVector.sub(desired, vel);
        steer.limit(maxforce);  // Limit to maximum steering force
        acc.add(steer);
      }
    
      void update() 
      {
        hist.add(new PVector(loc.x, loc.y, loc.z));
    
        // Update velocity
        vel.add(acc);
        // Limit speed
        vel.limit(maxspeed);
        loc.add(vel);
        // Reset accelertion to 0 each cycle
        acc.mult(0);
      }
    
      void render() 
      {
        stroke(0);
        strokeWeight(1);
        if (hist.size() > 0)
        {
          for (int i=1; i < hist.size (); i++)
          {
             line(hist.get(i-1).x, hist.get(i-1).y, hist.get(i-1).z, hist.get(i).x, hist.get(i).y, hist.get(i).z); 
          }
        }
    
        stroke(255, 0, 0);
        strokeWeight(5);
        pushMatrix();
        point(loc.x, loc.y, loc.z);
        popMatrix();
      }
    
      boolean isDead() 
      {
        if (loc.x < -r) return true;
        if (loc.y < -r) return true;
        if (loc.z < -r) return true;
        if (loc.x > 600+r) return true;
        if (loc.y > 600+r) return true;
        if (loc.z > 600+r) return true;
        else return false;
      }
    }
    
    class vectorField
    {
      PVector[][][] field;
      int cols, rows, surf;
    
      int resolution;
    
      vectorField()
      {
        resolution = 50;
    
        cols = 600/resolution;
        rows = 600/resolution;
        surf = 600/resolution;
    
        field = new PVector[cols][rows][surf];
        init();
      }
      void init()
      {
        for (int i = 0; i < cols; i++)
        {
          for (int j = 0; j < rows; j++)
          {
            for (int k = 0; k < surf; k++)
            {
             field[i][j][k] = new PVector(random(-100, 100), random(-100, 100), random(-100, 100));
            }
          }
        }
      }
    
      void display()
      {
        for (int i = 0; i < cols; i++)
        {
          for (int j = 0; j < rows; j++)
          {
            for (int k = 0; k < surf; k++)
            {
              drawVector(field[i][j][k], i*resolution, j*resolution, k*resolution);
            }
          }
        }
      }
    
      void drawVector (PVector v, float x, float y, float z)
      {
        pushMatrix();
        translate(x, y, z);
        stroke(0,10);
        strokeWeight(1);
        line(0, 0, 0, v.x, v.y, v.z);
        popMatrix();
      }
    
      PVector lookup(PVector lookup) 
      {
        int i = (int) constrain(lookup.x/resolution, 0, cols-1);
        int j = (int) constrain(lookup.y/resolution, 0, rows-1);
        int k = (int) constrain(lookup.z/resolution, 0, surf-1);
        return field[i][j][k].get();
      }
    }
    
  • Answer ✓

    Managed to solve it, just in case anyone ever has the same problem:

    import peasy.*;
    import processing.opengl.*;
    import java.util.Iterator;
    
    PeasyCam cam;
    
    vectorField vectorfield;
    
    ArrayList particles;
    //ArrayList<ArrayList> arrays = new ArrayList<ArrayList>();
    
    ArrayList<PVector> lines; 
    ArrayList<ArrayList> arrays = new ArrayList<ArrayList>();
    int counter = 0;
    
    void setup()
    {
      size(800, 600, OPENGL);
      smooth();
    
      cam = new PeasyCam(this, 600/2, 600/2, 600/2, 700);
    
      vectorfield = new vectorField();
      particles = new ArrayList();
    
      for (int i = 0; i < 1000; i++) 
      {
        particles.add(new Particle(new PVector(random(0, 600), random(0, 600), random(0, 600)), random(2, 5), random(0.1f, 0.5f)));
        lines = new ArrayList<PVector>();
        arrays.add(lines);
      }
    }
    
    void draw()
    {
      background(255);
      vectorfield.display();
    
      if (keyPressed)
      {
        drawlines();
      }
    
      for (int i = 0; i < particles.size (); i++) 
      {
        Particle p = (Particle) particles.get(i);
    
        p.follow(vectorfield);
        p.run();
      }
    
      Iterator<Particle> it = particles.iterator();
      while (it.hasNext ()) 
      {
        Particle p = it.next();
        if (p.isDead()) 
        {
          it.remove();
        }
      }
    }
    
    void drawlines()
    {
      for (int i = 0; i < arrays.size (); i++)
      {
        ArrayList points = (ArrayList) arrays.get(i);
        for (int j=1; j < points.size (); j++)
        {
          PVector a = (PVector) points.get(j-1);
          PVector b = (PVector) points.get(j);
          stroke(255, 0, 0);
          strokeWeight(1);
          line(a.x, a.y, a.z, b.x, b.y, b.z);
        }
      }
    }
    
    class Particle 
    {
      PVector loc;
      PVector vel;
      PVector acc;
      float r;
      float maxforce;    // Maximum steering force
      float maxspeed;    // Maximum speed
    
        ArrayList<PVector> hist;
    
      Particle(PVector l, float ms, float mf) 
      {
        loc = l.get();
        r = 3.0f;
        maxspeed = ms;
        maxforce = mf;
        acc = new PVector(0, 0, 0);
        vel = new PVector(0, 0, 0);
    
        hist = new ArrayList<PVector>();
      }
    
      public void run() 
      {
        render();
        update();
      }
    
      void follow(vectorField f) 
      {
    
        // Look ahead
        PVector ahead = vel.get();
        ahead.normalize(); 
        PVector lookup = PVector.add(loc, ahead);
    
        // What is the vector at that spot in the vector field?
        PVector desired = f.lookup(lookup);
        // Scale it up by maxspeed
        desired.mult(maxspeed);
        // Steering is desired minus velocity
        PVector steer = PVector.sub(desired, vel);
        steer.limit(maxforce);  // Limit to maximum steering force
        acc.add(steer);
      }
    
      void update() 
      {
        hist.add(new PVector(loc.x, loc.y, loc.z));
    
        // Update velocity
        vel.add(acc);
        // Limit speed
        vel.limit(maxspeed);
        loc.add(vel);
        // Reset accelertion to 0 each cycle
        acc.mult(0);
      }
    
      void render() 
      {
        stroke(0);
        strokeWeight(1);
        if (hist.size() > 0)
        {
          for (int i=1; i < hist.size (); i++)
          {
            line(hist.get(i-1).x, hist.get(i-1).y, hist.get(i-1).z, hist.get(i).x, hist.get(i).y, hist.get(i).z);
          }
        }
    
        stroke(255, 0, 0);
        strokeWeight(5);
        pushMatrix();
        point(loc.x, loc.y, loc.z);
        popMatrix();
      }
    
      boolean isDead() 
      {
        if (loc.x < -r) 
        {
          ArrayList _lines = (ArrayList) arrays.get(counter);
          _lines.addAll(hist);
          counter++; 
          return true;
        }
        if (loc.y < -r) 
        {
          ArrayList _lines = (ArrayList) arrays.get(counter);
          _lines.addAll(hist);
          counter++; 
          return true;
        }
        if (loc.z < -r)  
        {
          ArrayList _lines = (ArrayList) arrays.get(counter);
          _lines.addAll(hist);
          counter++; 
          return true;
        }
        if (loc.x > 600+r)  
        {
          ArrayList _lines = (ArrayList) arrays.get(counter);
          _lines.addAll(hist);
          counter++; 
          return true;
        }
        if (loc.y > 600+r)  
        {
          ArrayList _lines = (ArrayList) arrays.get(counter);
          _lines.addAll(hist);
          counter++; 
          return true;
        }
        if (loc.z > 600+r)  
        {
          ArrayList _lines = (ArrayList) arrays.get(counter);
          _lines.addAll(hist);
          counter++; 
          return true;
        } else 
        {
          return false;
        }
      }
    }
    
    class vectorField
    {
      PVector[][][] field;
      int cols, rows, surf;
    
      int resolution;
    
      vectorField()
      {
        resolution = 50;
    
        cols = 600/resolution;
        rows = 600/resolution;
        surf = 600/resolution;
    
        field = new PVector[cols][rows][surf];
        init();
      }
      void init()
      {
        for (int i = 0; i < cols; i++)
        {
          for (int j = 0; j < rows; j++)
          {
            for (int k = 0; k < surf; k++)
            {
              field[i][j][k] = new PVector(random(-100, 100), random(-100, 100), random(-100, 100));
            }
          }
        }
      }
    
      void display()
      {
        for (int i = 0; i < cols; i++)
        {
          for (int j = 0; j < rows; j++)
          {
            for (int k = 0; k < surf; k++)
            {
              drawVector(field[i][j][k], i*resolution, j*resolution, k*resolution);
            }
          }
        }
      }
    
      void drawVector (PVector v, float x, float y, float z)
      {
        pushMatrix();
        translate(x, y, z);
        stroke(0, 10);
        strokeWeight(1);
        line(0, 0, 0, v.x, v.y, v.z);
        popMatrix();
      }
    
      PVector lookup(PVector lookup) 
      {
        int i = (int) constrain(lookup.x/resolution, 0, cols-1);
        int j = (int) constrain(lookup.y/resolution, 0, rows-1);
        int k = (int) constrain(lookup.z/resolution, 0, surf-1);
        return field[i][j][k].get();
      }
    }
    
Sign In or Register to comment.