How to best grow an object in Processing

New to Processing/Java with some experience in Python and trying to wrap my head around the different kinds of ways one can and can't manipulate objects.

What I want is to have a shape defined as an object and then have a grow function as part of that shape which will grow it during draw, but I'm not sure I'm even on the right track trying to have this work as an object.

My current class idea is to have the original shape and then manipulate it somehow and add it to a group of shapes which all get drawn during the display function, so it looks like the shape is growing:

class growingShape {

  PShape growths;
  PShape originalshape;

  color c;
  float originalX;
  float originalY;
  float wide;
  float high;

  float newY;
  float newX;
  float newwide;
  float newhigh;

  growingShape(color tempC, float tempXpos, float tempYpos, float tempWidth, float tempHeight) { 
    c = tempC;
    originalX = tempXpos;
    originalY = tempYpos;
    wide = tempWidth;
    high = tempHeight;
    growths = createShape(GROUP);
    originalshape = createShape(ELLIPSE,originalX,originalY,wide,high);
    originalshape.setFill(color(c));
    originalshape.setStroke(color(c));

  }

  void display() {
    shape(originalshape);
    shape(growths);
  }

  void grow() {
  // what would this look like??
  }
}

then runtime would be something like

void setup {
  example = new growingShape(#D1B319,450,100,30,30);
}

void draw {
  example.display();
  example.grow();
}

I was thinking of using translate/push/pop matrix or stuff like that to make it grow, but I don't think there's a way you can do that inside the grow function in an object?

Like I said, I might be totally overcomplicating this. I'm just looking for tips on how to make a shape that grows in a complex manner. Thanks. : )

Answers

  • edited March 2018

    @lazordisk -- Is drawing an ellipse (or a series of ellipses) your end goal, or is that a placeholder for something more complex?

    1. If you want to constantly change the parameters on a primitive (rect, ellipse, quad etc.) then you really don't need to use createShape at all -- you can just have a class with some variables and a draw method that calls ellipse().

    2. If you want to accumulate a graphic layer with many ellipses drawn on it, you can do that with a pixel buffer rather than an object -- just create a transparent PGraphics, draw new ellipses on it, and display it using image()

    3. If you want to assemble a complex shape object and the ability to manipulate the individual parts is important, like a shadow puppet, then it might make sense to add child shapes onto a single PShape. For an example of this approach, see: https://forum.processing.org/two/discussion/comment/75715/#Comment_75715

  • @jeremydouglass

    Hmm. My ultimate goal is to have a series of starting shape which are ellipses, but to have them grow according to a series of variables I pass into the program. My original idea was to draw new shapes and append them to the original with PShape to make the illusion of a growing shape, but it sounds like maybe it would be better to have a series of parameters for one shape that change instead.

  • For an fixed shape you can use scale()

    If you want to have an organic grow look at brownian (link above)

    You could eval the data and when data has increased by 5 or 200 add a brownian step

  • which are ellipses, but to have them grow

    Do you mean, they become bigger ellipses? Or do they become something else, like a pentagon or a snowflake?

  • Something different, the shape should change. Kind of an organic look like the Brownian thing, although a little less random.

  • edited April 2018 Answer ✓

    @lazordisk -- so perhaps you want to draw a closed curve with points, then have each point on the curve drift out, like a growing blob? There are several ways in Processing of defining a complex curve consisting of many points. Making the curve closed often involves matching the anchors from the first and last point.

  • Ahh! Yes, that makes sense! So if I use something like

    `beginShape();

    for (let a = 0; a < 360; a += 10) {
      let x = 50 * sin(a) + (width*.5);
      let y = 50 * cos(a) + (height*.5);
      curveVertex(x, y);
    }
    
    endShape(CLOSE);`
    

    then I can use vertices to make a circle and then expand the vertices out. Would saving the vertices as variables be the best way to do that, then? Probably when making the shape?

  • @lazordisk -- Exactly! Your "circle" is a very high-count polygon. You can use curveVertex, or you can increase the point count (e.g. 400, 800, etc.) to the point where even with straight lines it appears curved.

    Yes, you can save the vertices in parallel arrays x[], y[] or in an array PVector[].

    You may be interested in a related discussion on the new forum:

  • GrowingShape example;  
    boolean growing = true; 
    
    void setup() {
      size(900, 800);
      example = new GrowingShape(#D1B319, 
        450, height/2, 
        30, 30);
      background(111);
    }
    
    void draw() {
      background(111); 
      example.display();
      if (frameCount>33 && growing) {
        example.grow();
      }
    }
    
    void keyPressed() {
      growing=!growing;
    }
    
    //==============================================================
    
    class GrowingShape {
    
      //PShape growths;
      PShape originalshape;
    
      color c;
      float originalX;
      float originalY;
      float wide;
      float high;
    
      float newY;
      float newX;
      float newwide;
      float newhigh;
    
      float[] radiusArray;
    
      // constr 
      GrowingShape(color tempC, 
        float tempXpos, float tempYpos, 
        float tempWidth, float tempHeight) { 
    
        c = tempC;
        originalX = tempXpos;
        originalY = tempYpos;
        wide = tempWidth;
        high = tempHeight;
    
        //growths = createShape(GROUP);
        //originalshape = createShape(ELLIPSE, originalX, originalY, wide, high);
        //originalshape.setFill(color(c));
        //originalshape.setStroke(color(c));
    
        int step=3;
        int k=0; 
        originalshape = createShape(); 
        originalshape.beginShape(); 
        radiusArray = new float [int(360/step)+1];
        for (int i = 0; i < 360; i+=step) {
          radiusArray[k] =  random(9, wide); 
          float x1 = radiusArray[k] * cos(radians(i)) + tempXpos;
          float y1 = radiusArray[k] * sin(radians(i)) + tempYpos;
          originalshape.vertex(x1, y1);
          k++;
        } 
        originalshape.endShape(); 
    
        int count = originalshape.getVertexCount();
        println(count);
      } // constr 
    
      void display() {
        noFill();
        shape(originalshape);
        //shape(growths);
      }
    
      void grow() {
        for (int i = 0; i < originalshape.getVertexCount(); i++) {
          PVector v = originalshape.getVertex(i);
          //v.x *= random(1);
          //v.y *= random(1);
          radiusArray[i]+=random(5);
          float x1 = radiusArray[i] * cos(radians(i*3)) + originalX;
          float y1 = radiusArray[i] * sin(radians(i*3)) + originalY;
    
          originalshape.setVertex(i, new PVector(x1, y1));
        }
      }
    }
    
Sign In or Register to comment.