{"id":947,"date":"2019-07-07T20:43:59","date_gmt":"2019-07-07T18:43:59","guid":{"rendered":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/?page_id=947"},"modified":"2019-08-17T23:11:19","modified_gmt":"2019-08-17T21:11:19","slug":"4-4-moviment","status":"publish","type":"page","link":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/4-4-moviment\/","title":{"rendered":"4.4. Moviment"},"content":{"rendered":"<p>Segur que recordareu que, tal com ja hem vist, la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span> es repeteix 60 cops per segon. I tamb\u00e9 que ja hem comentat que aix\u00f2 es pot canviar. La funci\u00f3 que ens permet canviar el nombre de vegades que es repeteix la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span> per segon es diu <a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/frameRate\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: Courier, Arial;\">frameRate()<\/span><\/a>. Podem fer servir aquesta funci\u00f3 de dues maneres diferents:<\/p>\n<ol>\n<li>Podem fer-la servir per a consultar quants cops per segon es repeteix actualment la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span>.<\/li>\n<li>Tamb\u00e9 podem fer-la servir per a fixar aquest valor.<\/li>\n<\/ol>\n<div class=\"featured featured-blue\"><p><strong><em>Frame rate<\/em><\/strong> o <a href=\"https:\/\/ca.wikipedia.org\/wiki\/Fotograma_per_segon\" target=\"_blank\" rel=\"noopener\">fotogrames per segon<\/a>, que \u00e9s la traducci\u00f3 m\u00e9s habitual, \u00e9s un concepte que ve del v\u00eddeo i es refereix al nombre de imatges que projecta un reproductor de v\u00eddeo en un segon. \u00c9s un concepte heretat de les pel\u00b7l\u00edcules anal\u00f2giques, per\u00f2 que es continua fent servir en el v\u00eddeo i animacions digitals. Al cinema, per a garantir la continu\u00eftat de la imatge, es fan servir 24 fotogrames per segon.<\/p>\n<\/div>\n<p>L\u2019exemple 8-1 del llibre fa servir la primera opci\u00f3: consulta el <span style=\"font-family: Courier, Arial;\">frameRate()<\/span> i mostra el resultat de la consulta a la consola. Si el feu servir, veureu que no sempre dona el mateix resultat, que va variant entre 55 i 65 aproximadament.<\/p>\n<div class=\"featured featured-grey\"><\/p>\n<p><strong>Fotogrames a p5.js<\/strong><\/p>\n<p>p5.js intenta que el nombre de fotogrames per segon sigui 60. Per\u00f2 aix\u00f2 dep\u00e8n de moltes coses: la velocitat del processador, de tot all\u00f2 que s\u2019estigui executant a l\u2019ordinador, del navegador (no tots els navegadors executen JavaScript de la mateixa manera), del codi que hi hagi dins de <span style=\"font-family: Courier, Arial;\">draw()<\/span>. p5.js s\u2019ha de \u00abbarallar\u00bb amb totes aquestes possibilitats per a aconseguir que el nombre de fotogrames sigui l\u2019indicat i es mantingui estable. Aix\u00f2 \u00e9s for\u00e7a complicat, per la qual cosa el valor fluctua.<\/p>\n<p>\n<\/div>\n<p>L\u2019exemple 8-2 afegeix la segona opci\u00f3 a la funci\u00f3 <span style=\"font-family: Courier, Arial;\">setup()<\/span> i ens suggereix canviar el valor dels fotogrames per segon a nombres m\u00e9s baixos. Feu-ho i comproveu com es comporta a diferents velocitats.<\/p>\n<h2>Velocitat i direcci\u00f3<\/h2>\n<p>Les nostres animacions tindran diferents objectes que es poden moure a diferents velocitats, de manera que tenint el nombre de fotogrames per segon de base, haurem de fer servir variables per a determinar la velocitat de cada objecte. Una cosa semblant passar\u00e0 amb la direcci\u00f3 en qu\u00e8 es mouen els objectes.<\/p>\n<p>L\u2019exemple 8-3 \u00e9s un bon exemple de moviment fluid on fem servir una variable, <span style=\"font-family: Courier, Arial;\">speed<\/span>, per a determinar la velocitat de l\u2019objecte. Modificant el valor d\u2019aquesta variable, l\u2019objecte es mou m\u00e9s r\u00e0pid o m\u00e9s a poc a poc (proveu a modificar el valor d\u2019<span style=\"font-family: Courier, Arial;\">speed<\/span> a 1 i a 0.25).<\/p>\n<p>El moviment va d\u2019esquerra a dreta gr\u00e0cies a la modificaci\u00f3 de la variable <strong>x<\/strong> que ens marca la posici\u00f3 horitzontal. Quan l\u2019<strong>x<\/strong> t\u00e9 un valor superior al l\u00edmit dret del <em>canvas<\/em>, l\u2019objecte es deixa de veure.<\/p>\n<p>Un darrer detall interessant, malgrat ja ho hem vist, \u00e9s el fet que pintant el fons de nou cada cop, esborrem la figura ja dibuixada abans de dibuixar-ne una de nova.<\/p>\n<p>A partir d\u2019aquest exemple b\u00e0sic, es poden fer diverses variacions. Aix\u00ed l\u2019exemple 8-4 fa que quan la variable <strong>x<\/strong> t\u00e9 un valor m\u00e9s gran que la mida horitzontal del <em>canvas<\/em> m\u00e9s el radi de la figura (aix\u00f2 vol dir que la figura haur\u00e0 desaparegut), li posa el valor inicial perqu\u00e8 torni a sortir per la dreta. Aquesta variaci\u00f3 es fa amb aquest codi:<\/p>\n<pre>if (x &gt; width+radius) { \/\/ Si la imatge surt del canvas\r\n x = -radius;     \/\/ la movem a l\u2019esquerra.\r\n}<\/pre>\n<p>I l\u2019exemple 8-5 fa que reboti quan arriba al final. Com podeu veure, el rebot implica dues coses: primer canviar la direcci\u00f3 (que no \u00e9s m\u00e9s que fer la velocitat negativa) i, despr\u00e9s, canviar la figura perqu\u00e8 la boca apunti a la dreta.<\/p>\n<pre>x += speed * direction; \/\/ Si direction \u00e9s 1 es mou d\u2019esquerra\r\n            \/\/ a dreta.\r\n            \/\/ Si direction \u00e9s -1 es mou de dreta\r\n            \/\/ a esquerra.\r\nif ((x &gt; width - radius) || (x &lt; radius)) {\r\n direction = -direction; \/\/ Canviar la direcci\u00f3\r\n}\r\nif (direction == 1) {\r\n arc(x, 60, radius, radius, 0.52, 5.76); \/\/ Cap a la dreta\r\n} else {\r\n arc(x, 60, radius, radius, 3.67, 8.9); \/\/ Cap a la esquerra\r\n}<\/pre>\n<h2>Movent-se en qualsevol direcci\u00f3<\/h2>\n<p>Moure un objecte de dreta a esquerra \u00e9s f\u00e0cil. En general, qualsevol moviment horitzontal o vertical ser\u00e0 f\u00e0cil de simular perqu\u00e8 nom\u00e9s caldr\u00e0 modificar la posici\u00f3 <strong>x<\/strong> o la posici\u00f3 <strong>y<\/strong>. Per\u00f2 si volem moure un objecte en una direcci\u00f3 que no sigui l\u2019horitzontal o la vertical, caldr\u00e0 modificar <strong>x<\/strong> i <strong>y<\/strong> de manera que el moviment sembli suau, per la qual cosa caldr\u00e0 calcular quina posici\u00f3 haur\u00e0 de tenir l\u2019objecte en cada moment.<\/p>\n<div class=\"featured featured-blue\"><p>Aquest c\u00e0lcul que ens permet dibuixar l\u2019objecte on toca quan toca, rep el nom, en angl\u00e8s, de <strong><em>tweening<\/em><\/strong> i, en catal\u00e0, li direm <a href=\"http:\/\/www.diccionari.cat\/lexicx.jsp?GECART=0078450\" target=\"_blank\" rel=\"noopener\"><strong>interpolar<\/strong><\/a> (posar una cosa entre altres).<\/p>\n<\/div>\n<p>Veient el codi de l\u2019exemple 8-6 del llibre, ens pot semblar que la interpolaci\u00f3 \u00e9s una cosa complicada. Per\u00f2 no \u00e9s aix\u00ed. Vegem l\u2019exemple pas a pas per a veure que no \u00e9s complicat.<\/p>\n<p><strong><div class=\"featured featured-grey\"><p><\/strong><\/p>\n<p><strong>Fe d\u2019errades<\/strong><\/p>\n<p>Al llibre hi ha una errada a la instrucci\u00f3:<\/p>\n<pre>y = startY + ((stopY-startX) * pct);<\/pre>\n<p>Com que estem calculant la posici\u00f3 de l\u2019<strong>y<\/strong>, <span style=\"font-family: Courier, Arial;\">startX<\/span> hauria de ser en realitat <span style=\"font-family: Courier, Arial;\">startY<\/span> i, per tant, la instrucci\u00f3 hauria de ser aquesta:<\/p>\n<pre>y = startY + ((stopY-startY) * pct);<\/pre>\n<p>Farem servir aquesta versi\u00f3 corregida en aquesta guia.<\/p>\n<\/div><\/p>\n<p>El primer que fa l\u2019exemple \u00e9s declarar les variables que fa servir: vuit! B\u00e9, fem un rep\u00e0s de qu\u00e8 fa cadascuna d\u2019aquestes. Comencem per les quatre primeres que s\u00f3n les m\u00e9s f\u00e0cils d\u2019entendre i indiquen la posici\u00f3 inicial i final de l\u2019objecte:<\/p>\n<pre>var startX = 20; \/\/ Indica la posici\u00f3 x inicial\r\nvar stopX = 160; \/\/ Indica la posici\u00f3 x final \r\nvar startY = 30; \/\/ Indica la posici\u00f3 y inicial\r\nvar stopY = 80; \/\/ Indica la posici\u00f3 y final<\/pre>\n<p>Les dues seg\u00fcents tamb\u00e9 s\u00f3n f\u00e0cils d\u2019entendre: indiquen la posici\u00f3 actual de l\u2019objecte:<\/p>\n<pre>var x = startX; \/\/ Posici\u00f3 x actual\r\nvar y = startY; \/\/ Posici\u00f3 y actual<\/pre>\n<p>Nom\u00e9s ens en queden dues que s\u00f3n una mica m\u00e9s complicades:<\/p>\n<pre>var step = 0.005; \/\/ Mida de cada pas que fem (de 0.0 fins a 1.0)\r\nvar pct = 0.0;  \/\/ Percentatge ja fet (0.0 to 1.0)<\/pre>\n<p>De les dues variables, <span style=\"font-family: Courier, Arial;\">pct<\/span> \u00e9s potser la m\u00e9s clara. Ens indica quin percentatge de recorregut ja hem fet. Comen\u00e7arem per 0 (per aix\u00f2 sempre la inicialitzarem a 0.0) i acabarem quan sigui 1.0.<\/p>\n<p><span style=\"font-family: Courier, Arial;\">step<\/span> \u00e9s potser la variable m\u00e9s complicada d\u2019entendre. Determina la mida de cada pas que farem i, a la pr\u00e0ctica, quants passos farem per anar d\u2019un lloc a un altre. Si ens fixem en el codi que hi ha a la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span>, a cada volta el percentatge que hem avan\u00e7at s\u2019incrementa la quantitat guardada a la variable <span style=\"font-family: Courier, Arial;\">step<\/span>.<\/p>\n<p>Com que anem de 0 a 1 en increments de 0.005, aix\u00f2 en realitat significa que farem 200 passos abans d\u2019arribar al dest\u00ed (0.005 * 200 \u21d2 1).<\/p>\n<p>Vegem ara el codi de la funci\u00f3 <span style=\"font-family: Courier, Arial;\">draw()<\/span>:<\/p>\n<pre>function draw() {\r\n background(0);\r\n if (pct &lt; 1.0) {\r\n  x = startX + ((stopX-startX) * pct); \/\/ nova posici\u00f3 x\r\n  y = startY + ((stopY-startY) * pct); \/\/ nova posici\u00f3 y\r\n  pct += step;\r\n }\r\n ellipse(x, y, 20, 20);\r\n}<\/pre>\n<p>Fem una breu simulaci\u00f3 de com funcionaria el programa.<\/p>\n<p>Valors inicials:<\/p>\n<pre>var startX = 20; \/\/ Indica la posici\u00f3 x inicial\r\nvar stopX = 160; \/\/ Indica la posici\u00f3 x final \r\nvar startY = 30; \/\/ Indica la posici\u00f3 y inicial\r\nvar stopY = 80; \/\/ Indica la posici\u00f3 y final \r\nvar step = 0.005; \/\/ Mida de cada pas que fem (de 0.0 fins a 1.0)\r\nvar pct = 0.0;  \/\/ Percentatge ja fet (0.0 to 1.0)<\/pre>\n<table>\n<thead>\n<tr>\n<th>N\u00fam. execucions<br \/>\n<span style=\"font-family: Courier, Arial;\"> draw()<\/span><\/th>\n<th>Valors de la variable<br \/>\n<span style=\"font-family: Courier, Arial;\"> pct<\/span><br \/>\nquan entra en la funci\u00f3<br \/>\n<span style=\"font-family: Courier, Arial;\"> draw()<\/span><\/th>\n<th>Valors de les variables <em>x<\/em> i <em>y<\/em> calculades dins l\u2019<br \/>\n<span style=\"font-family: Courier, Arial;\"> if<br \/>\nx = startX + ((stopX-startX) * pct);<br \/>\ny = startY + ((stopY-startY) * pct);<\/span><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>0<\/td>\n<td><em>x<\/em> = 20 + ((160 &#8211; 20) * 0) \u21d2 0<br \/>\n<em>y<\/em> = 30 + ((80 &#8211; 30) * 0) \u21d2 0<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>0.005<\/td>\n<td><em>x<\/em> = 20 + ((160 &#8211; 20) * 0.005) \u21d2 20.7 (21)<br \/>\n<em>y<\/em> = 30 + ((80 &#8211; 30) * 0.005) \u21d2 30.25 (30)<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>0.010<\/td>\n<td><em>x<\/em> = 20 + ((160 &#8211; 20) * 0.010) \u21d2 21.4 (21)<br \/>\n<em>y<\/em> = 30 + ((80 &#8211; 30) * 0.010) \u21d2 30.5 (31)<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>0.015<\/td>\n<td><em>x<\/em> = 20 + ((160 &#8211; 20) * 0.015) \u21d2 22.1 (22)<br \/>\n<em>y<\/em> = 30 + ((80 &#8211; 30) * 0.015) \u21d2 30.75 (31)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Cada posici\u00f3 de l\u2019<strong>x<\/strong>la calculem sumant a la posici\u00f3 inicial la dist\u00e0ncia a rec\u00f3rrer (posici\u00f3 final menys posici\u00f3 inicial) multiplicat pel percentatge que hem recorregut.<\/p>\n<p>Com que treballem en p\u00edxels (i els p\u00edxels no es poden dividir) l\u2019ordinador autom\u00e0ticament fa un arrodoniment, que \u00e9s el valor que hem posat entre par\u00e8ntesi al costat del resultat.<\/p>\n<h3>Exercicis<\/h3>\n<p>Per a entendre b\u00e9 aquest exemple, val la pena provar de canviar algunes coses. Aqu\u00ed hi ha unes quantes propostes:<\/p>\n<ul>\n<li>Canvieu l\u2019origen i el final. Qu\u00e8 passa quan l\u2019<strong>x<\/strong> de l\u2019origen (variable <span style=\"font-family: Courier, Arial;\">startX<\/span>) \u00e9s m\u00e9s gran que l\u2019<strong>x<\/strong> de destinaci\u00f3 (variable <span style=\"font-family: Courier, Arial;\">stopX<\/span>)?<\/li>\n<\/ul>\n<p>Per a entendre millor com funciona aix\u00f2 dels passos, afegirem una variable m\u00e9s a qu\u00e8 direm <span style=\"font-family: Courier, Arial;\">numeroP<\/span>&gt;. En aquesta variable guardarem el nombre de passos que volem fer des de l\u2019inici fins al final. La declaraci\u00f3 de les variables haur\u00e0 de quedar d\u2019aquesta manera:<\/p>\n<pre>var startX = 20; \/\/ Indica la posici\u00f3 x inicial\r\nvar stopX = 160; \/\/ Indica la posici\u00f3 x final \r\nvar startY = 30; \/\/ Indica la posici\u00f3 y inicial\r\nvar stopY = 80; \/\/ Indica la posici\u00f3 y final \r\n<span style=\"color: red; font-weight: bold;\">var numeroP = 200;<\/span> \/\/ Nombre de passos a fer entre els dos punts.\r\n<span style=\"color: red; font-weight: bold;\">var step = 1.0 \/ numeroP;<\/span> \/\/ Mida de cada pas\r\nvar pct = 0.0;  \/\/ Percentatge ja fet (0.0 to 1.0)\r\n\r\n<\/pre>\n<p>Amb <span style=\"font-family: Courier, Arial;\">numeroP<\/span> igual a 200 estem igual que a l\u2019enunciat inicial (<span style=\"font-family: Courier, Arial;\">step<\/span> tindr\u00e0 el valor de 0.005). Canvieu el nombre de passos per a veure quins canvis es produeixen.<\/p>\n<h2>Moviment aleatori<\/h2>\n<p>Ja hem vist com la funci\u00f3 <a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/random\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: Courier, Arial;\">random()<\/span><\/a> ens permet crear nombres aleatoris. Com vam veure, el primer par\u00e0metre que li indiquem \u00e9s el valor m\u00ednim i el segon el valor m\u00e0xim. Amb la caracter\u00edstica que el valor m\u00e0xim no apareixer\u00e0 mai. En matem\u00e0tiques ho expressem aix\u00ed: [min,max) (el m\u00ednim incl\u00f2s, el m\u00e0xim excl\u00f2s).<\/p>\n<p>Provem b\u00e9 la funci\u00f3 <span style=\"font-family: Courier, Arial;\">random()<\/span>. Proveu aquest codi (no necessitem la funci\u00f3 <span style=\"font-family: Courier, Arial;\">setup()<\/span>):<\/p>\n<pre>function draw() {\r\n var r = random(0, 10);\r\n print(r);\r\n}<\/pre>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-266\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_4_025.jpg\" alt=\"\" width=\"188\" height=\"247\" \/><\/p>\n<p>Aquest \u00e9s el resultat: ens escriu nombres aleatoris entre 0 i 10; 60 per segon. S\u00f3n nombres amb molts decimals.<\/p>\n<p>Fem un pas m\u00e9s, quedem-nos nom\u00e9s amb la part entera:<\/p>\n<pre>function draw() {\r\n\u00a0var r = int(random(0, 10));\r\n\u00a0print(r);\r\n}<\/pre>\n<p>Ara els nombres que ens dona s\u00f3n m\u00e9s comprensibles:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-267\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_4_027.jpg\" alt=\"\" width=\"47\" height=\"238\" \/><\/p>\n<p>Fem un pas m\u00e9s, calculem el m\u00e0xim i el m\u00ednim. Aquest codi us hauria de resultar f\u00e0cil d\u2019entendre:<\/p>\n<pre>var maxim = 0;\r\nvar minim = 99;\r\n\r\nfunction draw() {\r\n var r = int(random(0, 10));\r\n if (r &gt; maxim) {\r\n  maxim = r;\r\n  print(\"Nou m\u00e0xim: \",r);\r\n }\r\n if (r &lt; minim) {\r\n  minim = r;\r\n  print(\"Nou m\u00ednim: \",r);\r\n }\r\n}<\/pre>\n<p>El que escriu aquest codi a la consola \u00e9s alguna cosa semblant a aix\u00f2:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-268\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_4_029.jpg\" alt=\"\" width=\"162\" height=\"231\" \/><\/p>\n<p>Podem provar amb diferents nombres de m\u00e0xim i m\u00ednim per a veure com funciona.<\/p>\n<p>Ara tenim prou clar com funciona la funci\u00f3 <span style=\"font-family: Courier, Arial;\">random()<\/span>, per tant, podem provar l\u2019exemple 8-7 del llibre. \u00c9s molt semblant al nostre exemple, per\u00f2 posa com a m\u00e0xim la posici\u00f3 <strong>x<\/strong> del ratol\u00ed.<\/p>\n<p>L\u2019exemple 8-8 \u00e9s for\u00e7a interessant perqu\u00e8 genera un efecte molt efectiu. Vegem el codi i el comentem una mica:<\/p>\n<pre>function setup() {\r\n createCanvas(240, 120);\r\n}\r\nfunction draw() {\r\n background(204);\r\n for (var x = 20; <span style=\"color: red; font-weight: bold;\">x &lt; width<\/span>; <span style=\"color: green; font-weight: bold;\">x += 20<\/span>) {\r\n  var mx = mouseX \/ 10;\r\n  var offsetA = random(-mx, mx);\r\n  var offsetB = random(-mx, mx);\r\n  line(<span style=\"color: #bb9017; font-weight: bold;\">x<\/span> + <span style=\"color: #f835fc; font-weight: bold;\">offsetA<\/span>, 20, <span style=\"color: #4a86e8; font-weight: bold;\">x<\/span> - <span style=\"color: #f835fc; font-weight: bold;\">offsetB<\/span>, 100);\r\n }\r\n}<\/pre>\n<p>El que fa aquest codi \u00e9s, primer de tot, guardar a la variable <span style=\"font-family: Courier, Arial;\">mx<\/span> el valor <strong>x<\/strong> de la posici\u00f3 del ratol\u00ed dividit per 10 (divideix per 10 perqu\u00e8 els canvis siguin m\u00e9s suaus). Proveu qu\u00e8 passa si dividim per 2, per 100 o no dividim.<\/p>\n<p>La posici\u00f3 del ratol\u00ed es fa servir per a crear totes <span style=\"color: red;\">les l\u00ednies que c\u00e0piguen dins el <em>canvas<\/em><\/span>, per\u00f2 <span style=\"color: green;\">separades 20 p\u00edxels<\/span> entre elles.<\/p>\n<p>Quan pintem cada l\u00ednia, a l\u2019<span style=\"color: #bb9017;\">x de l\u2019inici<\/span> i a l&#8217;<span style=\"color: #4a86e8;\">x del final<\/span> les hi afegim o restem un <span style=\"color: #f835fc;\">valor calculat aleat\u00f2riament<\/span>.<\/p>\n<p>L\u2019exemple 8-9 fa un pas m\u00e9s enll\u00e0 i fa tot el moviment de manera aleat\u00f2ria. Inicialment dibuixa el cercle al mig del <em>canvas<\/em> (independentment de la mida del <em>canvas<\/em>) i, despr\u00e9s, el cercle es va movent depenent de dos valors (un per a <strong>x<\/strong> i un altre per a <strong>y<\/strong>) calculats aleat\u00f2riament.<\/p>\n<p>Com sempre, \u00e9s aconsellable provar l\u2019exemple i canviar coses com ara la mida del <em>canvas<\/em> (per a comprovar que sempre es comen\u00e7a des del centre), la velocitat o el di\u00e0metre del cercle.<\/p>\n<h2>Temporitzadors<\/h2>\n<p>p5.js compta el temps des de que s\u2019inicia l\u2019execuci\u00f3 del nostre programa. Nosaltres podem consultar el temps transcorregut des de l\u2019inici mitjan\u00e7ant la funci\u00f3 <a href=\"https:\/\/p5js.org\/es\/reference\/#\/p5\/millis\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: Courier, Arial;\">millis()<\/span><\/a>. L\u2019exemple 8-10 ens permet veure com va passant el temps. La funci\u00f3 <strong><span style=\"font-family: Courier, Arial;\">millis()<\/span><\/strong> ens retorna el temps en mil\u00b7lisegons, el que vol dir que 1000 \u21d2 1 segon.<\/p>\n<p>L\u2019\u00fas de la funci\u00f3 <strong><span style=\"font-family: Courier, Arial;\">millis()<\/span><\/strong> ens permet fer que al nostre programa passin coses en un moment determinat. L\u2019<strong>exemple 8-11<\/strong> n\u2019\u00e9s un cas. A continuaci\u00f3, teniu un altre exemple que comentarem pas a pas. B\u00e0sicament, \u00e9s un cercle que es fa m\u00e9s gran cada segon, fins que arriba a un di\u00e0metre de 200. A partir d\u2019aquest moment, es va fent cada cop m\u00e9s petit, fins que arriba a un di\u00e0metre de 0 i torna a cr\u00e9ixer.<\/p>\n<pre>var diametre = 0;\r\nvar creix = true; \/\/ Variable que determina si el cercle ha de\r\n          \/\/ cr\u00e9ixer o decr\u00e9ixer\r\n\r\nfunction setup() {\r\n createCanvas(480, 480);\r\n}\r\nfunction draw() {\r\n var currentTime = millis(); \/\/ Guardem el temps actual\r\n background(204);\r\n if (currentTime % 1000 &gt; 900) { \/\/ Calculem el residu de dividir\r\n                 \/\/ per 1000\r\n  if (diametre == 200) {  \/\/ Si arribem a 200 toca decr\u00e9ixer\r\n\tcreix = false;\r\n  }\r\n  if (diametre == 0) { \/\/ Si arribem a 0 tornar a cr\u00e9ixer\r\n   creix = true;\r\n  }\r\n  if (creix) {\r\n   diametre++;\r\n  } else { \r\n   diametre--;\r\n  }\r\n }\r\n ellipse(width\/2, height\/2, diametre, diametre);\r\n}<\/pre>\n<p>Aquest exemple \u00e9s molt senzill i \u00e9s f\u00e0cil de veure com funciona. L\u2019\u00fanica dificultat est\u00e0 en el fet de fer servir el residu de la divisi\u00f3 per 1000.<\/p>\n<h2>Moviment circular<\/h2>\n<p>Vegem com fer moure objectes pel <em>canvas<\/em> amb un moviment circular. Per a fer-ho, farem servir les funcions <span style=\"font-family: Courier, Arial;\">sin()<\/span> i <span style=\"font-family: Courier, Arial;\">cos()<\/span> que corresponen al sinus i al cosinus. Com que aqu\u00ed no podem explicar trigonometria, ens haurem de conformar sabent que aquestes funcions retornen valors d\u2019entre -1 i 1.<\/p>\n<p>Aqu\u00ed teniu un exemple que ens permet fer-nos una idea de com podem fer servir les funcions sinus i cosinus:<\/p>\n<pre>var x = 0.0;\r\n\r\nfunction setup() {\r\n createCanvas(400, 400);\r\n strokeWeight(4);\r\n}\r\n\r\nfunction draw() {\r\n stroke(0);\r\n point(x*10,sin(x)*50+200);\r\n stroke(255,0,0)\r\n point(x*10,cos(x)*50+200);\r\n x=x+0.08;\r\n}<\/pre>\n<p>Aquest codi dona com a resultat aquest dibuix:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-269\" src=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_4_031.jpg\" alt=\"\" width=\"423\" height=\"147\" srcset=\"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_4_031.jpg 423w, http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-content\/uploads\/sites\/17\/2019\/07\/PID_00258586_4_031-300x104.jpg 300w\" sizes=\"(max-width: 423px) 100vw, 423px\" \/><\/p>\n<p>On la funci\u00f3 sinus s\u2019ha dibuixat en negre i la cosinus en vermell.<\/p>\n<p>Doncs b\u00e9, aquestes dues funcions es poden fer servir per a diverses coses. Per exemple, en l\u2019exemple 8-12 es fa servir per a generar una sensaci\u00f3 d\u2019enfosquiment i aclariment del color del quadre. En aquest codi es fa servir la funci\u00f3 <span style=\"font-family: Courier, Arial;\">map()<\/span> que, recordeu, ens permet fer un canvi d\u2019escala d\u2019un valor. Aix\u00ed, com que la funci\u00f3 <span style=\"font-family: Courier, Arial;\">sin()<\/span> retorna un valor que va des de -1 fins a 1 i hem de tenir un nombre que vagi des de 0 (negre) fins a 255 (blanc), volem convertir el resultat de calcular el sinus en un color.<\/p>\n<pre>var sinval = sin(angle);\r\nprint(sinval);\r\n<strong>var gray = map(sinval, -1, 1, 0, 255);<\/strong>\r\nbackground(gray);<\/pre>\n<p>L\u2019exemple 8-13 ens mostra com es pot fer servir la funci\u00f3 <span style=\"font-family: Courier, Arial;\">sin()<\/span> per a generar moviment.<\/p>\n<p>Combinant la funci\u00f3 <span style=\"font-family: Courier, Arial;\">sin()<\/span> i la funci\u00f3 <span style=\"font-family: Courier, Arial;\">cos()<\/span> per a donar un valor a <strong>x<\/strong> i <strong>y<\/strong>, podem fer moviments circulars. L\u2019exemple 8-14 aprofita aquesta possibilitat. Modifiquem i comentem l\u2019exemple del llibre.<\/p>\n<pre>var angle = 0.0; \r\nvar offset = 120; \/\/ El centre del moviment circular. \r\n         \/\/ x = 120 i y = 120 \u00e9s el centre del canvas.\r\nvar scalar = 50; \/\/ Un valor m\u00e9s gran dibuixa un cercle m\u00e9s gran\r\nvar speed = 0.05;\r\nfunction setup() {\r\n createCanvas(240, 240);\r\n background(204);\r\n}\r\nfunction draw() {\r\n var x = offset + cos(angle) * scalar;\r\n var y = offset + sin(angle) * scalar;\r\n ellipse(x, y, 40, 40);\r\n angle += speed;\r\n}<\/pre>\n<p>L\u2019exemple 8-15 d\u2019aquest cap\u00edtol \u00e9s el que no \u00e9s complicat. Aquest dibuixa una espiral. El punt clau est\u00e0 en la variable <span style=\"font-family: Courier, Arial;\">scalar<\/span> que canvia a cada volta i que multiplica el resultat del sinus i el cosinus.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Segur que recordareu que, tal com ja hem vist, la funci\u00f3 draw() es repeteix 60 cops per segon. I tamb\u00e9 que ja hem comentat que aix\u00f2 es pot canviar. La funci\u00f3 que ens permet canviar el nombre de vegades que es repeteix la funci\u00f3 draw() per segon es diu frameRate(). Podem fer servir aquesta funci\u00f3 [&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\/947"}],"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=947"}],"version-history":[{"count":36,"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/pages\/947\/revisions"}],"predecessor-version":[{"id":3997,"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/pages\/947\/revisions\/3997"}],"wp:attachment":[{"href":"http:\/\/disseny-test.uoc.edu\/materials\/programacio\/wp-json\/wp\/v2\/media?parent=947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}