====== Le mouvement ====== Pour que la balle se déplace, il faut être capable de changer sa position. Pour cela, il va falloir faire des opérations vectorielles. Il s'agit de manipuler, tordre et transformer les vecteurs en effectuant des opérations, afin dépeindre un changement, une évolution de ce que l'on décrit. Si ça se complique ? Même pas. Pour se déplacer, il suffit de savoir faire une addition. ===== Additions et soustractions vectorielles ===== L'addition ou la soustraction de deux vecteurs u et v correspond à additionner ou soustraire entre eux chaque membres de u et v. u(x, y) + v(x, y) = w(ux+vx, uy+vy) u(x, y) - v(x, y) = w(ux-vx, uy-vy) On peut considérer que le vecteur qui résulte de l'opération est un vecteur qui retranscrit l'action de v sur u, le résultat de l'effet de v sur u. Ainsi, en considérant un long vecteur directionnel horizontal ''(5, 0)'' auquel on ajoute un petit vecteur directionnel dirigé vers le bas ''(0, -1)'', on obtiens le long vecteur légèrement incliné vers le bas ''(5, -1)'' : on a dévié une direction. Et si l'on considère plutôt le premier vecteur ''(5, 0)'' comme une position, alors l'addition du vecteur directionnel ''(0, -1)'' correspond à déplacer la position au bout du vecteur de direction : on a changé une position. ===== Position et vitesse ===== Le vecteur vitesse nous indique vers où se dirige la balle. Pour se déplacer, il faut donc que la position de notre balle se déplace au bout de son vecteur vitesse. On a vu juste au-dessus que c'est exactement l'effet de l'addition de vecteurs : la balle va se déplacer de sa position à sa position **plus** sa vitesse. [{{ balle_deplacement.png |nouvelle position = position + vitesse}}] <code javascript> // conditions initiales var taille = 50 var position = new Point(100, 100) var vitesse = new Point(7, 0) // la balle var balle = new Path.Circle(position, taille) balle.strokeColor = '#999fa5' balle.strokeWidth = 5 // on affiche la valeur initiale de la position console.log( balle.position ) // on ajoute le vecteur vitesse à la position balle.position += vitesse // on affiche la nouvelle valeur de la position console.log( balle.position) </code> Résultat : <code> { x: 100, y: 100 } { x: 107, y: 100 } </code> <WRAP center help> [[http://sketch.paperjs.org/#S/fZFNTsQwDIWvYoXFtKLqlMUIdaRZzQWQWLCgLDKpS0NDPErSskDclaPg9E9UQmyixH5+/ux8CivfURzFY4dBtSITiur43u9Bka110GQ9aMsXadBXdpAOgtTGIJzgUEyBK/lRySGLH/BA2obkrigy4COdNIMO6D1uJPcZxHRluZ2RcJFsO6nH66KVoc3P2imDydIpmyG4epTmPjjq8EyGHJftbsqybORht00/6Tq0kXvuycSyabRqMbYfeMLercNCPUbX2SrLG/HEZoZek4kwX7PpavhGfeBKhAFViIbL5N+/7Raw1eD2tAj/QLPUDxg3MjNu0f4lS/lTLw5ld40r9+L4/PL1Aw==|Voir l'exemple 2 : elle a bougé, non ?]] </WRAP> La balle a bien avancé légèrement sur la droite, comme l'indiquent les valeurs dans la console. Mais elle ne l'a fait qu'une seule fois, quand on a lancé le programme, ce qui est un peu décevant. Pour transformer ce déplacement en mouvement, ce résultat fixe en animation, il faut répéter cette opération plusieurs fois par secondes. Pour répéter une procédure on peut utiliser une boucle, ''while'' ou ''for'' par exemple, dans laquelle on prendra soin de réactualiser l'affichage du résultat. Dans le cadre d'une librairie graphique existante comme Paper.js, il y a généralement une fonction spécifique qui est exécutée à chaque instant, ici c'est ''onFrame()''. <code javascript> // conditions initiales var taille = 50 var position = new Point(100, 100) var vitesse = new Point(7, 0) // la balle var balle = new Path.Circle(position, taille) balle.strokeColor = '#999fa5' balle.strokeWidth = 5 function onFrame() { // à chaque instant, ajoute le vecteur vitesse à la position balle.position += vitesse } </code> {{ balle_mouvement.png |Le déplacement de la balle est répété en boucle.}} <WRAP center help> [[http://sketch.paperjs.org/#S/ZVHBTsMwDP0VKxzWimorhx26aadJnJE4cGAcvNRTs5ZkJG45TPvXfQpORkCISIls69l+7+WsLL6TWqnnnlh3qlLatTFfLEA72xo2zgYwVgIcKOz8zk7ogdEMA8EGlvU6104uJLhULX3CkzOWi4e6rkCeMqMmwxQC/QVVcAPEK5sHhD3K/NyTktyB3M23xuuBiryx+uZTJi4JPQ/sXU9bNzgvnbO7pmkOuJz9Q7yYlrsoZJ0JHEarkw5nH724U5RwjnWQI+SuoDv8GElMCYyWK8CjG5lAKE6kmcZfkdcoJbPMM27bf9y632R4YnCRP9h7wv4UrQlq9fp2+QI=|Voir l'exemple 3 : une superbe simulation de balle dans le vide]] </WRAP> En modifiant la vitesse initiale, on influence la vitesse et la direction de la balle, mais celle-ci continue toujours sa course de façon linéaire et infinie. On a la base fonctionnelle de notre simulation, mais sans aucune règle d'environnement c'est une simulation dans l'espace. Pour ramener la simulation sur terre, il va nous falloir faire preuve d'une nouvelle force. ===== Une nouvelle force ===== Dans la vraie vie, quand on lance une balle en l'air, on a tendance à penser qu'elle va finir par retomber. Et si on est si confiant, c'est qu'on prend en compte une force d'attraction formidable : la gravité. La gravité, si on la donne aux physiciens, ça peut être aussi compliqué qu'une déformation de la géométrie de l'espace-temps ou la propagation d'une particule. A l'échelle de notre balle c'est heureusement plus simple : c'est une force dirigée vers le bas. Et une force dirigée, on sait faire. C'est comme notre ''vitesse'', ça se représente simplement avec un vecteur directionnel. <code javascript> var gravite = new Point(0, 1); </code> Pour retranscrire l'effet de la gravité sur notre balle, il faut trouver un moyen pour que cette nouvelle force influence la vitesse de notre balle. On a vu précédemment qu'en additionnant un vecteur directionnel à un autre on le modifie, on le dévie... Cela signifie que pour ajouter l'influence d'une force, il suffit simplement d'additionner cette force à la vitesse ! {{ balle_gravite.png?nolink }} La vitesse finale de notre balle est la somme, la résultante des forces qui lui sont appliquées. <code javascript> // conditions initiales var taille = 50 var position = new Point(100, 100) var vitesse = new Point(7, 0) // la balle var balle = new Path.Circle(position, taille) balle.strokeColor = '#999fa5' balle.strokeWidth = 5 // règles d'environnement var gravite = new Point(0, 1) function onFrame() { // ajout de la force de gravité vitesse += gravite // mouvement balle.position += vitesse } </code> <WRAP center help> [[http://sketch.paperjs.org/#S/XVHBbsIwDP0VKzsUtKqwA5pA4oS086Qddhg7hNTQjNRGSdodEP+7/cWcQhAsUiLHeX5+zzkq0i2qhXrbYzSNKpXhOt0nEzBMtY2WKYAlCbTDsPZr6rWHqK1zCEuYTXPqwGFAS5LwG17ZUhw9TaclyDHOqN5GDAHvQM8lnAFpS2OnYaOFPtcMl1yhY1OtrDcOR7ljeZEzcAzgKkTPe1yxYy+FxcN8Pt/qWfEf8G7r2CQXN939z06MQl0g9dYzEbZIMWvZeZ0s3OkXi9XsamDbkRnmwPTiZbijMRxTHmQJvf7iLkKNyeWWvcEUn1l/MywP6XGZ++WXG6KWu/4qLeXOxq7fIMUXngQ4ydduPOr9IUkOavHxefoD|Voir l'exemple 4 : la balle tombe]] [[http://sketch.paperjs.org/#S/lVTNbtpAEH6VlXuwCYhApBxAyilRTq1UKap6aHpY7LHZYmbR7K5zQLxv8xadXbPGECdRkQz2er6fmfnEPkG5hWSZPG3A5utkkuS68M/X1yLXWCirNBqhkG9kDeaZnrGRJKxUdQ3iTtzO4tFOm1DNhwgv4rtWaLP5bDYR/DWKVY2yYAycFd1MRFvgLxaupVhJpo+Y8BAR0q6n94ryGrKoODnaCRyheGos6Q3c61oTA9Mvi8WilLfpZcFPVdi176KnTn8rblQUKWCjSCPCFtBGLxVJ38KZf25xOj9rQFXIFAQ7ejUMlmiF52wgt+Com2JzMQ3f21eFkO17/pcpQZEeThMkMK72nJ/hKgLAPvLC/DuwVe2gjzK5DOOfn1YtXTBtyUFs21+lwzxEQOMjca6ykdj7c8EfVYos4EY8F+sI44v4y3OTf7SzogCfgFJTDv6+Nf0ay+LIxndxFz2CrXZNty5/1i67iyaDjvgBdbcrpPWSJi5wq9HS0PKCkSPTtFRk7BNUXpelOBE8mnPhN5hafgYR42j1qt1Ax3Ha/39J92BD6h9YG8dJH51c3cw61uObYSfvc77BD1r6yLJnOFyE7pvmfD3oF+wHL4a1lHW79kHUj90QJgb8wH+MKwK5CdImWf76ffgH|Exemple 4, vecteurs visibles (cliquer pour animer)]] </WRAP> En deux lignes, on peut rajouter une force dirigée dans n'importe quel sens (une gravité vers le haut, pourquoi pas) et de n'importe quelle intensité (une gravité divisée par dix, et voilà la lune). Il ne manque plus qu'à trouver un sol, et on sera prêt à rebondir.