# Random walker through points

**URL:** <https://discourse.processing.org/t/random-walker-through-points/18040>\
**Category:** Coding Questions\
**Created:** [February 23, 2020, 8:14am UTC](https://discourse.processing.org/t/random-walker-through-points/18040 "2020-02-23T08:14:08Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 23, 2020, 8:14am UTC](https://discourse.processing.org/t/random-walker-through-points/18040/1 "2020-02-23T08:14:08Z")

</div>

Hi there,

I am working on a random walker through points, and I am struggling to get the next closest point in the walker class.

The idea is to have one or few random walkers going from point to point until there is no point left.

```auto
void update(ArrayList<Anchor> anchors) {
    if (anchors.size()>0) {
      int idx = getNearest(anchors);
      println(""+idx);
      Anchor a = anchors.get(idx);
      PVector move = a.pos;
      previousPos.set(pos);
      pos.add(move);
      anchors.remove(idx);
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 1000;
    int idx = 0;
    for (int i = 0; i >= anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < record) {
        dist = record;
        idx = i;
      }
    }
    return idx; // give index of nearest target
  }

```

It seem that the int idx never really update in the int getNearest(ArrayList anchors) function

Bellow the complete code;

```auto
ArrayList<Walker> walkers;
ArrayList<Anchor> anchors;

PVector pos;

int walkerCount = 1;
int anchorCount = 500;
float x = 0;
float y = 0;

void setup() {
  size(800, 800);
  background(51);
  frameRate(60);
  
  walkers = new ArrayList<Walker>();
  anchors = new ArrayList<Anchor>();
  
  for (int i = 0; i < walkerCount; i++) {
    PVector origin = new PVector(random(width), 0);
    walkers.add(new Walker(origin, color(random(256), random(256), random(256))));
  }
  for (int i = 0; i < anchorCount; i++) {
    PVector position = new PVector(random(width), random(height));
    anchors.add(new Anchor(position));
  }
}

void draw() {

  for (int i = 0; i < walkers.size(); i++) {
    Walker w = (Walker) walkers.get(i);
    w.update(anchors);
    w.show();
    
  }

  for (int i = 0; i < anchors.size(); i++) {
    Anchor a = (Anchor) anchors.get(i);
    a.show();
  }
}

class Walker {
  PVector pos;
  PVector previousPos;
  color col;

  Walker(PVector position, color c) {
    col = c;
    pos = new PVector(position.x, position.y);
    previousPos = pos.copy();
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    //point(pos.x, pos.y);
    line(previousPos.x, previousPos.y, pos.x, pos.y);
  }

  void update(ArrayList<Anchor> anchors) {
    if (anchors.size()>0) {
      int idx = getNearest(anchors);
      println(""+idx);
      Anchor a = anchors.get(idx);
      PVector move = a.pos;
      previousPos.set(pos);
      pos.add(move);
      anchors.remove(idx);
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 1000;
    int idx = 0;
    for (int i = 0; i >= anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < record) {
        dist = record;
        idx = i;
      }
    }
    return idx; // give index of nearest target
  }
}

class Anchor {
  PVector pos;
  color col;

  Anchor(PVector position) {
    col = color(0);
    pos = new PVector(position.x, position.y);
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    point(pos.x, pos.y);
  }

  void update() {
  }
}

```

I am very grateful for any advice,

Many thanks

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 11:47am UTC](https://discourse.processing.org/t/random-walker-through-points/18040/2 "2020-02-23T11:47:27Z")

</div>

> [@Giyomu](#):
>
> for (int i = 0; i \>= anchors.size(); i++) {

that’s wrong; I think you want `i < anchors.size()` (think do this **as long as** )

Chrisir

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 12:11pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/3 "2020-02-23T12:11:58Z")

</div>

you had several minor errors

- look at this line in getNearest: dist = record; !!!

- also look at pos.add(move); in method update() in class Walker

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 23, 2020, 12:31pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/4 "2020-02-23T12:31:24Z")

</div>

Thank you Chrisir, that right, and I also spotted that I didn’t sub the target with the pos. Thank you for your input.

```auto
  void update(ArrayList<Anchor> anchors) {
    if (anchors.size()>0) {
      int idx = getNearest(anchors);
      println(""+idx);
      Anchor a = anchors.get(idx);
      PVector target = a.pos;
      PVector move = target.sub(pos);
      previousPos.set(pos);
      pos.add(move);
      anchors.remove(idx);
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 1000;
    int idx=0;
    for (int i = 0; i < anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < 10) {
        if (dist < record) {
          dist = record;
          idx = i;
          if (idx == 0){break;}
        }
      }
    }
    return idx; 

```

I am getting closer to the desired solution :); A problem remains when the walker doesn’t find a smaller distance, the index becomes zero, so the walker jumps to the next zero of the list.

 ![gol_0003](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/c2ef6dedaf96af87653e1f834ae7f65d13534526.png)

Furthermore, I am trying to stop the process if;

- the walker doesn’t find a point close enough
- the walker has to jump on another walker path

I would like to implement this kind of code on a mesh later on

thank you again 🙂

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 12:34pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/5 "2020-02-23T12:34:33Z")

</div>

> [@Giyomu](#):
>
> dist = record;

that is still wrong!!!

Please read again the section

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 23, 2020, 12:46pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/6 "2020-02-23T12:46:56Z")

</div>

That right, my bad! (still a beginner)

```auto
int getNearest(ArrayList<Anchor> anchors) {
    float record = 1000;
    int idx=0;
    for (int i = 0; i < anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < 50) {
        if (dist < record) {
          record = dist;
          idx = i;
          //if (idx == 0){break;}
        }
      }
    }
    return idx;   

```

 ![gol_0011](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/b/b88eadef245f9f2fbc4c65c2d5be41dc4ca23e4a.png)

Would you know a method to stop the waker should the point being too far?

thank you

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 12:52pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/7 "2020-02-23T12:52:31Z")

</div>

> [@Giyomu](#):
>
> record = dist;

I think this was VERY important

here is my version (without stopping)

```auto

ArrayList<Walker> walkers;
ArrayList<Anchor> anchors;

PVector pos;

int walkerCount = 1;
int anchorCount = 500;

float x = 0;
float y = 0;

void setup() {
  size(800, 800);
  background(51);
  // frameRate(6);

  walkers = new ArrayList<Walker>();
  anchors = new ArrayList<Anchor>();

  for (int i = 0; i < walkerCount; i++) {
    PVector origin = new PVector(random(width), 0);
    walkers.add(new Walker(origin, color(random(256), random(256), random(256))));
  }

  for (int i = 0; i < anchorCount; i++) {
    PVector position = new PVector(random(width), random(height));
    anchors.add(new Anchor(position));
  }
}//setup()

void draw() {
  // background(51);

  for (int i = 0; i < walkers.size(); i++) { // for (Walker w : walkers) { !!!!!!!!!!!!!!!!!!!!!!!
    Walker w = walkers.get(i); // (Walker) walkers.get(i);
    w.update(anchors);
    w.show();
  }

  for (int i = 0; i < anchors.size(); i++) {
    Anchor a = anchors.get(i); // (Anchor) anchors.get(i);
    a.show();
  }
}//draw()

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

class Walker {
  PVector pos;
  PVector previousPos;
  color col;

  Walker(PVector position, color c) {
    col = c;
    pos = position.copy(); // new PVector(position.x, position.y);
    previousPos = pos.copy();
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    //point(pos.x, pos.y);
    line(previousPos.x, previousPos.y, 
      pos.x, pos.y);
  }

  void update(ArrayList<Anchor> anchors) {

    if (anchors.size()>0) {
      int idx = getNearest(anchors);
      println(""+idx);
      Anchor a = anchors.get(idx);
      PVector move = a.pos;
      previousPos.set(pos);

      /*
      float targetX = move.x;
       float dx = targetX - pos.x;
       pos.x += dx ; // * easing;  
       
       float targetY = move.y;
       float dy = targetY - pos.y;
       pos.y += dy ; // * easing; 
       */

      // pos.add(move);
      pos=move.copy(); 
      anchors.remove(idx);
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 10000;
    int idx = 0;
    for (int i = 0; i < anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < record) {
        record = dist; // YOU HAD dist = record; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        idx = i;
      }
    }
    return idx; // give index of nearest target
  }
}

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

class Anchor {
  PVector pos;
  color col;

  Anchor(PVector position) {
    col = color(0);
    pos = new PVector(position.x, position.y);
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    point(pos.x, pos.y);
  }

  void update() {
  }
}
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 12:56pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/8 "2020-02-23T12:56:50Z")

</div>

here is a version that stops.

We return -1 (not an allowed index!) to indicate failure when dist \> 86 or so

Then we evaluate idx and abort update in Walker class

```auto
ArrayList<Walker> walkers;
ArrayList<Anchor> anchors;

PVector pos;

int walkerCount = 1;
int anchorCount = 500;

float x = 0;
float y = 0;

void setup() {
  size(800, 800);
  background(51);
  // frameRate(6);

  walkers = new ArrayList<Walker>();
  anchors = new ArrayList<Anchor>();

  for (int i = 0; i < walkerCount; i++) {
    PVector origin = new PVector(random(width), 0);
    walkers.add(new Walker(origin, color(random(256), random(256), random(256))));
  }

  for (int i = 0; i < anchorCount; i++) {
    PVector position = new PVector(random(width), random(height));
    anchors.add(new Anchor(position));
  }
}//setup()

void draw() {
  // background(51);

  for (int i = 0; i < walkers.size(); i++) { // for (Walker w : walkers) { !!!!!!!!!!!!!!!!!!!!!!!
    Walker w = walkers.get(i); // (Walker) walkers.get(i);
    w.update(anchors);
    w.show();
  }

  for (int i = 0; i < anchors.size(); i++) {
    Anchor a = anchors.get(i); // (Anchor) anchors.get(i);
    a.show();
  }
}//draw()

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

class Walker {
  PVector pos;
  PVector previousPos;
  color col;

  Walker(PVector position, color c) {
    col = c;
    pos = position.copy(); // new PVector(position.x, position.y);
    previousPos = pos.copy();
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    //point(pos.x, pos.y);
    line(previousPos.x, previousPos.y, 
      pos.x, pos.y);
  }

  void update(ArrayList<Anchor> anchors) {

    if (anchors.size()>0) {
      int idx = getNearest(anchors);

      if (idx<0) 
        return; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

      println(""+idx);
      Anchor a = anchors.get(idx);
      PVector move = a.pos;
      previousPos.set(pos);

      /*
      float targetX = move.x;
       float dx = targetX - pos.x;
       pos.x += dx ; // * easing;  
       
       float targetY = move.y;
       float dy = targetY - pos.y;
       pos.y += dy ; // * easing; 
       */

      // pos.add(move);
      pos=move.copy(); 
      anchors.remove(idx);
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 10000;
    int idx = 0;
    for (int i = 0; i < anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < record) {
        record = dist; // YOU HAD dist = record; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        idx = i;
      }
    }
    if (record<86) 
      return idx; // give index of nearest target
    else 
    return -1;
  }
}

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

class Anchor {
  PVector pos;
  color col;

  Anchor(PVector position) {
    col = color(0);
    pos = new PVector(position.x, position.y);
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    point(pos.x, pos.y);
  }

  void update() {
  }
}
//

```

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 23, 2020, 1:04pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/9 "2020-02-23T13:04:35Z")

</div>

> [@Chrisir](#):
>
> record = dist; // YOU HAD dist = record; !!!

I know shame on me ;(

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 23, 2020, 1:21pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/10 "2020-02-23T13:21:22Z")

</div>

> [@Chrisir](#):
>
> if (record\<86) return idx; // give index of nearest target else return -1;

This is excellent thank you,

I will try to find some way to let start new walker when one die, get the walker to aim toward a direction, and not crossing the tail of another walker.

Thank you for your help.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 1:27pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/11 "2020-02-23T13:27:54Z")

</div>

> [@Chrisir](#):
>
> if (idx\<0)  
> return; // !!!

You can make here:

```auto
if (idx<0) {
    alive=false; 
    return; // !!!
}

```

when alive is a boolean inside the walker class

Then make a for loop to remove walkers with !alive (NOT alive), this for loop must go backward by the way

```auto
for(int i=walkers.size()-1; i>=0; i--) {
    Walker w=walkers.get(i); 
    if(!alive) 
        w.remove();
}

```

**3D version ================================**

HERE is a 3D version:

```auto

ArrayList<Walker> walkers;
ArrayList<Anchor> anchors;
ArrayList<Line> lines= new ArrayList<Line>();

PVector pos;

int walkerCount = 1;
int anchorCount = 1500;

float x = 0;
float y = 0;

float a; 

void setup() {
  size(1800, 900, P3D);
  background(51);

  //frameRate(69);

  walkers = new ArrayList<Walker>();
  anchors = new ArrayList<Anchor>();

  for (int i = 0; i < walkerCount; i++) {
    PVector origin = new PVector(random(4, 400), 4);
    walkers.add(new Walker(origin, color(random(256), random(256), random(256))));
  }

  for (int i = 0; i < anchorCount; i++) {
    PVector position = new PVector(random(-400, 400), random(4, height-4), random(-800, 800));
    anchors.add(new Anchor(position));
  }
}//setup()

void draw() {
  background(51);
  lights();

  translate(width/2, 0); 
  rotateY(a);
  a+=0.01; 

  for (Line l : lines) {
    l.show();
  }

  for (Walker w : walkers) { // !!!!!!!!!!!!!!!!!!!!!!!
    w.update(anchors);
    w.show();
  }

  for (int i = 0; i < anchors.size(); i++) {
    Anchor a = anchors.get(i); // (Anchor) anchors.get(i);
    a.show();
  }
}//draw()

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

class Walker {
  PVector pos;
  PVector previousPos;
  color col;

  // for lerp
  float amt;
  float amtAdd = 0.1;   
  boolean running=false;
  PVector move; 

  // ID of anchor
  int idx;

  Walker(PVector position, color c) {
    col = c;
    pos = position.copy(); 
    previousPos = pos.copy();
  }

  void show() {

    /*
    strokeWeight(2);
     stroke(col);
     point(pos.x, pos.y, pos.z);
     */

    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    noStroke();
    fill(col);
    sphere(14);
    popMatrix(); 

    /*
    strokeWeight(1);
     noFill();
     stroke(col); 
     ellipse(pos.x, pos.y, 8, 8);
     */

    /*
    strokeWeight(4);
     stroke(col);
     line(previousPos.x, previousPos.y, pos.x, pos.y);
     */
  }

  void update(ArrayList<Anchor> anchors) {

    //using lerp() !!! 

    if (anchors.size()>0) {

      if (running) {
        // lerping to the new pos
        pos.x=lerp(previousPos.x, move.x, amt);
        pos.y=lerp(previousPos.y, move.y, amt);
        pos.z=lerp(previousPos.z, move.z, amt);

        amt+=amtAdd;//.1;
        if (amt>1) {
          lines.add(new Line(previousPos, move)); 
          //reset 
          amt=0; 
          running=false;
          anchors.remove(idx);
        }
      } else {
        // find the new position and prepare lerp
        running=true; 

        idx = getNearest(anchors);
        // println(""+idx);

        Anchor a = anchors.get(idx);
        move = a.pos.copy();
        previousPos.set(pos);

        amtAdd = 1 / move.dist(pos) ;  
        amtAdd*=3; 
        // amtAdd = .5; 

        // pos.add(move); // WRONG 
        //pos=move.copy(); // OKAY
      }
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 100000;
    int idx = 0;
    for (int i = 0; i < anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < record) {
        record = dist; 
        idx = i;
      }
    }
    return idx; // give index of nearest target
  }
}

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

class Anchor {
  PVector pos;
  color col;

  Anchor(PVector position) {
    col = color(0);
    pos = position.copy();
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    point(pos.x, pos.y, pos.z);
  }

  void update() {
  }
}
//======================================================================================================

class Line {
  PVector f;
  PVector t;
  Line(PVector f_, PVector t_) { 
    f=f_.copy(); 
    t=t_.copy();
  }

  void show() {
    Walker w = walkers.get(0);
    stroke(w.col);
    line(f.x, f.y, f.z, 
      t.x, t.y, t.z );
  }
}//class
//

```

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 23, 2020, 1:41pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/12 "2020-02-23T13:41:53Z")

</div>

> [@Chrisir](#):
>
> HERE is a 3D version

Here, you blow my mind hehe,  
Thank you, I will update 🙂

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 23, 2020, 2:47pm UTC](https://discourse.processing.org/t/random-walker-through-points/18040/13 "2020-02-23T14:47:29Z")

</div>

The 3D idea will not work with your plans to stop a walker when crossing another line though

Better stay 2D…

See [Vector math for line-to-line intersection](https://discourse.processing.org/t/vector-math-for-line-to-line-intersection/5296)

> [@Vector math for line-to-line intersection](https://discourse.processing.org/t/vector-math-for-line-to-line-intersection/5296):
>
> While learning about vectors, I worked through this to better understand line-to-line intersection math instead of simply using it “because it works”. final int N = 4; // Fixed number to make two segments int MAX\_DIST = 20; // Control points PVector[] p = new PVector[N]; boolean held = false; int nearest = -1; float startx = 0; float starty = 0; float DIV\_TOO\_FAR = 0.00001; // Calculates the intersection with vectors. // Surely this uses the same math as solving the equations. // Input: // …

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 26, 2020, 9:19am UTC](https://discourse.processing.org/t/random-walker-through-points/18040/14 "2020-02-26T09:19:19Z")

</div>

Hi Chrisir, thank you for your advice. I like what the lerp() does to the motion.

My goal is to uses this logic to fill 3d Mesh. Here is the version I updated, there is probably still some problem but, it is already very interesting.

```auto
ArrayList<Walker> walkers;
ArrayList<Anchor> anchors;
ArrayList<Line> lines= new ArrayList<Line>();

PVector pos;

int walkerCount = 1;
int anchorCount = 1500;

float x = 0;
float y = 0;

float a; 

void setup() {
  size(800, 800);
  background(51);

  frameRate(60);

  walkers = new ArrayList<Walker>();
  anchors = new ArrayList<Anchor>();

  for (int i = 0; i < anchorCount; i++) {
    PVector position = new PVector(random(width), random(height));
    anchors.add(new Anchor(position));
  }

  for (int i = 0; i < walkerCount; i++) {
    int idx = (int)random(anchors.size());
    Anchor origin = anchors.get(idx);
    PVector originVec = origin.pos;
    walkers.add(new Walker(originVec, color(random(256), random(256), random(256))));
    anchors.remove(idx);
  }
}

void draw() {
  background(51);

  for (int i = 0; i < anchors.size(); i++) {
    Anchor a = anchors.get(i); // (Anchor) anchors.get(i);
    a.show();
  }

  for (int i = walkers.size()-1; i >= 0; i--) {
    Walker w = walkers.get(i);

    w.update(anchors);
    w.show();

    if (w.alive == false && walkers.size() <= walkerCount) {
      addWalker(anchors);
      walkers.remove(i);
    }
    println("walkers"+walkers.size());
  }

  for (Line l : lines) {
    l.show();
  }
}//draw()

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

void addWalker(ArrayList<Anchor> anchors) {
  int idx = (int)random(anchors.size());
  Anchor o = anchors.get(idx);
  PVector originVec = o.pos;
  walkers.add(new Walker(originVec, color(random(256), random(256), random(256))));
  anchors.remove(idx);
}

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

class Walker {
  PVector pos;
  PVector previousPos;
  color col;

  // for lerp
  float amt;
  float amtAdd = 0.1;   
  boolean running = false;
  boolean alive;
  PVector move; 

  // ID of anchor
  int idx;

  Walker(PVector position, color c) {
    alive = true;
    col = c;
    pos = position.copy(); 
    previousPos = pos.copy();
  }

  void show() {

    pushMatrix();
    noStroke();
    fill(col);
    ellipse(pos.x, pos.y, 8, 8);
    popMatrix();
  }

  void update(ArrayList<Anchor> anchors) {

    if (anchors.size() > 0) {

      if (running) {

        idx = getNearest(anchors);
        pos.x = lerp(previousPos.x, move.x, amt);
        pos.y = lerp(previousPos.y, move.y, amt);

        amt += amtAdd;//.1;

        if (amt > 1) {
          lines.add(new Line(previousPos, pos, col)); 
          amt = 0; //reset 
          running = false;
          
        }
      } else {
        // find the new position and prepare lerp
        running=true; 

        idx = getNearest(anchors);
        // println(""+idx);

        if (idx < 0) {
          alive = false;
          return;
        }

        Anchor a = anchors.get(idx);
        move = a.pos.copy();
        previousPos.set(pos);

        amtAdd = 1 / move.dist(pos) ;  
        amtAdd*=3;
        anchors.remove(idx);
      }
    }
  }

  int getNearest(ArrayList<Anchor> anchors) {
    float record = 100000;
    int idx = 0;
    for (int i = 0; i < anchors.size(); i++) {
      Anchor anchor = anchors.get(i);
      float dist = pos.dist(anchor.pos);
      if (dist < 30) {
        if (dist < record) {
          record = dist; 
          idx = i;
        }
      }
    }
    if (record<30) 
      return idx; // give index of nearest target
    else 
    return -1;
  }
}

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

class Anchor {
  PVector pos;
  color col;

  Anchor(PVector position) {
    col = color(0);
    pos = position.copy();
  }

  void show() {
    strokeWeight(4);
    stroke(col);
    point(pos.x, pos.y);
  }

  void update() {
  }
}

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

class Line {
  PVector f;
  PVector t;
  color col;
  
  Line(PVector f_, PVector t_, color inCol){ 
    f=f_.copy(); 
    t=t_.copy();
    col = inCol;
  }

  void show() {
    stroke(col);
    strokeWeight(3);
    line(f.x, f.y, t.x, t.y );
  }
}

```

Thank’s again.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 26, 2020, 9:37am UTC](https://discourse.processing.org/t/random-walker-through-points/18040/15 "2020-02-26T09:37:38Z")

</div>

lights(); are often nice in 3D

There is a bigger 3D line [https://github.com/Kango/3DSketches/wiki](https://github.com/Kango/3DSketches/wiki)

Do you know Peasycam? It allows you to look freely on a 3D sculpture

---

<div class="post-metadata">

**Author:** ![Giyomu](https://avatars.discourse-cdn.com/v4/letter/g/b19c9b/32.png) [@Giyomu](https://discourse.processing.org/u/Giyomu)\
**Post date:** [February 26, 2020, 10:50am UTC](https://discourse.processing.org/t/random-walker-through-points/18040/16 "2020-02-26T10:50:30Z")

</div>

Just discover it now, it’s all new to me, I am a grasshopper user by trade. I’ll try it later for sure!
