# 3D walker in a 3D grid / cube: what are the directions he can go to?

**URL:** <https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419>\
**Category:** Coding Questions\
**Created:** [October 7, 2020, 9:36pm UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419 "2020-10-07T21:36:41Z")\
**Posts on this page:** 9\
**Page:** 1

<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:** [October 7, 2020, 9:36pm UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/1 "2020-10-07T21:36:41Z")

</div>

Hello all,

I was doing a 3D walker in a 3D-grid.

What are the directions he can go to?

I plan to have a list of PVectors and depending which one is active, we add it to his position again and again so he moves in that direction.

I just want the list of possible directions to be complete.

He can go towards x, towards y, towards z,  
but also towards -x, towards -y, towards -z,

But then also diagonal…

I came up with the list.  
Is it complete? Or redundant?

Thank you!

Warm regards,

Chrisir 😉

```auto

  PVector[] pvList = {
    new PVector (0, 0, 1), 
    new PVector (0, 1, 0), 
    new PVector (1, 0, 0), 

    new PVector (1, 0, 1), 
    new PVector (1, 1, 0), 
    new PVector (0, 1, 1), 

    new PVector (1, 1, 1), 

    //---

    new PVector (0, 0, -1), 
    new PVector (0, -1, 0), 
    new PVector (-1, 0, 0), 

    new PVector (-1, 0, -1), 
    new PVector (-1, -1, 0), 
    new PVector (0, -1, -1), 

    new PVector (-1, -1, -1)

    
  };

```

---

<div class="post-metadata">

**Author:** ![SamuelCobb](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@SamuelCobb](https://discourse.processing.org/u/SamuelCobb)\
**Post date:** [October 8, 2020, 12:22am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/2 "2020-10-08T00:22:46Z")

</div>

That list is correct.

There’s probably a fancy technique that you could use, but what you have is pretty much perfect.

---

<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:** [October 8, 2020, 6:06am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/3 "2020-10-08T06:06:12Z")

</div>

No, it’s not complete

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [October 8, 2020, 6:33am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/4 "2020-10-08T06:33:30Z")

</div>

Hello,

Here is a ternary count which gives 3^3 = 27 counts:

```auto
PVector[] pvList1 = 
    {  
    new PVector ( 0, 0, 0), // This can be removed
    new PVector ( 0, 0, 1), // forward
    new PVector ( 0, 0, 2), // reverse
    new PVector ( 0, 1, 0),   
    new PVector ( 0, 1, 1), 
    new PVector ( 0, 1, 2),     
    new PVector ( 0, 2, 0),   
    new PVector ( 0, 2, 1), 
    new PVector ( 0, 2, 2),   

    new PVector ( 1, 0, 0),   
    new PVector ( 1, 0, 1), 
    new PVector ( 1, 0, 2), 
    new PVector ( 1, 1, 0),   
    new PVector ( 1, 1, 1), 
    new PVector ( 1, 1, 2),     
    new PVector ( 1, 2, 0),   
    new PVector ( 1, 2, 1), 
    new PVector ( 1, 2, 2),      
    
    new PVector ( 2, 0, 0),   
    new PVector ( 2, 0, 1), 
    new PVector ( 2, 0, 2), 
    new PVector ( 2, 1, 0),   
    new PVector ( 2, 1, 1), 
    new PVector ( 2, 1, 2),     
    new PVector ( 2, 2, 0),   
    new PVector ( 2, 2, 1), 
    new PVector ( 2, 2, 2),  
    };

```

Replace all the 2’s with -1’s and you have a complete list that you can iterate down to what you want to use.

_[https://en.wikipedia.org/wiki/Ternary\_numeral\_system](https://en.wikipedia.org/wiki/Ternary_numeral_system)_

`:)`

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

---

<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:** [October 8, 2020, 7:03am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/5 "2020-10-08T07:03:30Z")

</div>

Impressive.

I personally thought my list was for example

1,1,1

and

-1,-1,-1

but not

-1,1,-1

So not complete.

But I could not figure it out

Thank you!!

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:** [October 8, 2020, 7:15am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/6 "2020-10-08T07:15:47Z")

</div>

here is it with -1

```auto
 PVector[] pvList = 
    {  
    // new PVector ( 0, 0, 0), // This can be removed
    new PVector ( 0, 0, 1), // forward
    new PVector ( 0, 0, -1), // reverse
    new PVector ( 0, 1, 0), 
    new PVector ( 0, 1, 1), 
    new PVector ( 0, 1, -1), 
    new PVector ( 0, -1, 0), 
    new PVector ( 0, -1, 1), 
    new PVector ( 0, -1, -1), 

    new PVector ( 1, 0, 0), 
    new PVector ( 1, 0, 1), 
    new PVector ( 1, 0, -1), 
    new PVector ( 1, 1, 0), 
    new PVector ( 1, 1, 1), 
    new PVector ( 1, 1, -1), 
    new PVector ( 1, -1, 0), 
    new PVector ( 1, -1, 1), 
    new PVector ( 1, -1, -1), 

    new PVector ( -1, 0, 0), 
    new PVector ( -1, 0, 1), 
    new PVector ( -1, 0, -1), 
    new PVector ( -1, 1, 0), 
    new PVector ( -1, 1, 1), 
    new PVector ( -1, 1, -1), 
    new PVector ( -1, -1, 0), 
    new PVector ( -1, -1, 1), 
    new PVector ( -1, -1, -1), 
  };

```

---

<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:** [October 8, 2020, 8:46am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/7 "2020-10-08T08:46:33Z")

</div>

You must have put a lot of work in this

How did you make the list? Not by hand I guess. But with code.

How did you make the 3D graphic as a demonstration?

It’s an awesome post.

Reminds me of the discussion and your post here by the way: [Iterate once and only once through all the possible configurations of an array](https://discourse.processing.org/t/iterate-once-and-only-once-through-all-the-possible-configurations-of-an-array/22366/12)

---

<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:** [October 8, 2020, 9:41am UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/8 "2020-10-08T09:41:46Z")

</div>

ah, the code to generate the list could be:

```auto

size(300, 300); 

println("PVector[] pvList1 = "); 
println(" {" );

for (int i0 = 0; i0 < 3; i0++) { 
  for (int i1 = 0; i1 < 3; i1++) { 
    for (int i2 = 0; i2 < 3; i2++) { 
      //String a = str(i0)
      // +str(i1)
      // +str(i2);
      println(
        " new PVector ( "  
        + str(i0)+", "
        +str(i1)+", "
        +str(i2)
        +" ),");
    }//for
  }
}

println("};");

```

and the code to demonstrate the list as a graphic

```auto

float angle1; 

// auto-generated list of 3D PVectors for all possible directions in 3D (right, left, up, diagonal right downwards....)
PVector[] pvList1 = 
  {
  // new PVector ( 0, 0, 0 ), 
  new PVector ( 0, 0, 1 ), 
  new PVector ( 0, 0, -1 ), 
  new PVector ( 0, 1, 0 ), 
  new PVector ( 0, 1, 1 ), 
  new PVector ( 0, 1, -1 ), 
  new PVector ( 0, -1, 0 ), 
  new PVector ( 0, -1, 1 ), 
  new PVector ( 0, -1, -1 ), 
  new PVector ( 1, 0, 0 ), 
  new PVector ( 1, 0, 1 ), 
  new PVector ( 1, 0, -1 ), 
  new PVector ( 1, 1, 0 ), 
  new PVector ( 1, 1, 1 ), 
  new PVector ( 1, 1, -1 ), 
  new PVector ( 1, -1, 0 ), 
  new PVector ( 1, -1, 1 ), 
  new PVector ( 1, -1, -1 ), 
  new PVector ( -1, 0, 0 ), 
  new PVector ( -1, 0, 1 ), 
  new PVector ( -1, 0, -1 ), 
  new PVector ( -1, 1, 0 ), 
  new PVector ( -1, 1, 1 ), 
  new PVector ( -1, 1, -1 ), 
  new PVector ( -1, -1, 0 ), 
  new PVector ( -1, -1, 1 ), 
  new PVector ( -1, -1, -1 ) 
};

void setup() {
  // init
  size(800, 600, P3D);
} // func 

void draw() {
  // runs on and on 
  background(0);
  lights();

  stroke(255, 0, 0);
  strokeWeight(8);

  pushMatrix();
  translate(width/2, height/2, 0);
  rotateX(-0.2992);
  rotateY(angle1); 

  int i=0; 
  for (PVector pv : pvList1) {
    float amt = map(i, 
      0, pvList1.length, 
      0, 1);
    stroke(lerpColor(color(255), color(255, 0, 0), amt));
    line(
      //0, 0, 0, 
      pv.x*8, pv.y*8, pv.z*8, 
      pv.x*88, pv.y*88, pv.z*88);
    i++;
  }//for
  popMatrix();
  //

  stroke(100); 
  // noFill();
  fill(255, 0, 0);

  pushMatrix();
  translate(100, 100, 0);
  rotateZ(angle1);
  if (!keyPressed)
    angle1+=.04; 
  box(60);
  popMatrix();

  pushMatrix();
  translate(400, 100, 0); 
  rotateX(angle1);
  fill(0, 0, 255);
  box(60);
  popMatrix();

  pushMatrix();
  translate(700, 100, 0);
  rotateY(angle1);
  box(60);
  popMatrix();

  pushMatrix();
  translate(700, 300, -330);
  noStroke(); 
  sphere(50);
  popMatrix();
} // func 
//

```

Thank you!

Very inspiring!

---

<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:** [December 15, 2023, 11:43pm UTC](https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419/9 "2023-12-15T23:43:53Z")

</div>

I did some house cleaning (refactoring) and post a new version

Chrisir

```auto

// Demo for a **graphical representation** of a list of PVectors that represent the directions you can go in a 3D grid (like L/R and up/down and diagonal etc.):
// in the upper etage 9 directions, in the lower etage 9 directions and in the same plane (middle etage) 8 directions. This gives you 9+9+8 = 26 directions (without vector 0,0,0 itself of course).
// cf. https://discourse.processing.org/t/3d-walker-in-a-3d-grid-cube-what-are-the-directions-he-can-go-to/24419

// (I used this in a 3D Tic-Tac-Toe Game to find all possible lines (of 3 cells) in the 3D-board (grid) you can **win** in (these indices / lines are NOT what is shown here).)

// auto-generated list of 3D PVectors for all possible directions in 3D (right, left, up, diagonal right downwards....)
PVector[] pvList = {
  // new PVector ( 0, 0, 0 ),
  new PVector ( 0, 0, 1 ),
  new PVector ( 0, 0, -1 ),
  new PVector ( 0, 1, 0 ),
  new PVector ( 0, 1, 1 ),
  new PVector ( 0, 1, -1 ),
  new PVector ( 0, -1, 0 ),
  new PVector ( 0, -1, 1 ),
  new PVector ( 0, -1, -1 ),
  new PVector ( 1, 0, 0 ),
  new PVector ( 1, 0, 1 ),
  new PVector ( 1, 0, -1 ),
  new PVector ( 1, 1, 0 ),
  new PVector ( 1, 1, 1 ),
  new PVector ( 1, 1, -1 ),
  new PVector ( 1, -1, 0 ),
  new PVector ( 1, -1, 1 ),
  new PVector ( 1, -1, -1 ),
  new PVector ( -1, 0, 0 ),
  new PVector ( -1, 0, 1 ),
  new PVector ( -1, 0, -1 ),
  new PVector ( -1, 1, 0 ),
  new PVector ( -1, 1, 1 ),
  new PVector ( -1, 1, -1 ),
  new PVector ( -1, -1, 0 ),
  new PVector ( -1, -1, 1 ),
  new PVector ( -1, -1, -1 )
};

// old wrong version for comparison
PVector[] pvList_OLD = {
  new PVector (0, 0, 1),
  new PVector (0, 1, 0),
  new PVector (1, 0, 0),

  new PVector (1, 0, 1),
  new PVector (1, 1, 0),
  new PVector (0, 1, 1),

  new PVector (1, 1, 1),

  //---

  new PVector (0, 0, -1),
  new PVector (0, -1, 0),
  new PVector (-1, 0, 0),

  new PVector (-1, 0, -1),
  new PVector (-1, -1, 0),
  new PVector (0, -1, -1),

  new PVector (-1, -1, -1)
};

// rotate the object
float angleRotate;

// -----------------------------------------------------------------------------------------------

void setup() {
  size(1800, 900, P3D);
  textSize(19);
  textMode(SHAPE);
  println("Number of directions: "+pvList.length);
} // func

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

  showListOfPVectors(pvList);

  if (! keyPressed) // stop rotation with any key 
    angleRotate += 0.004;

  decoration();
} // func

// -----------------------------------------------------------------------------------------------

void showListOfPVectors(PVector[] pvList_) {
  // prepare scene
  pushMatrix();
  translate(width/2, height/2, 0);
  rotateX(-0.2992);
  rotateY(angleRotate); // rotate animation 

  // loop over the list
  int i=0;
  for (PVector pv : pvList_) {
    showThisVector(pv, i); // show one PVector 
    i++;
  }//for

  // reset
  popMatrix();
}

void showThisVector(PVector pv_, int intNumber_) {
  float lengthLine = 188;

  // calc color for this vector 
  float amt = map(intNumber_,
    0, pvList.length,
    0, 1);
  color colLine3d = lerpColor(color(255), color(255, 0, 0), amt);

  // draw pv_ as a 3D line
  line3D(
    pv_.copy().mult(8),
    pv_.copy().mult(lengthLine),
    16,
    colLine3d,
    intNumber_);
}

void line3D(PVector pv1_,
  PVector pv2_,
  float weight_,
  color color_,
  int intNumber_) {
  // draws a 3D-Line from pv1_ TO pv2_ with thickness weight_ and color color_
  // and shows a number intNumber_ at its end.

  // Was called drawLine; programmed by James Carruthers, modified,
  // see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
  PVector v1 = new PVector(pv2_.x-pv1_.x, pv2_.y-pv1_.y, pv2_.z-pv1_.z);
  float rho = sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z);
  float phi = acos(v1.z/rho);
  float the = atan2(v1.y, v1.x);
  v1.mult(0.5);

  // The line
  pushMatrix();
  translate(pv1_.x, pv1_.y, pv1_.z);
  translate(v1.x, v1.y, v1.z);
  rotateZ(the);
  rotateY(phi);
  // noStroke();
  stroke(0);
  fill(color_);
  // box(weight,weight,p1.dist(p2)*1.2);
  box(weight_, weight_, pv1_.dist(pv2_)*1.0);
  popMatrix();

  // The text (optional)
  pushMatrix();
  float yAdd = -21;// for the 2 upper etages we push intNumber_ up by 21
  if (pv2_.y > height/2.0-300) {
    yAdd = 23; // for the lower etage we push intNumber_ down by 23
  }
  translate( pv2_.x+21, pv2_.y + yAdd, pv2_.z-21);
  rotateY(-angleRotate);// rotate towards camera
  fill(255);
  text(intNumber_, 0, 0);
  popMatrix();
}

// -----------------------------------------------------------------------------------------------

void decoration() {
  stroke(100);
  fill(255, 0, 0);

  pushMatrix();
  translate(100, 100, 0);
  rotateZ(angleRotate);
  box(60);
  popMatrix();

  pushMatrix();
  translate(400, 100, 0);
  rotateX(angleRotate);
  fill(0, 0, 255);
  box(60);
  popMatrix();

  pushMatrix();
  translate(700, 100, 0);
  rotateY(angleRotate);
  box(60);
  popMatrix();

  pushMatrix();
  translate(1000, 100, -30);
  noStroke();
  sphere(50);
  popMatrix();
}
//

```
