# Animated conveyor belt

**URL:** <https://discourse.processing.org/t/animated-conveyor-belt/2060>\
**Category:** Coding Questions\
**Created:** [July 25, 2018, 4:06am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060 "2018-07-25T04:06:06Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Groot](https://avatars.discourse-cdn.com/v4/letter/g/82dd89/32.png) [@Groot](https://discourse.processing.org/u/Groot)\
**Post date:** [July 25, 2018, 4:06am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/1 "2018-07-25T04:06:06Z")

</div>

Hi all,

so i have searched the net and cant find an example anywhere and a bit lost as where to start.

I want to loop through an array and each time create a bar plot.

each new bar (3d rect/box) is brought to the front of the screen whilst the previous bars stay on the screen, but will be behind the new one. i can rotate the visualization so that i will be able to see all bars. essentially it will be like having the 3d bars on a conveyor belt.

sorry i cant provide any code or example. Any help is much appreciated.

thanks

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 25, 2018, 5:30am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/2 "2018-07-25T05:30:34Z")

</div>

Start with a blank 3D sketch that does nothing.

```auto
void setup(){
  size(600,400,P3D);
}

void draw(){
  background(0);
}

```

This is, of course, very boring. But it works! If we add or change something to this and it stops working, we’ll know where the problem is.

Next, let’s add a box. Because we want the box to be in the middle of the screen, let’s move the origin to the middle and then draw out box.

```auto
void setup(){
  size(600,400,P3D);
}

void draw(){
  background(0);
  translate(width/2,height/2);
  box(10);
}

```

Great, we can see the box. But is it a box or a rect? Let’s use the mouse to move it about a bit, throw in some lights, and make the box bigger.

```auto
void setup(){
  size(600,400,P3D);
  noStroke();
}

void draw(){
  background(0);
  translate(width/2,height/2);
  lights();
  rotateY(map(mouseX, 0, width, -PI,PI));
  rotateX(map(mouseY, 0, height, -PI,PI));
  box(60);
}

```

So we can do 3D boxes. Great. Now we know we’re going to need more than one box, right? So it makes sense to turn our one box example into a one box example that uses a class.

So the next step is to write a class for a single object.

```auto
class SingleBar {
  float px, py, pz;
  float sx, sy, sz;
  color c;
  SingleBar(float ipx, float ipy, float ipz, float h) {
    px = ipx;
    py = ipy;
    pz = ipz;
    sx = sy = sz = 60;
    c = color( random(255), random(255), random(255) );
  } 
  void draw() {
    pushMatrix();
    translate(px, py, pz);
    fill(c);
    box(sx, sy, sz);
    popMatrix();
  }
}

SingleBar sb0 = new SingleBar(0, 0, 0, 100);

void setup() {
  size(600, 400, P3D);
  noStroke();
}

void draw() {
  background(0);
  translate(width/2, height/2);
  lights();
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(map(mouseY, 0, height, -PI, PI));
  sb0.draw();
}

```

Looks basically the same, right? Good!

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 25, 2018, 5:34am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/3 "2018-07-25T05:34:45Z")

</div>

The point of writing a class is so that we can easily have many boxes. Like so:

```auto
class SingleBar {
  float px, py, pz;
  float sx, sy, sz;
  color c;
  SingleBar(float ipx, float ipy, float ipz, float h) {
    px = ipx;
    py = ipy;
    pz = ipz;
    sx = sy = sz = 60;
    c = color( random(255), random(255), random(255) );
  } 
  void draw() {
    pushMatrix();
    translate(px, py, pz);
    fill(c);
    box(sx, sy, sz);
    popMatrix();
  }
}

SingleBar[] sbs = new SingleBar[10];

void setup() {
  size(600, 400, P3D);
  noStroke();
  for( int i = 0; i< sbs.length; i++){
    sbs[i] = new SingleBar(0, 0, -60*i, 30*i);
  }
}

void draw() {
  background(0);
  translate(width/2, height/2);
  lights();
  rotateY(map(mouseX, 0, width, -PI, PI));
  //rotateX(map(mouseY, 0, height, -PI, PI));
  for( int i = 0; i< sbs.length; i++){
    sbs[i].draw();
  }
}

```

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 25, 2018, 5:55am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/4 "2018-07-25T05:55:31Z")

</div>

A few more tweeks now. Change to using an ArrayList so we can push new objects easier. Remove the initial objects. Add a mousePressed function that puts in a new bar when the mouse is clicked. Adjust a few values for rotations and positions. Look! It’s almost like they’re scrolling now!

```auto
class SingleBar {
  float px, py, pz;
  float sx, sy, sz;
  color c;
  SingleBar(float ipx, float ipy, float ipz, float h) {
    px = ipx;
    py = ipy;
    pz = ipz;
    sx = sz = 60;
    sy = h;
    c = color( random(255), random(255), random(255) );
  } 
  void draw() {
    pushMatrix();
    translate(px, py, pz);
    translate(0,-sy/2,0);
    fill(c);
    box(sx, sy, sz);
    popMatrix();
  }
}

ArrayList<SingleBar> sbs = new ArrayList();//SingleBar[10];

void setup() {
  size(600, 400, P3D);
  noStroke();
}

void draw() {
  background(0);
  translate(width/2, height/2);
  lights();
  rotateY(-map(mouseX, 0, width, -HALF_PI, HALF_PI));
  //rotateX(map(mouseY, 0, height, -PI, PI));
  for( int i = 0; i< sbs.size(); i++){
    sbs.get(i).draw();
    translate(0,0,-60);
  }
}

void mousePressed(){
  sbs.add( 0, new SingleBar(0, 170, 0, random(60,300)) );
}

```

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 25, 2018, 6:04am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/5 "2018-07-25T06:04:13Z")

</div>

More tweeks! Add an offset that is the amount that the boxes have shifted down by. If that offset is enough for a new box, add one and adjust the offset. Remove boxes if there are too many.

```auto
class SingleBar {
  float px, py, pz;
  float sx, sy, sz;
  color c;
  SingleBar(float ipx, float ipy, float ipz, float h) {
    px = ipx;
    py = ipy;
    pz = ipz;
    sx = sz = 60;
    sy = h;
    c = color( random(255), random(255), random(255) );
  } 
  void draw() {
    pushMatrix();
    translate(px, py, pz);
    translate(0,-sy/2,0);
    fill(c);
    box(sx, sy, sz);
    popMatrix();
  }
}

ArrayList<SingleBar> sbs = new ArrayList();//SingleBar[10];
int offset = 0;
final int OFFSET_SPEED = 6;
final int MAX_BARS = 300;

void setup() {
  size(600, 400, P3D);
  noStroke();
}

void draw() {
  if( sbs.size() > MAX_BARS ){
    sbs.remove(sbs.size()-1);
  }
  background(0);
  translate(width/2, height/2);
  lights();
  rotateY(-map(mouseX, 0, width, -HALF_PI, HALF_PI));
  //rotateX(map(mouseY, 0, height, -PI, PI));
  translate(0,0,-offset);
  for( int i = 0; i< sbs.size(); i++){
    sbs.get(i).draw();
    translate(0,0,-60);
  }
  if( offset > 60 ){
    offset %= 60;
    sbs.add( 0, new SingleBar(0, 170, 0, random(60,300)) );
  }
  offset+=OFFSET_SPEED;
}

```

---

<div class="post-metadata">

**Author:** ![Groot](https://avatars.discourse-cdn.com/v4/letter/g/82dd89/32.png) [@Groot](https://discourse.processing.org/u/Groot)\
**Post date:** [July 25, 2018, 12:36pm UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/6 "2018-07-25T12:36:20Z")

</div>

Thank you - huge help and thanks for explaining the steps.

further to the above -i wanted to add a second column of bars, to highlight i did this by changing the code such that:

for( int i = 0; i\< sbs2.size(); i++){  
sbs2.get(i).draw();  
pushMatrix();  
translate(-100,0,0);  
sbs2.get(i).draw();  
popMatrix();  
translate(0,0,-60);  
}

if( offset \> 60 ){  
offset %= 60;  
sbs2.add( 0, new SingleBar(0, 170, 0, random(60,300)) );  
}  
offset+=OFFSET\_SPEED;  
}…

However, i need the height of the second row of bars to be different to the other. ive tried numerous ways but think the code gets stuck in the loop when generating the first row.

do i have to crate a second variable, sbs2? if so how do i then add data to this?

Thanks again.

Jared

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 25, 2018, 7:56pm UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/7 "2018-07-25T19:56:35Z")

</div>

Alright, you got me. I cheated you a bit. While each of my bars has a full (x,y,z) position, it isn’t making use of it at all. The bars move because of a translate in the loop that is drawing them. This is not ideal. So the first thing to fix would be to have each bar store and use a real position in 3D space. I got that working, then I just made it so that more than one bar are added at once.

```auto
class SingleBar {
  float px, py, pz;
  float sx, sy, sz;
  color c;
  SingleBar(float ipx, float ipy, float ipz, float h) {
    px = ipx;
    py = ipy;
    pz = ipz;
    sx = sz = 60;
    sy = h;
    c = color( random(255), random(255), random(255) );
  } 
  void draw() {
    pushMatrix();
    translate(px, py, pz);
    translate(0,-sy/2,0);
    fill(c);
    box(sx, sy, sz);
    popMatrix();
  }
}

ArrayList<SingleBar> sbs = new ArrayList();//SingleBar[10];
int offset = 0;
final int OFFSET_SPEED = 6;
final int MAX_BARS = 300;
float atX = 0;
float atZ = 0;

void setup() {
  size(600, 400, P3D);
  noStroke();
}

void draw() {
  if( sbs.size() > MAX_BARS ){
    sbs.remove(sbs.size()-1);
  }
  background(0);
  translate(width/2, height/2);
  lights();
  rotateY(-map(mouseX, 0, width, -HALF_PI, HALF_PI));
  //rotateX(map(mouseY, 0, height, -PI, PI));
  translate(0,0,atZ-offset);
  for( int i = 0; i< sbs.size(); i++){
    sbs.get(i).draw();
  }
  if( offset > 60 ){
    atZ -= 60;
    offset %= 60;
    for( int i = -1; i < 2; i+=2){
      sbs.add( 0, new SingleBar(30*i, 170, -atZ, random(60,300)) );
    }
  }
  offset+=OFFSET_SPEED;
}

```

---

<div class="post-metadata">

**Author:** ![Groot](https://avatars.discourse-cdn.com/v4/letter/g/82dd89/32.png) [@Groot](https://discourse.processing.org/u/Groot)\
**Post date:** [July 26, 2018, 12:18pm UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/8 "2018-07-26T12:18:10Z")

</div>

Hey - Thanks again - your help is much appreciated. i under estimated the time it would take me to pick this up.

I have slightly modified the code - i wanted to create a few more bar plots. In doing so, im not exactly sure what to call it, but the red image is not as clear as the blue, im not sure what is causing this. Also, the height of sbs3 is not as random as sbs2/1. Any ideas would be great - but again, thanks for all the help you have provided.

class SingleBar {  
float px, py, pz;  
float sx, sy, sz;  
color c;  
SingleBar(float ipx, float ipy, float ipz, float h) {  
px = ipx;  
py = ipy;  
pz = ipz;  
sx = sz = 60;  
sy = h;  
c = color( 0,0,255,20);  
}  
void draw() {  
pushMatrix();  
translate(px, py, pz);  
translate(0,-sy/2,0);  
fill©;  
box(sx, sy, sz);  
popMatrix();  
}  
}

class SingleBar2 {  
float px, py, pz;  
float sx, sy, sz;  
color c;  
SingleBar2(float ipx, float ipy, float ipz, float h) {  
px = ipx;  
py = ipy;  
pz = ipz;  
sx = sz = 60;  
sy = h;  
c = color( 255,0,0,20);  
}  
void draw() {  
pushMatrix();  
translate(px, py, pz);  
translate(0,-sy/2,0);  
fill©;  
box(sx, sy, sz);  
popMatrix();  
}  
}

class SingleBar3 {  
float px, py, pz;  
float sx, sy, sz;  
color c;  
SingleBar3(float ipx, float ipy, float ipz, float h) {  
px = ipx;  
py = ipy;  
pz = ipz;  
sx = sz = 30;  
sy = h;  
c = color( 255,255,255,200);  
}  
void draw() {  
pushMatrix();  
translate(px, py, pz);  
translate(0,-sy/2,0);  
fill©;  
box(sx, sy, sz);  
popMatrix();  
}  
}

ArrayList sbs = new ArrayList();//SingleBar[10];  
ArrayList sbs2 = new ArrayList();//SingleBar[10];  
ArrayList sbs3 = new ArrayList();//SingleBar[10];  
int offset = 0;  
final int OFFSET\_SPEED = 6;  
final int MAX\_BARS = 300;  
float atX = 0;  
float atZ = 0;

void setup() {  
size(1000, 1000, P3D);  
noStroke();  
}

void draw() {  
background(0);

translate(width/2, height/2);  
lights();  
rotateY(-map(mouseX, 0, width, -HALF\_PI, HALF\_PI));  
rotateX(map(mouseY, 0, height, -PI, PI));  
translate(0,0,atZ-offset);

for( int i = 0; i\< sbs.size(); i++){  
sbs.get(i).draw();  
}

pushMatrix();  
translate(-200,0,0);  
for( int j = 0; j\< sbs2.size(); j++){  
sbs2.get(j).draw();  
}  
popMatrix();

pushMatrix();  
translate(-75,0,0);  
for( int k = 0; k\< sbs3.size(); k++){  
sbs3.get(k).draw();  
}  
popMatrix();

if( offset \> 60 ){  
atZ -= 60;  
offset %= 60;  
for( int i = 1; i \< 10; i+=2){  
sbs.add( 0, new SingleBar(30\*i, 170, -atZ, random(60,300)) );

```
 for( int j = 1; j < 10; j+=2){
  sbs2.add( 0, new SingleBar2(-30*j, 170, -atZ, random(60,300)) );
  
  for( int k = 1; k < 2; k+=2){
  sbs3.add( 0, new SingleBar3(-15*k, 170, -atZ, random(0,75)) );
 
  }
}
  } }

```

offset+=OFFSET\_SPEED;  
}

---

<div class="post-metadata">

**Author:** ![Groot](https://avatars.discourse-cdn.com/v4/letter/g/82dd89/32.png) [@Groot](https://discourse.processing.org/u/Groot)\
**Post date:** [July 26, 2018, 12:32pm UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/9 "2018-07-26T12:32:31Z")

</div>

also re the above - everything has to be in that first if statement - anything past that does not run, if i take the offset% out it works, but then the visualisations obviously doesn’t run as smooth and isn’t aligned. im not sure why this is happening? Thanks in advance.

if( offset \> 60 ){  
atZ -= 60;  
offset %= 60;  
for( int i = 1; i \< 10; i+=2){  
sbs.add( 0, new SingleBar(30\*i, 170, -atZ, random(60,300)) );

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 26, 2018, 6:27pm UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/10 "2018-07-26T18:27:45Z")

</div>

Please edit your posts, select your code, and hit the format button, which looks like this: \</\>

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [July 26, 2018, 6:52pm UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/11 "2018-07-26T18:52:40Z")

</div>

The beauty of a class is that you can use one class for all sort of similar objects. You don’t need a seperate class for white bars and blue bars and red bars. You just need one class for bars, and then that class can remember which type of bar it is. There is no need for three copies of basically the same class.

The beauty of having a dynamic data structure such as an ArrayList is that is can hold all the objects you’re working with. There is no need for three copies of the same data structure.

The beauty of formatted code is that it allows you to see what level of depth your loops are taking place in. There is no need to put a loop in a loop in a loop in this instance.

Consider this code, which is basically the same but runs smoothly (because there is a lot less looping), and vastly simplier (because there has been a 66% reduction in number of classes and ArrayLists):

```auto
color[] colors = { 
  color(0, 0, 255, 200), 
  color(255, 0, 0, 200), 
  color(255, 255, 255, 200) 
}; 
int[] bases = {
  60, 
  60, 
  30
};

class SingleBar {
  float px, py, pz;
  float sx, sy, sz;
  color c;
  SingleBar(float ipx, float ipy, float ipz, float h, int type) {
    px = ipx;
    py = ipy;
    pz = ipz;
    sx = sz = bases[type];
    sy = h;
    c = colors[type];
  }
  void draw() {
    pushMatrix();
    translate(px, py, pz);
    translate(0, -sy/2, 0);
    fill(c);
    box(sx, sy, sz);
    popMatrix();
  }
}

ArrayList<SingleBar> sbs = new ArrayList();

int offset = 0;
final int OFFSET_SPEED = 6;
final int MAX_BARS = 300;
float atX = 0;
float atZ = 0;

void setup() {
  size(1000, 1000, P3D);
  noStroke();
}

void draw() {
  background(0);

  translate(width/2, height/2);
  lights();
  rotateY(-map(mouseX, 0, width, -HALF_PI, HALF_PI));
  rotateX(map(mouseY, 0, height, -PI, PI));
  translate(0, 0, atZ-offset);
  
  for ( int i = 0; i< sbs.size(); i++) {
    sbs.get(i).draw();
  }
  
  if ( offset > 60 ) {
    atZ -= 60;
    offset %= 60;
    for ( int i = 0; i < 5; i++) {
      sbs.add( 0, new SingleBar(60*i+140, height/3, -atZ, random(60, 300), 0) );
      sbs.add( 0, new SingleBar(-60*i-140, height/3, -atZ, random(60, 300), 1) );
    }
    sbs.add( 0, new SingleBar(0, height/3, -atZ, random(0, 75), 2) );
  }
  offset+=OFFSET_SPEED;
}

```

I also had to brighten up the red and blue bar colors because they were driving me crazy being as dark as they were. I also re-centered things.

---

<div class="post-metadata">

**Author:** ![Groot](https://avatars.discourse-cdn.com/v4/letter/g/82dd89/32.png) [@Groot](https://discourse.processing.org/u/Groot)\
**Post date:** [July 28, 2018, 10:32am UTC](https://discourse.processing.org/t/animated-conveyor-belt/2060/12 "2018-07-28T10:32:06Z")

</div>

Thank you very much… This was very helpful.

The bars are now running from left to right but i can adjust them with the arrows - so all good.

thanks again
