Pushing and Popping a PGraphics Grid (pushMatrix / popMatrix in a grid)

Hi there -
I was hoping to draw a basic grid of rectangles with PGraphics, but something I’m doing is wrong here and I’m not sure what it is.
Can anyone shed some light?

PGraphics img;

void setup() {  
  size(100, 100);
  img = createGraphics(width, height);
  img.beginDraw();
  img.translate(-10, 10);
  
  for (int x=0; x<10; x++) {
  img.translate(10, 0);
  img.square(0, 0, 10.0);
  img.fill(random(200), random(200), random(200));
    for (int y=0; y<40; y++) {
    img.push();
    img.translate(0, 10);
    img.square(0, 0, 10.0);
    img.fill(random(200), random(200), random(200));
    img.pop();
    }
  }
 
    img.endDraw();
  //background(0);
  image(img, 0, 0);

}

This is the output on my system (macos); what were you expecting? I note that you did not use either x or y. If you expect to see 40 rows then you’ll have to make the window taller and use y in the translation.
grid

Ah, I think I understand now. The translate moved the boxes horizontally, but when using push and pop, I need to mutiply by “y” in order to move from a relative distance.

1 Like

I need to mutiply by “y” in order to move from a relative distance

Correct. I also note that you’re using img.fill() twice and on my system all 40 rows use the same color for each column. Try using only one img.fill() and moving it down below img.pop() in the ‘for’ loop for the rows if you want each square to have a different color.

Version 1
here is a version without push / pop

the columns are beneath each other. Bad.



PGraphics img;

void setup() {
  size(600, 600);

  img = createGraphics(width, height);
  img.beginDraw();

  img.translate(-10, -10);

  for (int x=0; x<10; x++) {
    img.translate(10, 0);
    img.fill(random(200), random(200), random(200));
    for (int y=0; y<10; y++) {
      img.translate(0, 10);
      img.square(0, 0, 10.0);
    }
  }

  img.endDraw();

  //background(0);
  image(img, 0, 0);
}


Version 2

in this version, we surround the y for-loop with push / pop (resetting the y after each column)

works well and fixes the error above

no calculation with x and y needed, the translate() commands add up for x and y

PGraphics img;

void setup() {
  size(600, 600);

  img = createGraphics(width, height);
  img.beginDraw();

  img.translate(-10, -10);

  for (int x=0; x<10; x++) {
    img.translate(10, 0);
    img.fill(random(200), random(200), random(200));
    img.pushMatrix();
    for (int y=0; y<10; y++) {
      img.translate(0, 10);
      img.square(0, 0, 10.0);
    }
    img.popMatrix();
  }

  img.endDraw();

  //background(0);
  image(img, 0, 0);
}

Version 3

in this version we calculate each cell’s position

push / pop for each cell, only one translate() command in the Sketch

PGraphics img;

void setup() {
  size(600, 600);

  img = createGraphics(width, height);
  img.beginDraw();

  for (int x=0; x<10; x++) {
    img.fill(random(200), random(200), random(200));
    for (int y=0; y<10; y++) {
      img.pushMatrix();
      img.translate(x*13+32, y*13+22);
      img.square(0, 0, 10.0);
      img.popMatrix();
    }
  }

  img.endDraw();

  //background(0);
  image(img, 0, 0);
}

I don’t think there are severe speed differences between the three versions.

Personally I like version 3 the most, for example because you can make a cell to a class Cell and its display() method would just work like this. This would be harder in version 2.

Chrisir

[Edited]

3 Likes

Hello @bdon,

Always start with the simplest of examples and build on that.

Review the tutorials and and read all the references related to your code:
https://processing.org/

Simple example to help understand a nested for loop:

size(600, 600);
background(0);

int counter = 0;

for (int x=0; x<10; x++) 
  {
  for (int y=0; y<10; y++) 
    {
    fill(255);
    textSize(24);
    text(counter, x, y); // You are putting text at the (x, y) location!
    
    // See what this does:
    //int loc = x + y*10;
    //text(loc, x, y+20); // You are putting text at the (x, y) location!
    
    counter++;
    }
  }

The above needs some work.
Multiple the x and y by a factor of 60:

Change the x and y around in the for() loop and see what happens:

for (int y=0; y<10; y++) 
  {
  for (int x=0; x<10; x++) 
    {
   // Your code here
    }
  }

Replace text with a shape:

In 3D mode using a sphere you will need to push(), pop() and translate().
See the reference for sphere() to understand why.

size(600, 600, P3D);
background(0);

lights();

for (int x=0; x<10; x++) 
  {
  for (int y=0; y<10; y++) 
    {
    fill(255, 0, 0); // You may want to change in a loop so left it here!
    
    push();
    translate(60*x, 60*y); // You can add a small offset to center things better!
    noStroke();
    sphere(20);
    pop();
    }
  }

:)

3 Likes