Transformaciones
Las transformaciones nos permiten modificar la ubicación de nuestro origen de dibujo, la dimensiones de las medidas del canvas, y su rotación.
Estas modificaciones se acumulan, y pueden ser temporales.
1 Funciones
1.1 translate(dx, dy);
Traslada la posición del origen dx
pixeles sobre el eje x
, y dy
pixeles sobre el eje y
, respecto a la posición anterior.
Los dos argumentos son de tipo float
, por lo que pueden tener puntos decimales, y pueden ser positivos o negativos.
// dibuja un cuadrado en el origen
rect(0, 0, 100, 100);
// traslada el origen 200 pixeles a la derecha
translate( 200, 0);
// dibuja un cuadrado con la misma función que antes
rect(0, 0, 100, 100);
// traslada el origen 200 pixeles hacia abajo de donde estaba
translate(0, 200);
// dibuja un cuadrado con la misma función que antes
rect(0, 0, 100, 100);
Nota que el tercer cuadrado queda debajo del segundo.
translate(0, 200);
no significa “traslada el origen a las coordenadas originales 0, 200
”, sino “traslada el origen 0 pixeles en x
, y 200 pixeles hacia abajo en y
, respecto a donde estaba antes”
1.2 scale( k );
Multiplica las unidades de medida actuales por un factor k
de tipo float
.
Si k
es mayor a 1.0
, la escala crece, si k
es menor a 1.0
y mayor a 0.0
, la escala decrece.
Por ejemplo, escala al doble:
scale( 2 ); // escala al doble
rect(0, 0, 100, 50); // este rectángulo medirá 200x100 en el marco de referencia original
O escala a la mitad:
scale( 0.5 ); // escala a la mitad
rect(0, 0, 100, 50); // este rectángulo medirá 50x25 en el marco de referencia original
1.3 rotate( a );
Rota el lienzo una cantidad de a
radianes respecto a su posición actual, tomando como centro de rotación al origen.
Una vuelta completa son 2π radianes, que en Processing podemos escribir TWO_PI
. También tenemos disponible la palabra clave PI
para referirnos a media vuelta (π).
// rota PI/2 radianes (un cuarto de vuelta)
rotate( PI/2 );
Podemos rotar en grados usando la función radians( grados )
, que convierte una cantidad de grados a su valor en radianes.
// rota 90° (un cuarto de vuelta)
rotate( radians( 90 ) );
Ángulos positivos rotan con las manecillas de reloj (clockwise) y ángulos negativos rotan en contra (counter clockwise).
1.4 Guarda y recupera matriz de transformaciones: pushMatrix(), popMatrix()
En ocasiones necesitaremos regresar al estado del canvas (técnicamente, al estado de su matriz de transformaciones) previo a ciertas transformaciones.
Una opción es revertir las transformaciones manualmente, pero puede ser confuso y con mucha posibilidad de error.
La opción recomendada es guardar (pushMatrix()
) la matriz antes de aplicar transformaciones, y recuperarla (popMatrix()
) cuando terminemos y queramos regresar a un estado previo.
// guardamos matriz original
pushMatrix();
// aplicamos algunas transformaciones
translate( 200, 200);
rotate( PI/3 );
// todo lo que dibujemos aquí va a estar transformado
rect(0,0, 100, 100);
// recuperamos matriz guardada
popMatrix();
// todo lo que dibujemos a continuación estará "normal":
rect(0, 0, 100, 100);
push y pop se refieren a operaciones de una “pila” (stack), como si fuera una pila de libros.
push es poner un libro hasta arriba, y pop es quitar el libro de hasta arriba.
Es posible utilizar múltiples pushMatrix()
para guardar distintos estados de la matriz; solo hay que tener presente que tiene que haber un número correspondiente de popMatrix()
.
2 Ejemplos
2.1 Rotar alrededor de cierto punto en específico
El siguiente código dibuja un rectángulo con esquina superior izquierda en 100,100, un ancho de 200 y una altura de 100 pixeles:
rect( 100, 100, 200, 100);
Podemos calcular que su centro está en las coordenadas 200, 150. En términos de variables x
, y
, ancho
y altura
las coordenadas del centro las calculamos de la siguiente forma:
2; // 300 = 100 + 200/2
cx = x + ancho/2; // 150 = 100 + 100/2 cy = y + altura/
Para rotar al rectángulo usando ese centro como ubicación del eje de rotación, usamos la siguiente secuencia de transformaciones:
// guarda el origen
pushMatrix();
// traslada al punto/eje de rotación
translate( 200, 150);
// rota 45 grados clockwise
rotate( radians(45) );
// translada "de regreso":
translate( -200, -150);
// dibuja el rectángulo
rect( 100, 100, 200, 100);
// recupera el origen
popMatrix();
3 Consideraciones
El orden de las transformaciones importa.
Será distinto escalar y luego trasladar, que trasladar y luego escalar.
Será distinto trasladar y luego rotar, que rotar y luego trasladar.
¡Haz las pruebas e identifica las diferencias! :)