# Beginner question on drawing mulitple random shapes related to each other?

I’ve been learning Processing for about a month and have a new idea and am not quite sure how to approach. What would your approach be? Like what do I need to look up and learn to write something where I draw a shape using random() to generate coordinates or size and then draw a subsequent shape related to those random numbers and so on…

So for a tangible example, let’s say I draw a rectangle:

``````int randwidth = int(random(0,100));
int randheight = int(random(0100));
rect(0,0, randwidth, randheight);
``````

Now I want to draw another rectangle of a new random height and random width that starts at the bottom right corner of the previous rectangle, I suppose I could write this:

``````rect(randwidth, randheight, newrandwidth, newrandheight);
``````

But let’s say I want to do this 7 times (or 100 times) and end up with 7 rectangles each of different random heights and widths, each starting at the bottom right corner of the previous rectangle. How would I do this cleanly without many lines of code?

1 Like

One way:

``````final int _num = 100;

void drawRectangles(int rndmW, int rndmH) {
int randwidth = int(random(0, 600));
int randheight = int(random(0, 600));
rect(0, 0, randwidth, randheight);
rect(randwidth, randheight, rndmW, rndmH);
}

void setup() {
size(800, 800);
background(209);
for (int x = 0; x < _num; x++) {
int randWidth = int(random(0, 600));
int randHeight = int(random(0, 600));
drawRectangles(randWidth, randHeight);
}
}

void draw() {
}

``````

A for-loop is the way to go.

You can make a rectangle and draw it. Then store the lower right corner.

In the next iteration use the data and set the data with your new position.

Thanks!

This isn’t exactly it. It basically is repeating the first rectangle from (0,0) and then adding one rectangle to the bottom right corner. I want essentially no overlap and each subsequent rectangle to start at the previous rectangle’s bottom right corner.

Exactly!

Now tell a newbie how to do that The problem where I get stuck is how to store the lower right corner and then use it in the next iteration. I could “manually” do it a few times, but what if I want to draw 1000 rectangles?

Is this where I would use an array? Vectors?

Basically how in a for-loop do I relate subsequent lines/shapes/whatever to randomly generated numbers generated within the loop?

That’s the secret of the for loop: it’s doing the repetition for you

Before setup ()

float x,y;

Inside the for loop:

``````Define myWidth, myHeight

// draw rect
rect(x,y, myWidth, myHeight);

x=x+myWidth;
y=y+myHeight;

} // for
``````

This works!

``````float x;
float y;

void setup() {
size(700,700);
background(255);
}

void draw() {
for (int i=0; i < 8; i++){
float myWidth = (random(100));
float myHeight = (random(100));
rect(x, y, myWidth, myHeight);
x=x+myWidth;
y=y+myHeight;
}
noLoop();
}
``````

This draws me 8 rectangles exactly how I want. This is so simple, and yet it is making my head hurt. I definitely only partly understand for loops.

1 Like

Nice.

my version

• unique colors (using `lerpColor` command)
• giving x and y initial random values so they are not at 0,0 initially
• using random command with 2 parameters, so we have a minimum value bigger than 0
``````
// pre-set the first rect
float x=random(10, 90),
y=random(10, 90);

color RED = color(255, 0, 0);
color GREEN  = color(0, 255, 0);

// --------------------------------------------------------------------------------

void setup() {
size(700, 700);
background(255);
// stop running
noLoop();
}

void draw() {
// main loop

// for loop
for (int i=0; i < 8; i++) {
// set width and height
float myWidth = random(15, 100);
float myHeight = random(15, 100);

// calc color
float amt = map(i, 0, 8, 0, 1);
fill (lerpColor(RED, GREEN, amt));

// draw rect
rect(x, y, myWidth, myHeight);

// store the new lower right corner
x+=myWidth;
y+=myHeight;
} // for
//
} // func
//

``````

Question: If you only want it to draw once, why not move the ‘for’ loop to setup() and forget the noLoop()?

1 Like

Yeah, I guess it’s just a matter of practice and getting used to it.

1 Like

Interesting and cool to see it another way! Learning a lot here…thanks

1 Like

Because I didn’t know that would work thanks for telling me!

1 Like

not much to grasp actually:

`for (this var ; while this condition is not met; do this to it)`and…
`{do this using that var (or not) until the condition is met}` then…
follow the rest of the code
so
`for (int i = 0; i < 8; i++)` means while `i` (initialized as zero) is less than
8 keep adding one to it, execute the stuff inside brackets, test to see if it is less than 8. If it’s not, repeat, if it is, go ahead outside the brackets.

So if the condition is never met you would never get out the brackets

this is an infinite loop (not to be done!! unless you are really sure you want it):

``````//this code will break your program
for ( int = 0 ; i < 0; i++){
// do something... in this case for ever
}
rect(0, 0, 10, 10);// this line never will be executed as the program wil be stuck inside the for loop
``````

The tricky part in the loop suggested above is: `x=x+myWidth;` where the randomly choose width is added to the original x value, and become the next x. So the next rectangle is draw at the end of the last.

Lets say `x = 0`.
Then, `myWidth` gets a value of 135 from random assingmet. (`float myWidth = (random(150));`)

the rect is, then, draw with this values `rect(0, y, 135, myHeight);`

After that `x=x+myWidth` so `x = 0 + 135` and `x` now has the value of 135.

The process is repeated:

`myWidth` now gets 78 from the random generator.

the rect is, then, draw with this values `rect(135, y, 78, myHeight);`

After that `x=x+myWidth` so `135 + 78` and `x` now has the value of 213.

The process is repeated until i is equal to 7 (here `i` is not being used inside the loop).

Same logic applies to `y` and `myHeight`.
Is often useful try to read the code as the machine will when it’s hard to understand…

cheers

2 Likes