How do I use recursion on a shape made out of curves?

edited January 2017 in Questions about Code

Hello everyone,

I am trying to use recursion in order to fill in a shape made out of 8 curves. I am aware I would first have to translate the shape into a function before using recursion but I cannot seem to be able to do so. Could someone show me how to translate a shape made out of curves into a function and then how to use recursion on that function ? Here is my code :
void setup(){ size (1200,800); background (255); }

 void draw (){
   stroke(255,131,59);
   strokeWeight (3);
beginShape ();
  curve(100,300,250,200,500,100,500,400); 
  curve(300,-690,500,100,870,180,1000,750); 
  curve(600,-200,870,180,1050,240,1500,100);
  curve(880,300,1050,240,1125,298,1117,500);
  curve(100,-800,1125,298,1000,450,400,500);
  curve(200,850,700,550,1000,450,1400,900);
  curve(400,0,170,400,700,550,800,200);
  curve(400,0,170,400,250,200,800,200);
  endShape ();
 }

I have also attached below an image of my shape. Thank you very much, i am pretty new to processing and any help/ideas is appreciated!

shape

Answers

  • use recursion in order to fill

    Who told you to do that? Is this a particular recursive filling method from a textbook, article, or assignment?

    Which is your goal -- to fill with recursion, or just to fill the curvy shape, one way or another?

    For the basics of how to use recursion (a function, calling itself), see the Processing recursion example.

    translate a shape made out of curves into a function

    Do you mean create a function which takes arguments and uses those arguments to draw shapes made out of curves? If you are really new to programming, start with what is a function.

  • edited November 2016

    Hi Jeremy, thank you very much for your response! This in the context of a creative assignment and I am trying to fill in the shape with recursion of smaller versions of it. such as i attached bellow.

    I am able to use recursion on an ellipse but am lost on how to use it with irregular shapes such as the one i have created.

    Is there a possible way to do that? Or of using any method that may give me a similar result?

    unnamed

  • edited November 2016

    @JF27

    Oooooooh. I thought you meant a recursive approach to filling the shape with a solid color.

    You want:

    1. reread the Recursion example I sent.
    2. put your curve code in a function -- reread the function example.
    3. From draw, call the function once
    4. The function will draw the curve, then call the "scale()" function, then will call itself (recursion!) -- and make a smaller cuve!
    5. ...which makes a smaller curve, which makes a smaller curve....
    6. You may want to let it know when it should stop!

    P.S. Please edit your top post and format your code with highlighting and CTRL+o

  • Answer ✓

    Is there a particular reason for using recursion since in this case a simple iterative (fop-loop, while-loop, or do-while loop) would do the job more efficiently.

    There are other problems to overcome.

    1) You need to execute noFill(); before drawing the curve

    2) Scaling will simply rescale the image about the origin which means that the curves will not be nested without translating the smaller curves first (see image below)

    3) Scaling will affect the stroke weight as well (see image below)

    The other problem is that you want the curves

    This image was produced from this code which at least creates the initial function you need.

    void setup() {
      size (1200, 800);
    }
    
    void draw () {
      background(255);
      for (float scale = 1; scale > 0.4; scale -= 0.1) {
        scale(scale);
        drawCurve();
      }
    }
    
    void drawCurve() {
      stroke(255, 131, 59);
      strokeWeight (3);
      noFill();
      beginShape ();
      curve(100, 300, 250, 200, 500, 100, 500, 400); 
      curve(300, -690, 500, 100, 870, 180, 1000, 750); 
      curve(600, -200, 870, 180, 1050, 240, 1500, 100);
      curve(880, 300, 1050, 240, 1125, 298, 1117, 500);
      curve(100, -800, 1125, 298, 1000, 450, 400, 500);
      curve(200, 850, 700, 550, 1000, 450, 1400, 900);
      curve(400, 0, 170, 400, 700, 550, 800, 200);
      curve(400, 0, 170, 400, 250, 200, 800, 200);
      endShape ();
    }
    
  • @JF27 -- If you center the curve set using translate(), scaling will work correctly (shapes will be properly nested). For starters, the center is the min+max x / 2, and the min+max y / 2.

    For greater control you might also want to create your curve with createShape() and store it in a PShape. In that case you could translate once (when creating the shape, to center it on 0,0) and then translate one more time before drawing your recursively nested set (to draw them anywhere you want, e.g. screen width/2, height/2).

  • edited November 2016

    thanks so much for the code @quark and @jeremydouglass ! i feel like i am definitely getting to the bottom of

    So I have now tried centering the curve set but I cannot figure out where to place the `translate`` function in the code or how to define the min and max ? do i have to use an array for that? this is my code and the result is it just pushes the image off frame :

    void setup() {
      size (1200, 800);
    }
    
    void draw () {
      background(255);
    
      for (float scale = 1; scale > 0.4; scale -= 0.1) {
        scale(scale);
        drawCurve();
    
      }
    }
    
    void drawCurve() {
      stroke(255, 131, 59);
      strokeWeight (3);
      noFill();
    
      beginShape ();
      translate (width/2, height/2);
      curve(100, 300, 250, 200, 500, 100, 500, 400); 
      curve(300, -690, 500, 100, 870, 180, 1000, 750); 
      curve(600, -200, 870, 180, 1050, 240, 1500, 100);
      curve(880, 300, 1050, 240, 1125, 298, 1117, 500);
      curve(100, -800, 1125, 298, 1000, 450, 400, 500);
      curve(200, 850, 700, 550, 1000, 450, 1400, 900);
      curve(400, 0, 170, 400, 700, 550, 800, 200);
      curve(400, 0, 170, 400, 250, 200, 800, 200);
      endShape ();
    }
    

    I'm guessing the problem is with the values i put into translate () ?

  • edited November 2016

    Your "translate" is getting called over and over -- each time with a different amount, because of the scaling down -- and it makes alignment impossible.

    Use pushMatrix / popMatrix to isolate the translation and reset it each time. Doing that is budging each curves around each time so that it is centered around 0,0, (regardless of its scaled size) -- shifting by half the curves width and height.

    Make a separate translation at the top to do all drawing with 0,0 at the center of the screen.

    // CurveShape
    // 2016-11-09 Processing 3.2.1 
    // https:// forum.processing.org/two/discussion/18947/how-do-i-use-recursion-on-a-shape-made-out-of-curves#latest
    
    void setup() {
      size (1200, 800);
    }
    void draw () {
      background(255);
      translate(width/2,height/2); // draw with 0,0 at the center of the screen
      for (float scale = 1; scale > 0.4; scale -= 0.025) {
        scale(scale);
        drawCurve();
      }
    }
    void drawCurve() {
      stroke(255, 131, 59);
      strokeWeight (3);
      noFill();
      pushMatrix();
        ellipse(0, 0, 2, 2);
        // Align 0,0 with the center of the width/height of the curve.
        // The curves run from x=170 to x=1125, and y = 100 to 550.
        // So the center is offset (1125+170)/2 = 647.5 , y = (550+100)/2 = 325. 
        // We fix that by subtracting.
        translate (-647.5, -325);
        curve(100, 300, 250, 200, 500, 100, 500, 400); 
        curve(300, -690, 500, 100, 870, 180, 1000, 750); 
        curve(600, -200, 870, 180, 1050, 240, 1500, 100);
        curve(880, 300, 1050, 240, 1125, 298, 1117, 500);
        curve(100, -800, 1125, 298, 1000, 450, 400, 500);
        curve(200, 850, 700, 550, 1000, 450, 1400, 900);
        curve(400, 0, 170, 400, 700, 550, 800, 200);
        curve(400, 0, 170, 400, 250, 200, 800, 200);
        // ... although it would have been better to draw the curves around 0,0 in the first place!
      popMatrix();
    }
    

    Note that:

    1. This solution doesn't use recursion, just a loop.
    2. If you use a PShape ps with ps.curveVertex() instead of drawing each curve(), you can just use ps.width/2, ps.height/2 to automatically find the center of whatever you drew. Easier!
    3. If you want to find the center manually, save your sketch, then activate Menu > Sketch > Tweak. Hover your mouse over the -647.5 and drag back and forth. You could find the alignment manually this way. Easier!

    Screen Shot 2016-11-09 at 2.57.40 PM

Sign In or Register to comment.