Make trail move in Z direction

I am trying to set up an interaction between AntD and the trail it leaves behind. I want the trail to move up in the Z direction every time the AntD come within a certain distance of the trail. Right now i have just added more trail into the arrayList trail, but what I want to do is move the trail that is already being left behind. Currently i have set up the Void collideTrail for this but it doesn’t seem to be working properly. Any help would be greatly appreciated.

import peasy.*;
PeasyCam cam;

AntD [] armyD = new AntD[20];


void setup()
{

  size(900, 900, P3D);
  smooth();
  frameRate(24);
  cam = new PeasyCam (this, 1000);
  cam.setMinimumDistance(50);
  cam.setMaximumDistance(1000);

  for (int i=0; i<armyD.length; i++)
  {
    armyD [i] = new AntD();
  }
}



void draw()
{

  background (0);

  for (int i=0; i<armyD.length; i++)
  {
    armyD[i].heading();
    armyD[i].draw();
    armyD[i].transmit();
    armyD[i].drawTrail();
    //armyD[i].drawFood();
    armyD[i].collideTrail();
  }
}
}
class AntD
{

  int[][]coordinates = {{0, 2}, {2, 2}, {2, 0}, {2, -2}, {0, -2}, {-2, -2}, {-2, 0}, {-2, 2}, {0, 5}, {5, 5}, {5, 0}, {5, -5}, {0, -5}, {-5, -5}, {-5, 0}, {-5, 5}};

  PVector positionD;
  PVector headingD;
  float dia;
  ArrayList trail;
  ArrayList fsource;
  int dir;
  //List<PVector> foodA = new ArrayList<PVector>();



  AntD()
  {
    dia = 2;
    float a = random(16);  // picking a random value
    int b = int(a);       // converting random value from float to integer
    headingD = new PVector(random(width)+coordinates [b][0], random(height)+coordinates [b][1], 0);
    trail = new ArrayList();
    fsource = new ArrayList();
  }

  void heading()
  {
    float a = random(-2, 2);
    int b = int(a);
    dir = dir+b;

    if (dir == -1)
    {
      dir = 15;
    }
    if (dir == 16)
    {
      dir = 0;
    }
    headingD.x = (headingD.x+width)%width;
    headingD.y = (headingD.y+height)%height;
    headingD.z = (headingD.z+width)%width;
  }

  void draw()
  {

    heading();
    positionD = headingD.get();
    headingD = new PVector(positionD.x+coordinates[dir][0], positionD.y+coordinates[dir][1], 0);


    //stroke (0, 255, 0);
    // line (positionD.x, positionD.y, headingD.x, headingD.y);
    //pushMatrix();
    stroke (0);
    fill (255);
    ellipse (headingD.x, headingD.y, 5, 5);
    //popMatrix();
  }

  void transmit() {
    for (int i=0; i<trail.size (); i++) {
      if (trail.size() != 0) {
        droppings t = (droppings) trail.get(i);
        t.paint();
        if ( trail.size() > 700) {
          trail.remove(trail.get(i--)); // reduces the lenght of the trail, to run code smoother
        }
      }
    }
  }

  void drawTrail() {

    trail.add(new droppings(new PVector(positionD.x, positionD.y, positionD.z), 2));
  }
  
  
  void collideTrail() {
    PVector droppingspos;
    for (int i=0; i<trail.size(); i++) {
      droppings drop = (droppings) trail.get(i);
      droppingspos = drop.loc.get();
      float d = positionD.dist(droppingspos);
      if ( d< dia/2) {
        trail.add(new droppings(new PVector(droppingspos.x, droppingspos.y, droppingspos.z+10), 2));
        println("movingup");
      }
    }
  }


class droppings {
  PVector loc;
  float diameter;
  PVector moveZ;
  
  
  droppings (PVector loc_, float dia) {
    loc = loc_;
    dia = diameter= 2;
  }

void paint () {
  pushMatrix(); 
    stroke(255);
    translate(loc.x, loc.y, loc.z);
    ellipse(0,0, diameter,diameter);
    popMatrix();
  }

Nice idea!

Here is my version!

import peasy.*;
PeasyCam cam;

AntD [] armyD = new AntD[20];


void setup()
{

  size(900, 900, P3D);
  smooth();
  frameRate(24);
  cam = new PeasyCam (this, 1000);
  cam.setMinimumDistance(50);
  cam.setMaximumDistance(1000);

  for (int i=0; i<armyD.length; i++)
  {
    armyD [i] = new AntD();
  }
}

void draw()
{

  background (0);
  lights(); 

  for (int i=0; i<armyD.length; i++)
  {
    armyD[i].heading();
    armyD[i].draw();
    armyD[i].transmit();
    armyD[i].drawTrail();
    //armyD[i].drawFood();
    armyD[i].collideTrail();
  }
}

// ===============================================================================================================

class AntD
{

  int[][]coordinates = {
    {0, 2}, {2, 2}, {2, 0}, {2, -2}, {0, -2}, {-2, -2}, {-2, 0}, {-2, 2}, {0, 5}, {5, 5}, {5, 0}, {5, -5}, {0, -5}, {-5, -5}, {-5, 0}, {-5, 5}
  };

  PVector positionD;
  PVector headingD;
  float dia;
  ArrayList trail;
  ArrayList fsource;
  int dir;
  //List<PVector> foodA = new ArrayList<PVector>();
  color col1  =  color(random(22, 256), random(22, 256), random(22, 256));

  AntD()
  {
    dia = 2;
    float a = random(16);  // picking a random value
    int b = int(a);       // converting random value from float to integer
    headingD = new PVector(random(width)+coordinates [b][0], random(height)+coordinates [b][1], 0);
    trail = new ArrayList();
    fsource = new ArrayList();
  }

  void heading()
  {
    float a = random(-2, 2);
    int b = int(a);
    dir = dir+b;

    if (dir == -1)
    {
      dir = 15;
    }
    if (dir == 16)
    {
      dir = 0;
    }
    headingD.x = (headingD.x+width)%width;
    headingD.y = (headingD.y+height)%height;
    headingD.z = (headingD.z+width)%width;
  }

  void draw()
  {
    heading();
    positionD = headingD.get();
    headingD = new PVector(positionD.x+coordinates[dir][0], positionD.y+coordinates[dir][1], 0);

    //stroke (0, 255, 0);
    // line (positionD.x, positionD.y, headingD.x, headingD.y);
    //pushMatrix();
    stroke (0);
    fill (col1);
    ellipse (headingD.x, headingD.y, 9, 9);
    //popMatrix();
  }

  void transmit() {
    for (int i=0; i<trail.size (); i++) {
      if (trail.size() != 0) {
        Dropping t = (Dropping) trail.get(i);
        t.paint();
        if ( trail.size() > 700) {
          trail.remove(trail.get(i--)); // reduces the lenght of the trail, to run code smoother
        }
      }
    }
  }

  void drawTrail() {

    trail.add(new Dropping(new PVector(positionD.x, positionD.y, positionD.z), 2));
  }


  void collideTrail() {
    PVector droppingspos;
    for (int i=0; i<trail.size(); i++) {
      Dropping drop = (Dropping) trail.get(i);
      droppingspos = drop.loc.get();
      float d = positionD.dist(droppingspos);

      drop.loc.z=(trail.size()-i)*0.3; 

      if ( d < dia/2) {
        drop.loc.z+=10; 
        // trail.add(new Dropping(new PVector(droppingspos.x, droppingspos.y, droppingspos.z+10), 2));
        //  println("movingup");
      }
    }
  }
}//class 

//===================================================================================================================

class Dropping {
  PVector loc;
  float diameter;
  PVector moveZ;


  Dropping (PVector loc_, float dia) {
    loc = loc_;
    dia = diameter= 2;
  }

  void paint () {
    pushMatrix(); 
    stroke(255);
    translate(loc.x, loc.y, loc.z);
    ellipse(0, 0, diameter, diameter);
    popMatrix();
  }
}//class 
//

Hey,

Thanks Chrisir, this helps a lot. If i may ask, right now the entire trail moves in the Z direction. What if i just wanted the parts of the trail that overlap each other to move, not the entire trail, and every time the x,y position is same as the x,y position of the trail, only then it moves in the Z direction. I hope it makes sense what i am trying to say.

Regards

The idea is that in your sketch you added new droppings to the list of droppings.

Instead change the z of an existing dropping. Make this in your project

Remark

To avoid clipping call this function

void avoidClipping() {
// avoid clipping :
// https : //
// [forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear ](http://forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear)
perspective(PI/3.0, (float) width/height, 1, 1000000);
}//func

Thanks, i will give it a go.

1 Like

The avoid clipping code and lights() in draw are essential in every 3D Sketch imho

Also, consider using sphere instead of ellipse (slower though)

Least: the general idea in 3D is that the floor is in x/z plane and UP is y.

You haven’t this

something like this

or drop.loc.z = 120;

The idea is I want export the file as dxf to further work on it in the 3d modelling software Rhino. Spheres are much more heavier to export, and its easier to translate ellipses into grasshopper.

1 Like

I will try editing the sketch so that it moves the XY to the XZ and use Y as up.

1 Like

When you say this, you express the same thing twice, correct?

  • if i just wanted the parts of the trail that overlap each other to move, not the entire trail, and
  • every time the x,y position is same as the x,y position of the trail, only then it moves in the Z direction.

Same, isn’t it?

Do you mean overlapping droppings within the same trail of one Ant or
do you mean overlapping droppings of different trails/Ant?

I assume your if-clause was correct and you have to change it to:

      if ( d < dia/2) {
           drop.loc.z = (trail.size()-i)*0.3; 

Okay?

Warm regards,

Chrisir

Hello, yes I think that was me pretty much repeating it, apologies for the confusion.

Yes that’s exactly what I meant that only the ones that overlap should move.The rest of the trail stays where it is.

And yes, it’s working that way. Thankyou very much.

1 Like

Is this solved? Can you please show me the function?