Rotació i transformacions
Descobreix com moure, girar i escalar les teves formes per crear mandales, patrons radials i composicions dinàmiques amb translate(), rotate() i scale().
Per què necessitem transformar?
Fins ara hem dibuixat formes directament en una posició del llenç. Però imagina que vols dibuixar un molí de vent amb aspes al voltant d'un centre, o una flor amb pètals en cercle. Calcular les coordenades de cada element pot ser complicat.
Les transformacions geomètriques ens permeten canviar temporalment el sistema de referència del dibuix: desplaçar l'origen, girar els eixos o canviar l'escala. Així, poden dibuixar cada element com si estigués a la posició original, i que automàticament aparegui al lloc correcte.
translate(x, y): desplaçar l'origen
translate(dx, dy) mou l'origen de coordenades (0,0) a la posició (dx, dy) del llenç. A partir d'aleshores, tot el que dibuixem es referirà a aquest nou origen.
Per exemple, si fem translate(150, 100) i després dibuixem un cercle a (0,0), aquest apareixerà al centre (150, 100) del llenç original.
translate(150, 100); // movem origen al centre
fill(255,0,0,100);
ellipse(0, 0, 80, 80); // cercle centrat al nou origen
fill(0,0,255,150);
rect(-20, -10, 40, 20); // rectangle al voltant de l'origen
line(-60, 0, 60, 0); // eix X
line(0, -50, 0, 50); // eix Y
Sense translate(), hauríem de sumar 150 a totes les X i 100 a totes les Y. Amb la transformació, dibuixem al voltant del (0,0) local i és molt més còmode.
rotate(angle): girar el món
rotate(angle) gira el sistema de coordenades un cert angle (en radians) al voltant de l'origen actual. Per passar de graus a radians, podem fer radians(graus).
Important: la rotació sempre es fa respecte a l'origen (0,0) actual. Per girar un objecte al voltant del seu propi centre, primer cal fer translate() per situar l'origen al centre desitjat.
translate(150, 100); // centre del llenç
for (let i = 0; i < 8; i++) {
rotate(radians(45)); // gira 45° cada cop
fill(255, 150, 0, 150);
rect(30, -5, 30, 10); // rectangle desplaçat a la dreta
}
Cada rotate() s'acumula als anteriors. Per aïllar transformacions, més endavant veurem push() i pop().
scale(factor): escalar el dibuix
scale(s) multiplica la mida de tot el que dibuixem a partir d'aleshores. Si el factor és 2, tot serà el doble de gran; si és 0.5, la meitat. També podem escalar de manera diferent en X i Y: scale(sx, sy).
translate(20, 80);
for (let i = 0; i < 4; i++) {
scale(0.8); // cada cop un 80% de la mida anterior
fill(255, 100, 100, 100);
rect(0, -20, 50, 40); // rectangle a la posició actual
translate(55, 0); // desplaçament per al següent
}
Truc: scale() també afecta el gruix del traç i altres propietats. Si vols evitar-ho, pots ajustar strokeWeight() després d'escalar.
L'ordre de les transformacions importa!
Quan combines translate(), rotate() i scale(), l'ordre és crucial perquè les transformacions s'apliquen en seqüència. No és el mateix traslladar i després girar, que girar i després traslladar.
translate → rotate
L'objecte gira al voltant de la seva pròpia posició.
rotate → translate
L'objecte orbita al voltant d'un punt llunyà.
Recorda: Les transformacions s'apliquen en ordre invers al que les escrivim. Primer rotate() gira el món, i després translate() es fa sobre el món ja girat.
push() i pop() en profunditat
Com que les transformacions s'acumulen, si volem dibuixar diversos objectes independents, necessitem aïllar les transformacions de cadascun. push() guarda l'estat actual (posició, rotació, escala, estil...) i pop() el recupera.
// Objecte 1: vermell, girat 20°
push(); translate(70, 100); rotate(radians(20));
fill(255,100,100); rect(-20,-15,40,30); pop();
// Objecte 2: blau, girat -35°
push(); translate(210, 100); rotate(radians(-35));
fill(100,100,255); rect(-20,-15,40,30); pop();
// Objecte 3: verd, sense transformacions
fill(0,255,100); ellipse(140,150,30,30);
Creació de mandales pas a pas
Un mandala és un disseny radial simètric. Amb un bucle i rotate(), podem repetir un motiu al voltant d'un centre per crear mandales hipnòtics.
translate(width/2, height/2);
let numPecs = 12;
for (let i = 0; i < numPecs; i++) {
push(); rotate(radians(i * 360 / numPecs));
fill(255, 200, 0, 200); noStroke();
ellipse(40, 0, 25, 15);
fill(255, 100, 0, 150);
triangle(50, -8, 70, 0, 50, 8);
pop();
}
fill(255, 255, 200); ellipse(0, 0, 30, 30);
Fórmula màgica del mandala: translate(centre); for(...){ push(); rotate(angle); dibuixaMotiu(); pop(); }
Exemples creatius pas a pas
Molí de vent animat
Utilitzem rotate() amb un angle que canvia al draw() per crear aspes que giren.
let angle = 0;
function draw() {
background(135,206,235);
translate(120, 120);
fill(180,130,80); rect(-5, 0, 10, 40);
push(); rotate(angle);
for (let i=0; i<3; i++) {
rotate(radians(120));
fill(220,220,240); triangle(0,0, -15,-40, 15,-40);
}
pop(); angle += 0.02;
}
Flor concèntrica amb escala
Combinem scale() i rotate() per crear capes de pètals de mides decreixents.
translate(width/2, height/2);
for (let capa=0; capa<4; capa++) {
push(); scale(1 - capa*0.2);
for (let i=0; i<8; i++) {
rotate(radians(45));
fill(255, 100+40*capa, 150-30*capa, 150);
ellipse(25, 0, 18, 8);
}
pop();
}
fill(255,255,0); ellipse(0,0,15,15);
Consells per treballar amb transformacions
- Dibuixa sempre al voltant del (0,0) local dins de cada
push()/pop(). Així el teu motiu serà fàcil de centrar i girar. - Utilitza
radians(graus)per no haver de pensar en radians. - L'ordre recomanat dins d'un
push()/pop(): primertranslate(), desprésrotate()i/oscale(), i finalment dibuixa. - Per animar, utilitza una variable global per a l'angle i incrementa-la a cada
draw(). - Combina amb bucles per multiplicar l'efecte.
Exercicis per practicar
- Dibuixa un rellotge analògic: 12 marques horàries al voltant d'un cercle, utilitzant un bucle i
rotate(). - Crea un "sol radiant" amb 16 raigs (línies) que surtin del centre, alternant longituds llargues i curtes.
- Dissenya una roda de carro: un cercle exterior, un de central, i radis (línies) cada 30 graus.
- Fes una espiral de quadrats: un quadrat que es repeteix 20 cops, cada cop girat 15° i escalat al 95%.
- Repte: Crea un calidoscopi digital: dibuixa un motiu al centre, i utilitza
scale(-1,1)o múltiplesrotate()per reflectir-lo en diferents eixos i omplir tot el llenç.
Reflexió artística
Les transformacions geomètriques són el cor de moltes formes d'art: des dels mandales budistes fins als vitralls gòtics, passant per l'op-art de Victor Vasarely. Amb rotate() i scale(), un sol motiu pot convertir-se en una composició hipnòtica.
La bellesa de la simetria radial és que l'ull humà la troba natural i satisfactòria: la veiem a les flors, als estels de mar, a les rodes. Però també pots trencar la simetria introduint petites variacions, com fèiem amb random() al Tema 5, per crear obres que siguin alhora ordenades i sorprenents.
Pensa en les transformacions com una dansa: tu decideixes els passos (translate, rotate, scale) i el motiu és el ballarí que els executa.
Mini-projecte del Tema 7
Crea un "Mandala generatiu personal" amb les següents directrius:
- Utilitza
translate()per centrar el mandala al llenç. - Defineix un motiu propi (combinació de formes, línies, colors) dins d'un bloc
push()/pop()ambrotate(). - Repeteix el motiu almenys 8 vegades al voltant del centre (360° / 8 = 45° entre cada un).
- Incorpora almenys dues capes amb diferents escales (per exemple, una capa externa gran i una interna petita).
- Utilitza colors amb transparència per crear superposicions interessants.
- Opcional: anima el mandala fent que l'angle de rotació variï amb el temps (
frameCount) o amb el ratolí.
Comparteix el teu mandala i explica el significat del motiu que has triat i com l'has construït.