Repasando Processing / pushMatrix(), popMatrix()

En el primer post sobre transformaciones ya expliqué cómo maneja Processing este tipo de operaciones y cómo estas se suman cuando hay varias en un mismo sketch. Y también adelanté que hay formas de resetear las tranformaciones para que resulte más sencillo operar con ellas.

En el siguiente sketch hay dos grupos de tres cuadrados a los que se aplica transformaciones de escalado.

En el grupo de la izquierda cada cuadrado es un 80% menor que el anterior

scale(0.8);

Como las transformaciones se aplican a todo el plano y se suman, el resultado es que cada cuadrado no sólo se reduce sino que cambia de posición, al escalarse también el sistema de coordenadas.

Al final de ese primer bloque hay una función resetMatrix() que devuelve el origen de coordenadas a su posición inicial, por lo que las transformaciones siguientes no se sumarán a las anteriores.

En el segundo bloque de cuadrados vemos que todos tienen la misma posición en el plano, y que están escritos entre funciones pushMatrix() y popMatrix().

//Primer cuadrado
pushMatrix();
translate(width*0.75, height/2);
rect(0, 0, 100, 100);
popMatrix();

//Segundo cuadrado
pushMatrix();
translate(width*0.75, height/2);
scale(0.8);
rect(0, 0, 100, 100);
popMatrix();

//Tercer cuadrado
pushMatrix();
translate(width*0.75, height/2);
scale(0.6);
rect(0, 0, 100, 100);
popMatrix();

pushMatrix() guarda la matriz de coordenadas en un momento determinado del sketch, y popMatrix() las restablece después de haber realizado alguna transformación o transformaciones. De esta manera cada una de ellas no se suma a las anteriores, sino que se efectúan todas desde la misma posición original.

Estos otros ejemplos servirán para comprender mejor el modo como operan estas funciones:

Trasladar y girar un elemento

img
El uso de rotate() y translate() para girar y mover respectivamente un elemento, es sencillo, pero requiere que se comprendan varias cosas:

  1. Estas funciones no mueven objetos o elementos, sino todo el espacio de dibujo. rotate() gira alrededor del origen de coordenadas. Si quieres situar un cuadrado girando alrededor de su centro en medio de la ventana, necesitas hacer coincidir el centro del cuadrado con el origen de coordenadas y luego trasladarlo todo hacia el centro.
  2. Si quieres aplicar difirentes movimientos a diferentes elementos de una misma aplicación, tienes que resetear el cambio anterior mediante resetMatrix().
//usaremos esta variable para hacer girar los cuadrados
float i = 0;
//y esta para el tono (hue) del color
float h = 0;
 
void setup(){
 size(300, 300);
 //cambiamos el modo para el rectángulo
 rectMode(CENTER);
 //y el de color
 colorMode(HSB, 100);
 //creamos un valor aleatorio para el tono
 h = random(100);
 //definimos el color de fondo
 background(h, 50, 50);
} 
 
void draw(){
  //tiramos un rectángulo del mismo color y tamaño del fondo a cada ciclo
  fill(h, 50, 50);
  rect(width/2, height/2, width, height);
  //borde y relleno del cuadrado
  stroke(#ffffff);
  fill(h*0.5, 50, 50);
  //trasladamos el punto 0,0 al centro de la ventana
  translate(width/2, height/2);
  //asignamos el valor de giro
  rotate(i);
  //y dibujamos el cuadrado
  rect(0, 0, 150, 150);
  //resereamos traslación y giro
  resetMatrix();
  //y repetimos con otro rectángulo
  stroke(0, 50);
  noFill();
  translate(width/2, height/2);
  rotate(-i/2);
  rect(0, 0, 156, 156);
  //esto hace que el valor del ángulo aumente a cada ciclo
  i = i + 0.01;
}