Processing Square Stacking loop

ROOLLINGTOON

This is my first time writing here so i'll be direct, i've been trying to recreate this image:

Loop

and so far all the code i've got is:

void setup() {
size(500, 500);
}

void draw() {
rectMode(CENTER);
recta();
}


void recta() {
noFill();
int a = 10;
int y = 250;

for (int x = 0; x<20; x++) {

pushMatrix();
translate(y, y);
rect(0, 0, a, a);
popMatrix();
rotate(radians(2.0*PI));

stroke(0, 0, 0);
a= a - 20;
 }
}

And i have no idea what to do next since this is what i get from it:

Current State

So i'd like to ask for help on how to get the same result as the image.

George Profenza

You are so close !

You're absolutely on the right track using pushMatrix()/popMatrix() to isolate coordinate systems, however you might have accidentally placed the rotation after popMatrix() which defeats the purpose. You probably meant to for each square to have an independent rotation from each other and not accumulate 2 * PI to the global rotation.

The other catch is that you're rotating by the same angle (2 * PI) for each iteration in your for loop and that rotation is 360 degrees so even if you fix rotation like this:

pushMatrix();
translate(y, y);
rotate(radians(2.0*PI));
rect(0, 0, a, a);
popMatrix();

you'll get a scaling effect: concentric black squares on white background (Minor note 2.0 * PI already exists in Processing as the TWO_PI constant)

To get that spiral looking effect is to increment the angle for each iteration (e.g. x = 0, rotation = 0, x = 1, rotation = 5, x = 2, rotation = 10, etc.). The angle increment is totally up to you: depending on how you map the x increment to a rotation angle angle you'll get a tighter or looser spiral.

Speaking of mapping, Processing has a map() function which makes it super easy to map from one range of numbers (let's say x from 0 to 19) to another (let's say 0 radians to PI radians):

for (int x = 0; x < 20; x++) {
    pushMatrix();
    translate(y, y);
    rotate(map(x, 0, 19, 0, PI));
    rect(0, 0, a, a);
    popMatrix();
    a = a - 20;
  }

concentric black squares on white background rotated from centre incrementally

Here's a basic sketch based on your code:

int a = 10;
int y = 250;

void setup() {
  size(500, 500);
  rectMode(CENTER);
  noFill();
  background(255);
  recta();
}

void recta() {
  for (int x = 0; x < 20; x++) {
    pushMatrix();
    translate(y, y);
    rotate(map(x, 0, 19, 0, PI));
    rect(0, 0, a, a);
    popMatrix();
    a = a - 20;
  }
}

I've removed draw() because it was rendering the same frame without any change: drawing once in setup() achieves the same visual effect using less CPU/power.

You can use draw(), but might as add some interactivity or animation to explore shapes. Here's a tweaked version of the above with comments:

int y = 250;

void setup() {
  size(500, 500);
  rectMode(CENTER);
  noFill();
}

void draw(){
  background(255);
  recta();
}

void recta() {
  // map mouse X position to -180 to 180 degrees (as radians)
  float maxAngle = map(mouseX, 0, width, -PI, PI);
  // reset square size
  int a = 10;
  // for each square
  for (int x = 0; x < 20; x++) {
    // isolate coordinate space
    pushMatrix();
    // translate first
    translate(y, y);
    // then rotate: order matters
    // map x value to mouse mapped maximum rotation angle
    rotate(map(x, 0, 19, 0, maxAngle));
    // render the square
    rect(0, 0, a, a);
    popMatrix();
    // decrease square size
    a = a - 20;
  }
}

Remember transformation order matters (e.g. translate() then rotate() would produce different effects compared to rotate() then translate()). Have fun!

concentric circles iteratively rotated interactively mapping mouse x position to the maximum angle increment.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related