{"id":415,"date":"2019-07-05T00:12:32","date_gmt":"2019-07-04T22:12:32","guid":{"rendered":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/?page_id=415"},"modified":"2019-08-17T13:31:44","modified_gmt":"2019-08-17T11:31:44","slug":"2-3-3-translacio-rotacio-i-escala","status":"publish","type":"page","link":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/2-3-3-translacio-rotacio-i-escala\/","title":{"rendered":"2.3.3. Translaci\u00f3, rotaci\u00f3 i escala"},"content":{"rendered":"<p>Fins ara hem vist com posar formes gr\u00e0fiques al <em>canvas <\/em>fent servir les coordenades on les volem situar. Sempre hem partit del fet que el punt (0, 0) (l\u2019origen de les coordenades) est\u00e0 al v\u00e8rtex superior esquerre, per\u00f2 amb p5.js podem decidir a quin lloc del <em>canvas<\/em> situarem el punt (0, 0). El cap\u00edtol 6 del llibre ens explica com podem moure l\u2019origen de les coordenades. Movent l\u2019origen de les coordenades mourem les formes que tenim dibuixades, at\u00e8s que les haurem dibuixat a partir de l\u2019origen de les coordenades. Per tant, aix\u00f2 ens ser\u00e0 \u00fatil per a moure formes complexes creades a partir de diverses formes simples.<\/p>\n<p>Vegem tres maneres de fer aquest canvi de l\u2019origen de les coordenades.<\/p>\n<h2><strong>Translaci\u00f3<\/strong><\/h2>\n<p>L\u2019opci\u00f3 m\u00e9s senzilla per a moure l\u2019origen de les coordenades \u00e9s la <strong>translaci\u00f3<\/strong>. Consisteix a despla\u00e7ar-lo un determinat nombre de p\u00edxels. Aquests dos exemples s\u00f3n prou clars:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-237\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_019.jpg\" alt=\"\" width=\"634\" height=\"351\" srcset=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_019.jpg 634w, http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_019-300x166.jpg 300w\" sizes=\"(max-width: 634px) 100vw, 634px\" \/><\/p>\n<p>La funci\u00f3 que fem servir per a determinar on tenim l\u2019origen de les coordenades \u00e9s <a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/translate\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: Courier, Arial;\">translate()<\/span><\/a>. Aquesta instrucci\u00f3 mou l\u2019origen de les coordenades des de la posici\u00f3 actual a la posici\u00f3 indicada en els seus par\u00e0metres. Aix\u00ed:<\/p>\n<pre>translate(40,20);<\/pre>\n<p>Mou l\u2019origen de les coordenades a la posici\u00f3 (40,\u00a0 20).<\/p>\n<p>Atenci\u00f3, perqu\u00e8 at\u00e8s que l\u2019origen de les coordenades es mou a partir de la seva posici\u00f3 actual, si posem dos <span style=\"font-family: Courier, Arial;\">translate()<\/span> seguits el segon agafar\u00e0 com a origen de les coordenades el que hem seleccionat primer.<\/p>\n<p>I un detall m\u00e9s. L\u2019origen de les coordenades es restableix (torna al seu lloc), cada cop que es torna a executar la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span> (que, com ja sabem, s\u2019executa 50 cops per segon).<\/p>\n<p>Aquest exemple pot ser prou aclaridor:<\/p>\n<pre>function setup() {\r\n  createCanvas(200, 200);\r\n}\r\n\r\nfunction draw() {\r\n  background(220);\r\n    for (var i = 10; i &lt; 400; i += 10){ \/\/ Dibuixem les l\u00ednies\r\n  \t line(i,0,i,height);   \/\/ Verticals\r\n  \t line(0,i,width,i);    \/\/ Horitzontals\r\n    }\r\n    fill(255,0,0);\r\n    rect(20,20,20,20);\r\n    translate(20,20);\r\n    fill(0,255,0);\r\n    rect(20,20,20,20);\r\n    fill(0,0,255);\r\n    translate(20,20);\r\n    rect(20,20,20,20);\r\n}\r\n<\/pre>\n<p>Si l\u2019executem, aquest \u00e9s el resultat:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-242\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_027.jpg\" alt=\"\" width=\"207\" height=\"209\" srcset=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_027.jpg 207w, http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_027-150x150.jpg 150w\" sizes=\"(max-width: 207px) 100vw, 207px\" \/><\/p>\n<p>Si ens fixem en el codi, el dibuix del rectangle \u00e9s sempre el mateix: <span style=\"font-family: Courier, Arial;\">rect(20,20,20,20);<\/span> el que canviem \u00e9s que cada cop traslladem l\u2019origen de les coordenades. Per\u00f2, a m\u00e9s a m\u00e9s, tamb\u00e9 el canvi de l\u2019origen de les coordenades sempre \u00e9s el mateix <span style=\"font-family: Courier, Arial;\">translate(20,20);<\/span> perqu\u00e8, com hem vist abans, el segon canvi parteix de l\u2019origen de les coordenades que hem seleccionat primer.<\/p>\n<p>Aix\u00ed, el primer rectangle es dibuixa a la posici\u00f3 (20, 20), el segon a la (40, 40) i el tercer a la (60, 60).<\/p>\n<p>Ara que ja hem vist com funciona la funci\u00f3 <span style=\"font-family: Courier, Arial;\">translate()<\/span>, ja ens podem posar amb els exemples del llibre.<\/p>\n<p>El 6-1 \u00e9s molt senzill: fem servir la posici\u00f3 del ratol\u00ed per a determinar el nou origen de les coordenades. D\u2019aquesta manera, quan dibuixem el quadrat, es dibuixa all\u00e0 on est\u00e0 el ratol\u00ed.<\/p>\n<p>En el 6-2 es fan dues translacions, de manera que es dibuixen dos quadrats lleugerament separats. La veritat \u00e9s que, un cop tenim clar el funcionament de la funci\u00f3 <span style=\"font-family: Courier, Arial;\">translate()<\/span>, aquests dos exemples s\u00f3n molt f\u00e0cils d\u2019entendre.<\/p>\n<h2><strong>Rotaci\u00f3<\/strong><\/h2>\n<p><strong>Rotar<\/strong> \u00e9s fer girar un objecte. En el cas de p5.js el que farem girar \u00e9s l\u2019origen de les coordenades. La funci\u00f3 que fem servir per a fer aquesta rotaci\u00f3 \u00e9s <a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/rotate\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: Courier, Arial;\">rotate()<\/span><\/a>.<\/p>\n<p>Com que estem parlant de fer un gir, el par\u00e0metre que li indicarem a la funci\u00f3 <span style=\"font-family: Courier, Arial;\">rotate()<\/span> ser\u00e0 uns graus, normalment en radiants, tot i que podem fer servir graus. En aquest punt val la pena revisar, en la guia del repte 2, l\u2019explicaci\u00f3 de la funci\u00f3 <span style=\"font-family: Courier, Arial;\">arc()<\/span>.<\/p>\n<p>Mireu aquest exemple:<\/p>\n<pre>function setup() {\r\n  createCanvas(200, 200);\r\n}\r\nfunction draw() {\r\n  background(220);\r\n  translate(100,100)\r\n  for (var i=0;i&lt;16;i++){\r\n    line(20, 20, 40, 40);\r\n    rotate(QUARTER_PI\/2.0);\r\n  }\r\n}<\/pre>\n<p>Dibuixa aix\u00f2:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-239\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_023.jpg\" alt=\"\" width=\"208\" height=\"207\" srcset=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_023.jpg 208w, http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_023-150x150.jpg 150w\" sizes=\"(max-width: 208px) 100vw, 208px\" \/><\/p>\n<p>El primer que fem \u00e9s traslladar l\u2019origen de les coordenades al centre del <em>canvas<\/em>.<\/p>\n<p>A continuaci\u00f3, pintem una l\u00ednia i rotem, pintem una l\u00ednia i rotem. Aix\u00ed, 16 cops fins a completar el cercle.<\/p>\n<p>Com hem vist en l\u2019apartat anterior, els despla\u00e7aments de l\u2019origen de les coordenades s\u00f3n acumulatius.<\/p>\n<p>Un cop ent\u00e8s com funciona la funci\u00f3 <span style=\"font-family: Courier, Arial;\">rotate()<\/span> podem veure els exemples del llibre.<\/p>\n<p>El 6-3 fa una rotaci\u00f3 a partir de la posici\u00f3 <strong>x<\/strong> del ratol\u00ed. Dibuixem el quadrat i comencem a fer la rotaci\u00f3 a partir de la posici\u00f3 (0, 0) actual.<\/p>\n<p>En aquest exemple, el llibre fa una explicaci\u00f3 que no \u00e9s ben b\u00e9 real. Diu que <span style=\"font-family: Courier, Arial;\">mouseX<\/span> nom\u00e9s pot prendre valors de 0 a 120 (la mida del <em>canvas<\/em>) per\u00f2 aix\u00f2 ja hem vist que no \u00e9s aix\u00ed, ja que guarda el valor de la posici\u00f3 <strong>x<\/strong> del ratol\u00ed fins i tot quan el ratol\u00ed est\u00e0 fora del <em>canvas<\/em>.<\/p>\n<p>L\u2019exemple 6-4 \u00e9s molt semblant. Per\u00f2 en aquest cas, el que s\u2019ha fet \u00e9s situar l\u2019inici del quadrat fora del <em>canvas<\/em> de manera que l\u2019origen de les coordenades queda al mig del rectangle. Aix\u00ed, dona la sensaci\u00f3 que el rectangle gira sobre el seu eix. Una manera diferent de fer el mateix seria fent servir la funci\u00f3 <a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/rectMode\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: Courier, Arial;\">rectMode()<\/span><\/a> que ens permet definir com es dibuixa el rectangle i dibuixar-lo a partir del seu centre.<\/p>\n<p>Modifiqueu aquest exemple per tal que l\u2019origen de les coordenades quedi al mig del <em>canvas<\/em>. Feu servir <span style=\"font-family: Courier, Arial;\">rectMode()<\/span> per a dibuixar el rectangle.<\/p>\n<p>L\u2019exemple 6-5 genera un efecte curi\u00f3s. El quadre va rotant cont\u00ednuament i alhora que movem el ratol\u00ed anem dibuixant quadrats. En aquest cas, la variable <span style=\"font-family: Courier, Arial;\">angle<\/span> \u00e9s la que determina l\u2019angle en qu\u00e8 es rota el quadrat. Recordeu que, cada cop que s\u2019executa la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span>, l\u2019origen de les coordenades torna al seu lloc. Per aix\u00f2 necessitem guardar l\u2019angle en una variable.<\/p>\n<p>En aquest cas (i ho veurem en l\u2019exemple seg\u00fcent) \u00e9s important l\u2019ordre en qu\u00e8 cridem les funcions <span style=\"font-family: Courier, Arial;\">translate()<\/span> i <span style=\"font-family: Courier, Arial;\">rotate()<\/span> perqu\u00e8, recordeu, dins la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span> els canvis de l\u2019origen de les coordenades s\u00f3n acumulatius. Aix\u00ed, quan fem el <span style=\"font-family: Courier, Arial;\">rotate()<\/span> en segon terme, el que fem \u00e9s que el quadrat estigui cont\u00ednuament rotant, per\u00f2 nom\u00e9s es mou quan movem el ratol\u00ed.<\/p>\n<p>L\u2019exemple 6-6 canvia l\u2019ordre, primer fa el <span style=\"font-family: Courier, Arial;\">rotate()<\/span> i despr\u00e9s el <span style=\"font-family: Courier, Arial;\">translate()<\/span>. La difer\u00e8ncia \u00e9s notable. Ara el quadrat s\u2019est\u00e0 movent cont\u00ednuament fent un cercle. I el moviment del ratol\u00ed nom\u00e9s determina com de gran \u00e9s el cercle que estem dibuixant.<\/p>\n<p>L\u2019exemple 6-7 pot semblar complex per\u00f2, a la pr\u00e0ctica, nom\u00e9s fa servir funcions que ja hem vist. Defineix tres variables:<\/p>\n<pre>var angle = 0.0;\r\nvar angleDirection = 1;\r\nvar speed = 0.005;<\/pre>\n<p>La variable <span style=\"font-family: Courier, Arial;\">angle <\/span> determina l\u2019angle que cal fer servir en cada moment. \u00c9s la mateixa variable (o almenys es fa servir pel mateix motiu) que la que ja hem fet servir en un exemple anterior.<\/p>\n<p>La variable <span style=\"font-family: Courier, Arial;\">angleDirection<\/span> es fa servir per a determinar si el bra\u00e7 va en una direcci\u00f3 o en la contr\u00e0ria. Canvia el seu valor a -1 quan arriba al l\u00edmit determinat.<\/p>\n<p>La variable <span style=\"font-family: Courier, Arial;\">speed<\/span> determina la velocitat amb qu\u00e8 es mou el bra\u00e7.<\/p>\n<p>Aquest exemple fa servir la funci\u00f3 <span style=\"font-family: Courier, Arial;\"><a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/strokeWeight\" target=\"_blank\" rel=\"noopener\">strokeWeight()<\/a><\/span> que el que fa \u00e9s determinar l\u2019amplada de la l\u00ednia que es dibuixar\u00e0 a continuaci\u00f3. I l\u2019exemple no t\u00e9 m\u00e9s misteri.<\/p>\n<h2><strong>Escala<\/strong><\/h2>\n<p>L\u2019escalat \u00e9s el canvi de mida d\u2019un objecte. Amb la funci\u00f3 <span style=\"font-family: Courier, Arial;\">scale()<\/span> el que podem fer \u00e9s canviar la mida de les coordenades del <em>canvas<\/em>, de manera que no hi haur\u00e0 una correspond\u00e8ncia entre els p\u00edxels de la pantalla i els p\u00edxels del <em>canvas<\/em>.<\/p>\n<p>Recuperem aquest exemple que hem vist abans. Per\u00f2 hi afegim una nova variable i una nova l\u00ednia:<\/p>\n<pre>var escala = 2;  \/\/ <strong>Variable afegida<\/strong>\r\n\r\nfunction setup() {\r\n  createCanvas(200, 200);\r\n}\r\n\r\nfunction draw() {\r\n  background(220);\r\n  scale(escala);   \/\/ <strong>Crida a la funci\u00f3 scale()<\/strong>\r\n  for (var i = 10; i &lt; 400; i += 10){ \/\/ Dibuixem les l\u00ednies\r\n    line(i,0,i,height);   \/\/ Verticals\r\n    line(0,i,width,i);    \/\/ Horitzontals\r\n  }\r\n  fill(255,0,0);\r\n  rect(20,20,20,20);\r\n  translate(20,20);\r\n  fill(0,255,0);\r\n  rect(20,20,20,20);\r\n  fill(0,0,255);\r\n  translate(20,20);\r\n  rect(20,20,20,20);\r\n}<\/pre>\n<p>Varieu el valor de la variable escala i comproveu el que passa. A continuaci\u00f3, teniu tres captures de pantalla amb tres casos diferents:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-2123 size-full\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_024_2.jpg\" alt=\"\" width=\"727\" height=\"262\" srcset=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_024_2.jpg 727w, http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_024_2-300x108.jpg 300w\" sizes=\"(max-width: 727px) 100vw, 727px\" \/><\/p>\n<p>L\u2019exemple 6-8 tamb\u00e9 fa un escalat per\u00f2 fa servir el ratol\u00ed per a controlar-lo. I l\u2019exemple 6-9 explica qu\u00e8 cal fer per a evitar que les l\u00ednies tamb\u00e9 es facin m\u00e9s gruixudes.<\/p>\n<p>Amb el nostre exemple i fent aquest canvi (la segona l\u00ednia \u00e9s l\u2019afegida):<\/p>\n<pre>scale(escala);   \/\/ <strong>Crida a la funci\u00f3 scale()<\/strong>\r\n<span style=\"color: red;\">strokeWeight(1.0 \/ escala);<\/span>\r\nfor (var i = 10; i &lt; 400; i += 10){ \/\/ Dibuixem les l\u00ednies<\/pre>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-2124 size-full\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_025_2.jpg\" alt=\"\" width=\"727\" height=\"257\" srcset=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_025_2.jpg 727w, http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_2_025_2-300x106.jpg 300w\" sizes=\"(max-width: 727px) 100vw, 727px\" \/>(amb <strong>escala = 5<\/strong>)<\/p>\n<h2><span style=\"font-family: Courier, Arial;\">push()<\/span> i <span style=\"font-family: Courier, Arial;\">pop()<\/span><\/h2>\n<p>Aquestes dues funcions ens permeten guardar la situaci\u00f3 actual de l\u2019origen de les coordenades. <span style=\"font-family: Courier, Arial;\">push()<\/span> la guarda i <span style=\"font-family: Courier, Arial;\">pop()<\/span> la recupera. Pot ser \u00fatil en programes molt llargs, amb la finalitat de tornar a una versi\u00f3 anterior de l\u2019origen de les coordenades. L\u2019exemple 6-10 fa una petita demostraci\u00f3.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fins ara hem vist com posar formes gr\u00e0fiques al canvas fent servir les coordenades on les volem situar. Sempre hem partit del fet que el punt (0, 0) (l\u2019origen de les coordenades) est\u00e0 al v\u00e8rtex superior esquerre, per\u00f2 amb p5.js podem decidir a quin lloc del canvas situarem el punt (0, 0). El cap\u00edtol 6 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"inline_featured_image":false},"acf":[],"_links":{"self":[{"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/pages\/415"}],"collection":[{"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/comments?post=415"}],"version-history":[{"count":22,"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/pages\/415\/revisions"}],"predecessor-version":[{"id":3741,"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/pages\/415\/revisions\/3741"}],"wp:attachment":[{"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/media?parent=415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}