Arraylist in a draw function

Hi,

I am really new to processing. I am controlling my animations using OSC messages. I altered some code from one of the “create shapes” examples and I want to be able to control the number of items in an array list. I also want to be able to change the dimensions in the Pshape I made (called boxes), which is what is in the ArrayList. I would think that the create new ArrayList code would need to be in void draw() so I could use a variable and I could change it. As well as the code between beginShape() and endShape() so I could have variables for the verticies I want to change the dimensions to.

Right now I have those things in void setup(). If I put them in draw they draw new shapes every frame, which is not what I want.

If you look at the animation as it is now, this is how I want it to look, but I want to be able to control the number of boxes with a variable, and I want to be able to assign variables to some of the verticies in my Pshape called boxes.

I’ll put the code below. Any help, suggestions or input would be greatly appreciated.

thanks.

main code

import oscP5.*; 

OscP5 oscP5;

float ramp1=450;
float ramp2=100;
float ramp3=1;


ArrayList<Polygon> polygons;

void setup() {

  fullScreen(P3D);
  //  size(2700, 1500, P3D); 

  //background(0);
  oscP5 = new OscP5(this, 12000);

  PShape boxes = createShape();   //boxes is the name of my shape  
  boxes.beginShape();
  boxes.strokeWeight(1);
  boxes.stroke(0);

  boxes.noFill();


  //dimentions of base are 30X by 20 deep
  // sides are 50 Y by 30 X

  boxes.vertex(50, 50, 0);    // this is the square top
  boxes.vertex(20, 50, 0); 
  boxes.vertex(20, 50, -20); 
  boxes.vertex(50, 50, -20); 
  boxes.vertex(50, 50, 0); 

  boxes.vertex(70, 100, 0);   //front rectangle
  boxes.vertex(40, 100, 0); 
  boxes.vertex(20, 50, 0); 

  boxes.vertex(20, 50, -20); //back rectangle
  boxes.vertex(40, 100, -20); 
  boxes.vertex(70, 100, -20); 
  boxes.vertex(50, 50, -20); 

  boxes.vertex(50, 50, -20);  //close up bottom or middle square
  boxes.vertex(70, 100, -20); 
  boxes.vertex(70, 100, 0); 
  boxes.vertex(70, 100, 0);   
  boxes.vertex(40, 100, 0);
  boxes.vertex(40, 100, -20); 

  boxes.vertex(40, 100, -20);    //bottom back rectangle
  boxes.vertex(20, 150, -20); 
  boxes.vertex(50, 150, -20); 
  boxes.vertex(70, 100, -20); 

  boxes.vertex(70, 100, 0);   //front bottom rectangle
  boxes.vertex(50, 150, 0);
  boxes.vertex(20, 150, 0); 
  boxes.vertex(40, 100, 0);   

  boxes.vertex(20, 150, 0);   //bottom square
  boxes.vertex(20, 150, -20); 
  boxes.vertex(50, 150, -20); 
  boxes.vertex(50, 150, 0); 

  boxes.endShape();


  // Make an ArrayList
  polygons = new ArrayList<Polygon>();
  for (int i = 0; i < 200; i++) {
    polygons.add(new Polygon(boxes));
  }
}

void oscEvent(OscMessage theOscMessage) {    

  float value = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > 0.1) {
      ramp1 = value;
    } else {
      ramp1 = 0.0;
    }
  }
  float value2 = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp2")) {
    if (value2 > 0.1) {
      ramp2 = value2;
    } else {
      ramp2 = 0.0;
    }
  }

  float value3 = theOscMessage.get(0).floatValue();

  if (theOscMessage.checkAddrPattern("/ramp3")) {
    if (value3 > 0.1) {
      ramp3 = value3;
    } else {
      ramp3 = 0.0;
    }
  }
}

void draw() {

  background(255);


  stroke(0);               //  for the sphere
  strokeWeight(ramp3);
  translate(width/2, height/2, 0);
  //rotateX(mouseY * 0.05);
  rotateY(radians(ramp2));
  noFill();
  sphereDetail(30);
  sphere(ramp1);


 

  // Display and move them all
  for (Polygon poly : polygons) {
    poly.display();
    poly.move();

    println(ramp1);
  }
}

tab called Polygon

// A class to describe a Polygon (with a PShape)

class Polygon {
  // The PShape object
  PShape s;
  // The location where we will draw the shape
  float x, y, z;
  // Variable for simple motion

   float speed;
 

  Polygon(PShape s_) {
    x = random(-1000, 1000);
   y = random(1000, -1000); 
   z = random(-1000, 1000); 

    s = s_;
    speed = random(-1, 1);
  }

  // Simple motion
  void move() {
    y += speed;
    x += speed*1.2;
    z += speed*4;


    if (y > height) {
      y = -100;
    }


    if (y < -1000) {
      y = height;
    }

    if (x > width) {
      x = 0;
    }


    if (x > width) {
      x = -200;
    }

    if (z > 0) {
      z = -500;
    }


    if (z < -1000) {
      z = 0;
    }
  }

  // Draw the object
 void display() {
    pushMatrix();
    //size(P3D);
    fullScreen(P3D);
    translate(x, y, z);
    shape(s);
   popMatrix();
  }
}
1 Like

allow me to show you just a rewrite,
not say it is better, but for me, easy readable:

import oscP5.*; 
OscP5 oscP5;

float ramp1=450, ramp2=100, ramp3=1;
ArrayList<Polygon> polygons;
PShape boxes;
int many = 200;  // number of boxes in array

void setup() {
  //fullScreen(P3D);
  size(1000, 1000, P3D); 
  oscP5 = new OscP5(this, 12000);
  make_boxes();
  polygons = new ArrayList<Polygon>();  // Make an ArrayList
  for (int i = 0; i < many; i++)   polygons.add(new Polygon(boxes));
}

void draw() {
  background(255);
  draw_sphere();
  for (Polygon poly : polygons)   poly.display();// move and display them all
}

void oscEvent(OscMessage theOscMessage) {    
  float value = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > 0.1)   ramp1 = value;
    else               ramp1 = 0.0;
  }
  float value2 = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp2")) {
    if (value2 > 0.1)  ramp2 = value2;
    else               ramp2 = 0.0;
  }
  float value3 = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp3")) {
    if (value3 > 0.1)  ramp3 = value3;
    else               ramp3 = 0.0;
  }
}

void draw_sphere() {
  stroke(0);               //  for the sphere
  strokeWeight(ramp3);
  translate(width/2, height/2, 0);
  //rotateX(mouseY * 0.05);
  rotateY(radians(ramp2));
  noFill();
  sphereDetail(30);
  sphere(ramp1);
  println(ramp1); 
}

  //dimentions of base are 30X by 20 deep // sides are 50 Y by 30 X
int bw = 50, bw2 = 2*bw, bw3 = 3*bw, bh = 20, bh2 = 40, bh3 = 70, bz = 20;

void make_boxes() {
  boxes = createShape();   //boxes is the name of my shape  
  boxes.beginShape();
  boxes.strokeWeight(1);
  boxes.stroke(0);
  boxes.noFill();

  boxes.vertex(bw, bw, 0);    // this is the square top
  boxes.vertex(bh, bw, 0); 
  boxes.vertex(bh, bw, -bz); 
  boxes.vertex(bw, bw, -bz); 
  boxes.vertex(bw, bw, 0); 

  boxes.vertex(bh3, bw2, 0);   //front rectangle
  boxes.vertex(bh2, bw2, 0); 
  boxes.vertex(bh, bw, 0); 

  boxes.vertex(bh, bw, -bz); //back rectangle
  boxes.vertex(bh2, bw2, -bz); 
  boxes.vertex(bh3, bw2, -bz); 
  boxes.vertex(bw, bw, -bz); 

  boxes.vertex(bw, bw, -bz);  //close up bottom or middle square
  boxes.vertex(bh3, bw2, -bz); 
  boxes.vertex(bh3, bw2, 0); 
  boxes.vertex(bh3, bw2, 0);   
  boxes.vertex(bh2, bw2, 0);
  boxes.vertex(bh2, bw2, -bz); 

  boxes.vertex(bh2, bw2, -bz);    //bottom back rectangle
  boxes.vertex(bh, bw3, -bz); 
  boxes.vertex(bw, bw3, -bz); 
  boxes.vertex(bh3, bw2, -bz); 

  boxes.vertex(bh3, bw2, 0);   //front bottom rectangle
  boxes.vertex(bw, bw3, 0);
  boxes.vertex(bh, bw3, 0); 
  boxes.vertex(bh2, bw2, 0);   

  boxes.vertex(bh, bw3, 0);   //bottom square
  boxes.vertex(bh, bw3, -bz); 
  boxes.vertex(bw, bw3, -bz); 
  boxes.vertex(bw, bw3, 0); 

  boxes.endShape();
}

// A class to describe a Polygon (with a PShape)
class Polygon {
  PShape s;              // The PShape object
  float x, y, z;         // The location where we will draw the shape
  float speed;           // Variable for simple motion

  Polygon(PShape s_) {
    x = random(-1000, 1000);
    y = random(1000, -1000); 
    z = random(-1000, 1000); 
    s = s_;
    speed = random(-1, 1);
  }

  // Simple motion
  void move() {
    y += speed;
    x += speed*1.2;
    z += speed*4;
    if (y > height)  y = -100;
    if (y < -1000)   y = height;
    if (x > width)   x = 0;
    if (x > width)   x = -200;
    if (z > 0)       z = -500;
    if (z < -1000)   z = 0;
  }

  void display() {    // Draw the object
    pushMatrix();
    move();
    translate(x, y, z);
    shape(s);
    popMatrix();
  }
}

your question:
-a- number of elements in array list ( at runtime?)
you can make the whole array again, or just change the number you draw,
also can make a visible attribute in the class and use it inside display()
and write it ( show / hide ) on certain conditions.

-b- if the elements ( boxes shape ) need to be different,
they ( their size parameters ) need to be part of the class
and not like now ONE global shape.
BUT depending what you want to do, still there are ways to show ONE global shape in different ways, size, fill- stroke - color, angle …
https://processing.org/reference/PShape.html

-c- the variables ( here global ) for the boxes shape i give you already,
you could make them “knowledge” of the class to make each one different

2 Likes

kll,

Thanks for this reply. I learned a lot from your rewrite of the code. I didn’t know you could list all the float variables like that at the top, good to know.

Also, for animating the boxes, which I eventually want to do, I was thinking I would need the verticies as variables, so thank you for showing me an easy way to do that.

The thing that is really stumping me, and this has been a problem for many sketches I’m trying to make, is that I want something to happen once and in the void draw() function it gets redrawn every frame.

I want to be able to control the number of boxes that are in the animation, and have them float around the sphere as you have them in the code you posted.

I put this in draw:

int ramp4i = int(ramp4);
   
   if (many < ramp4){
     many = many +1;
   }
   else {              // maybe this else part doesn't make sense
     many = ramp4i;
   }
   
  for (int i = 0; i < many; i++)   polygons.add(new Polygon(boxes));
  
    for (Polygon poly : polygons)   poly.display();// move and display them all
    

ramp4 is a number I can send with OSC messages. I would think that if ramp4 was 1 it would make one box, if ramp4 was 2 it would make 2 boxes, etc.

Instead it is drawing these boxes new each time per frame. What I am trying to achieve is to draw them a certain number of times and let those float around. When I want more I can increase the ramp4 variable ( or some other controllable variable). I’ve been trying while loops and for loops too, but not finding this out.

If you have any suggestions please let me know.

Thank you so much for the input!

Here is the whole code that I tried out

import oscP5.*; 
OscP5 oscP5;

float ramp1=450, ramp2=100, ramp3=1, ramp4 = 1;
ArrayList<Polygon> polygons;
PShape boxes;
int many = 200;  // number of boxes in array

void setup() {
  //fullScreen(P3D);
  size(1000, 1000, P3D); 
  oscP5 = new OscP5(this, 12000);
  make_boxes();
 // polygons = new ArrayList<Polygon>();  // Make an ArrayList
//  for (int i = 0; i < many; i++)   polygons.add(new Polygon(boxes));
}

void draw() {
  background(255);
  draw_sphere();
  
   polygons = new ArrayList<Polygon>();  // Make an ArrayList
   many = 0;
  int ramp4i = int(ramp4);
   
   if (many < ramp4){
     many = many +1;
   }
   else {
     many = ramp4i;
   }
   
  for (int i = 0; i < many; i++)   polygons.add(new Polygon(boxes));
  
    for (Polygon poly : polygons)   poly.display();// move and display them all
    
    println(ramp1);
}

void oscEvent(OscMessage theOscMessage) {    
  float value = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp1")) {
    if (value > 0.1)   ramp1 = value;
    else               ramp1 = 0.0;
  }
  float value2 = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp2")) {
    if (value2 > 0.1)  ramp2 = value2;
    else               ramp2 = 0.0;
  }
  float value3 = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp3")) {
    if (value3 > 0.1)  ramp3 = value3;
    else               ramp3 = 0.0;
  }
  
    float value4 = theOscMessage.get(0).floatValue();
  if (theOscMessage.checkAddrPattern("/ramp4")) {
    if (value4 > 0.1)  ramp4 = value4;
    else               ramp4 = 0.0;
  }
  
}

void draw_sphere() {
  stroke(0);               //  for the sphere
  strokeWeight(ramp3);
  translate(width/2, height/2, 0);
  //rotateX(mouseY * 0.05);
  rotateY(radians(ramp2));
  noFill();
  sphereDetail(30);
  sphere(ramp1);
 // println(ramp1); 
}

  //dimentions of base are 30X by 20 deep // sides are 50 Y by 30 X
int bw = 50, bw2 = 2*bw, bw3 = 3*bw, bh = 20, bh2 = 40, bh3 = 70, bz = 20;

void make_boxes() {
  boxes = createShape();   //boxes is the name of my shape  
  boxes.beginShape();
  boxes.strokeWeight(1);
  boxes.stroke(0);
  boxes.noFill();

  boxes.vertex(bw, bw, 0);    // this is the square top
  boxes.vertex(bh, bw, 0); 
  boxes.vertex(bh, bw, -bz); 
  boxes.vertex(bw, bw, -bz); 
  boxes.vertex(bw, bw, 0); 

  boxes.vertex(bh3, bw2, 0);   //front rectangle
  boxes.vertex(bh2, bw2, 0); 
  boxes.vertex(bh, bw, 0); 

  boxes.vertex(bh, bw, -bz); //back rectangle
  boxes.vertex(bh2, bw2, -bz); 
  boxes.vertex(bh3, bw2, -bz); 
  boxes.vertex(bw, bw, -bz); 

  boxes.vertex(bw, bw, -bz);  //close up bottom or middle square
  boxes.vertex(bh3, bw2, -bz); 
  boxes.vertex(bh3, bw2, 0); 
  boxes.vertex(bh3, bw2, 0);   
  boxes.vertex(bh2, bw2, 0);
  boxes.vertex(bh2, bw2, -bz); 

  boxes.vertex(bh2, bw2, -bz);    //bottom back rectangle
  boxes.vertex(bh, bw3, -bz); 
  boxes.vertex(bw, bw3, -bz); 
  boxes.vertex(bh3, bw2, -bz); 

  boxes.vertex(bh3, bw2, 0);   //front bottom rectangle
  boxes.vertex(bw, bw3, 0);
  boxes.vertex(bh, bw3, 0); 
  boxes.vertex(bh2, bw2, 0);   

  boxes.vertex(bh, bw3, 0);   //bottom square
  boxes.vertex(bh, bw3, -bz); 
  boxes.vertex(bw, bw3, -bz); 
  boxes.vertex(bw, bw3, 0); 

  boxes.endShape();
}

// A class to describe a Polygon (with a PShape)
class Polygon {
  PShape s;              // The PShape object
  float x, y, z;         // The location where we will draw the shape
  float speed;           // Variable for simple motion

  Polygon(PShape s_) {
    x = random(-1000, 1000);
    y = random(1000, -1000); 
    z = random(-1000, 1000); 
    s = s_;
    speed = random(-1, 1);
  }

  // Simple motion
  void move() {
    y += speed;
    x += speed*1.2;
    z += speed*4;
    if (y > height)  y = -100;
    if (y < -1000)   y = height;
    if (x > width)   x = 0;
    if (x > width)   x = -200;
    if (z > 0)       z = -500;
    if (z < -1000)   z = 0;
  }

  void display() {    // Draw the object
    pushMatrix();
    move();
    translate(x, y, z);
    shape(s);
    popMatrix();
  }
}


1 Like

this would not make the array again with different length, it would actually
ADD (new)many more
but show only the first (new)many

you should reset the array