Drawing different elements ramdomly and avoiding nested if/else

Hi! I have a problem here, I have a Particle object that can be around 20 differents shapes (the shapes are limited), so in my constructor i do a random(0,20) and then on the draw method i pick the correct shape with something like this: generate(){ if(type == 0) {

rect();
circle()

} else if(...){ circle(); circle();

} else if(){ triangle(); rect(); circle();

} }

I know this is akward and a big performance flaw, so i need to do something to:

  • Avoid the multiple if's and also"save" the shape on some object that can be used on the draw method ( i tried PGraphics but 1500 images were heavy) without calling everytime this generate() method.

Thanks and sorry for the english

Have a good day

Answers

  • Hello ! Can you post your code because it's really hard to figure out what you re trying to do from your description

  • If I understood correctly, I think PShape can do it for you, see:

    // lets keep adding shapes
    ArrayList <Shape> shapes= new ArrayList <Shape>();
    
    
    void setup() {
    
      size(500, 500, P2D);
      background(255);
    
      //one for starters
      shapes.add(new Shape());
    
      // not in a hurry
      frameRate(3);
    }
    
    void draw() {
      background(255);
    
      // display all of them
      for (Shape s : shapes) {
        s.display();
      }
    
      shapes.add(new Shape());
    }
    
    
    
    
    class Shape {
      //a PShape to hold each instance particular shape
      PShape s;
      PVector pos;
    
      Shape() {
        // go only once, at creation trough random choosing
        int format = int(random(3));
    
        pos = new PVector(random(width), random(height));
    
        // a switch easier to read...
        // create the object already with it's specific shape
        // you can make any kind of customization whot PShape
        // see reference 
        switch (format) {
    
        case 0:
          s = createShape(RECT, 0, 0, 50, 50 );
          s.setFill(color(0, 0, 120));
          s.setStroke(false);
          return;
        case 1:
          s = createShape(ELLIPSE, 0, 0, 50, 50 );
          s.setFill(color(120, 0, 0));
          s.setStroke(false);
          return;
    
        default:
          s = createShape(TRIANGLE, 0, 0, 0, 50, 50, 0 );
          s.setFill(color(120, 0, 120));
          s.setStroke(false);
          return;
        }
      }//eof constructor
    
    
      void display() {
        //display the shape
        shape(s, pos.x, pos.y);
      }
    }//eof class
    

    before I thought in using an interface. The PShape seem s abetter way, but as iit s done... You might want to look at

    Shape[] shapes = new Shape[30];
    
    
    void setup() {
      size(400, 400);
    
    
      for (int i =0; i < shapes.length; i++) {
        float r = random(1);
        if ( r < 0.34) {
          shapes[i] = new Circle();
        } else if( r > 0.34 && r > 0.68) {
          shapes[i] = new Square();
        } else {
          shapes[i] = new Rect();
        }
      }
    
      for (Shape s : shapes) {
        s.display();
      }
    }
    
    
    
    interface Shape {
      void display();
    }
    
    
    class Square implements Shape {
    
      Square() {
      }
    
      void display() {
        fill(255, 0, 0);
        rect(random(25, width-25), random(25, height -25), 50, 50);
      }
    }
    
    
    
    class Circle implements Shape {
    
      Circle() {
      }
    
      void display() {
        fill(0, 0, 255);
        ellipse(random(25, width-25), random(25, height -25), 50, 50);
      }
    }
    
    class Rect implements Shape {
    
      Rect() {
      }
    
      void display() {
        fill(0, 255, 0);
        rect(random(25, width-25), random(25, height -25), 50, 100);
      }
    }
    
  • Hey _vk! Thanks but this are compound shapes, rects in rects for example and PShape doesn't allow me to do that.

    Hey tlecoz! it's something like this, sorry but it's in Spanish:

    void generate(){

    if (tipo == 0) { // Figura 0 rect(x, y, wescala, wescala);

        if (subtipo > 0 ) {  
          fill(secundario , opacidad);    
          if ( subtipo == 0) rect(x, y, w-20*escala, w-20*escala);
          // Figura 2
          else if (subtipo == 1) {
            rect(x-w/4, y+h/4, w/3*escala, w/3*escala);
            rect(x+w/4, y+h/4, w/3*escala, w/3*escala);
          } 
          //Figura 3
          else if (subtipo == 2) {
            rect(x, y+h/4, w*.80*escala, h/3*escala);
          } 
          //Figura 5
          else if (subtipo == 3) {
            rect(x, y-h/4, w*.80*escala, h/3*escala);
            rect(x, y+h/4, w*.80*escala, h/3*escala);
          }
    
          //Figura 6
          else if (subtipo == 4) {
            rect(x-w/4, y-h/4, w/3*escala, w/3*escala);
            rect(x+w/4, y-h/4, w/3*escala, w/3*escala);
            rect(x, y+h/4, w*.80*escala, h/3*escala);
          }
          //Figura 7
          else if (subtipo == 5) {
            stroke(primario);
            strokeWeight(2);
    
            rect(x-w/4, y-h/5, w/4*escala, h*0.5*escala);
            rect(x, y-h/5, w/4*escala, h*0.5*escala);
            rect(x+w/4, y-h/5, w/4*escala, h*0.5*escala);
          }
      }
    
    }
    
      //Rectangulo con o sin variacion
    else if (tipo == 1) {
      rect(x, y, w*escala, h*escala);
      if (subtipo > 0) {  
        fill(secundario , opacidad);
    
        //Figura 8
        if (subtipo == 1) {
          rect(x, y, w*0.7*escala, h*0.8*escala);
        }
    
        //Figura 9
        else if (subtipo == 2) {
          rect(x+w/5.5, y+h/3, w/3*escala, w/3*escala);
          rect(x+w/5.5, y, w/3*escala, w/3*escala);
        }
    
        //Figura 11
        else if (subtipo == 3) {
          rect(x, y+h/5, w*0.7*escala, h/3.5*escala);
          rect(x, y-h/5, w*0.7*escala, h/3.5*escala);      
        }
    
        //Figura 12
        else if (subtipo == 4) {        
          rect(x, y, w*0.7*escala, h*0.8*escala);
          fill(terciario);
          rect(x, y+h/5, w*0.4*escala, w*0.4*escala);      
        }
    
        //Figura 13
        else if (subtipo == 5) {
          rect(x, y+h/5, w*0.7*escala, h/3.5*escala);
          rect(x, y-h/5, w*0.7*escala, h/3.5*escala);
          fill(terciario);
          rect(x, y-h/5, w*0.3*escala, w*0.3*escala);
        }
    
        //Figura 14
        else if (subtipo == 6) {
          rect(x-w/6, y+h/5, w*0.3*escala, w*0.3*escala);
          fill(terciario);
          rect(x, y-h/5, w*0.7*escala, w*0.7*escala);
        }   
    
      }
    }
    
    // Encadenados
    
    else if (tipo == 2) {
        if (subtipo > 0) {  
          fill(secundario);
         //Figura 15
          if (subtipo == 1) {
            for( int i =1; i < figura_encadenado[0]; i++){
              for( int j =1; j < figura_encadenado[1]; j++){
                rect(x+w/2*i, y+h/5*j, w*0.3*escala, w*0.3*escala);
              }
            }
          }
        }  
    }
    
    // Otros
    
    else if (tipo==3) {
      if (subtipo > 0) {  
        fill(secundario);
    
        //Figura 16
        if (subtipo == 1) {  
    
          pushStyle();
          fill(primario);
          rect(x, y, w, h);     
          popStyle();        
    
    
          rect(x, y+h/5, w*0.7*escala, h/3.5*escala);
          rect(x, y-h/5, w*0.7*escala, h/3.5*escala); 
    
          pushStyle();
          fill(primario);
          rect(x, y, w*0.5*escala, h*0.4*escala);
          popStyle();        
        }
    
        //Figura 17
        else if (subtipo == 2) {  
          rect(x, y, w/2*escala, h*escala);
          rect(x-w/4, y+h/2, w*escala, w/2*escala);
        }  
    
        //Figura 20
        else if (subtipo == 3) {
    
          rect(x, y, w/2*escala, h*escala);
          fill(terciario);
          rect(x, y+w, w/2*escala, w/2*escala);
    
        }         
    
    }
    

    }

    Subtipos are some elements that share some characteristics with Tipos, for example tipo 1 es a RECT and subtipos use that rect, and so.

    I can get rid of subtipos doing more tipos (doesn't really matter) I just did it that way because i tought it could help me reusing code.

  • Have you looked at the other code? The one with the Interface.

  • Yes _vk, but if I do that i should create a new shape class for each possible shape i have right? For example, I have rect, rect-rect, rect-rect-rect, rectangle, and so on. Maybe i get it wrong

  • _vk_vk
    edited May 2015

    i should create a new shape class for each possible shape

    Yes I think so.

  • _vk_vk
    edited May 2015

    And what about this one ?

    : )

    //two pImages
    PImage[] images = new PImage [2];
    
    
    VarShape[] shapes = new VarShape[200];
    
    // for drawing the image
    int img_size = 40;
    
    
    void setup() {
      size(800, 800);
      noStroke();
    
    
    
    //****** drawing each image once
    
      // local to setup.  
      // draw once
      PGraphics fSquare;
    
      fSquare = createGraphics(img_size, img_size);
      fSquare.beginDraw();
      fSquare.noStroke();
      fSquare.fill(255, 0);
      for (int i = 0; i <= 12; i+=4) {
        fSquare.fill(255 - (i*12), 0, 255, 100);
        fSquare.rect(i, i, img_size - (i*2), img_size - (i*2));
      }
      fSquare.fill(150, 0, 150);
      fSquare.ellipse(img_size/2, img_size/2, img_size/4, img_size/4);
      fSquare.endDraw();
    
    
    
    
    
    
      // local to setup.  
      // draw once
      PGraphics fCircle;
      fCircle = createGraphics(img_size, img_size);
      fCircle.beginDraw();
      fCircle.noStroke();
      fCircle.fill(255, 0);
      for (int i = 0; i <= 12; i+=4) {
        fCircle.fill(0, 255 - (i*12), 255, 100);
        fCircle.ellipse(img_size/2, img_size/2, img_size - (i*2), img_size - (i*2));
      }
      fCircle.fill(0, 150, 150);
      int xy = img_size/4 + img_size/8;
      fCircle.rect(xy, xy, img_size/4, img_size/4);
      fCircle.endDraw();
    
    
    
    //******* get rid of PGraphics
    
      // pass reference to global Pimage
      images[0] = createImage(img_size, img_size, ARGB);
      images[1] = createImage(img_size, img_size, ARGB);
      images[0] = fSquare;
      images[1] = fCircle;
    
    
    
      // populate VarShape array
      for (int i = 0; i < shapes.length; i++) {
        shapes[i] = new VarShape();
      } 
    
      frameRate(60);
    }
    
    void draw() {
      background(255);
    
    //a strip on the background to see transparency
    fill(190, 220, 200);
    rect(width/3, 0, width/3, height);
    
    
      for (VarShape s : shapes) {
        s.display();
      }
    
     // new ones 
    int gone = frameCount%shapes.length;
    shapes[gone] = new VarShape();
    
    }
    
    
    class VarShape {
      // an int to choose a image to display
      int img;
      PVector pos;
    
      VarShape() {
    
        // get a random index
        img  = int(random(2));
        pos = new PVector(random(width), random(height));
      }
    
    
      void display() {
        // display apropiate one
        image(images[img], pos.x, pos.y);
      }
    }
    
Sign In or Register to comment.