Help understanding the logic behind this code (center grid)

Hi everybody, I have this code from a tutorial. So basically I want to draw a grid of boxes using WEBGL.
I have a hard time to understand the logic of this translate( size/2+ i * size - size * cols/2, size/2+ j * size - size * rows/2);
Why would this help center the box grid to the center of the canvas ? And how can the tutorial come up with this logic?
Thank you!


let size = 50;
let rows;
let cols;

function setup() {
  createCanvas(400, 400, WEBGL);
  angleMode(DEGREES);
  rows=3;
  cols=3;
}

function draw() {
  background(220);
  
  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      fill(255);
      push();
     translate( size/2+ i * size - size * cols/2, size/2+ j * size - size * rows/2);
     
      box(size);
      pop();
    }
    
    fill(255, 0, 0);
    box(50);
  }
}

Apparently, the point in 0,0 in WEBGL is at the center of the screen.

Apparently, a box (other than rect()!) is drawn at its center (not corner).

So box(29); is centered at 0,0.

Having this in mind, the formula is easy to get:

 translate( size/2+ i * size - size * cols/2,   // the x part uses i 
                 size/2+ j * size - size * rows/2);  // the y part uses j 
                                                                         // no z part yet

Explanation

Move right by half a box (compensating the fact that cube is displayed centered, not upper left corner):
size/2+

That’s the core: place the cubes next to each other, starting with 0, then 50, 150
i * size

we need to move left to center the grid / cube ( - 50 * 1.5 on screen)
- size * cols/2

simplified version :
works only for 3 cols
translate( i * size - size,


same for y-part

remember that in math * and / is calculated before + and - , otherwise this wouldn’t work.

Chrisir


P.S.

my version

let size = 50.0;

let rows;
let cols;

function setup() {
  createCanvas(400, 400, WEBGL);

  // angleMode(DEGREES);
  rows = 7.0;
  cols = 7.0;
}

function draw() {
  background(220);

  stroke(0);
  line(0, 0, 300, 0);
  stroke(0);
  line(0, 300, 0, 0);

  // return;
  
  push();
  translate((-size * cols) / 2 + size / 2,
            (-size * rows) / 2 + size / 2);

  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      fill(255);
      push();
      translate(i * size,
                j * size);

      box(size);
      pop();
    }
  }

  pop();

  fill(255, 0, 0);
  box(size);
}


2 Likes

Thank you so much for your thorough explanation!

1 Like