====== Différences ====== Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
|
animation-procedurale:balle:sol [2015/03/27 22:23] nliautaud |
animation-procedurale:balle:sol [2015/04/13 22:04] (Version actuelle) nliautaud |
||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| ====== Le sol ====== | ====== Le sol ====== | ||
| - | <WRAP center alert> | + | Pour simplifier, on imagine le sol comme une ligne horizontale infinie. On peut définir son emplacement par une seule valeur, sa position en hauteur. |
| - | WIP, en cours de réécriture | + | |
| - | </WRAP> | + | |
| + | <code javascript> | ||
| + | var hauteurSol = 400 | ||
| + | </code> | ||
| - | Pour simplifier, on représente le sol par une ligne horizontale infranchissable, située à une certaine hauteur. | + | On le représente ici via une ligne grise, en utilisant en PaperJs ''Path.Line''. |
| <code javascript> | <code javascript> | ||
| - | // le sol | + | var sol = new Path.Line(9999, 0) |
| - | var hauteurSol = 400 | + | sol.position.y = hauteurSol |
| - | var sol = new Path.Line(new Point(0, hauteurSol), new Point(800, hauteurSol)) | + | |
| sol.strokeColor = '#ccc' | sol.strokeColor = '#ccc' | ||
| - | sol.strokeWidth = 2 | ||
| </code> | </code> | ||
| - | La ''position'' de la balle est un point situé en son milieu, à l'intérieur du cercle. Pour savoir quand la balle touche le sol, il nous faut considérer le point de sa surface situé en bas. Comme le sol est horizontal, on peut comparer uniquement la position verticale des éléments. Et comme la valeur ''taille'' correspond au rayon de notre balle, la balle touche le sol si sa position verticale plus son rayon est égale à la hauteur du sol. | + | Pour que la balle réagisse au contact du sol, il faut d'abord déterminer quand ce contact a lieu et, s'il a lieu, adopter un comportement différent. C'est le rôle d'une condition. |
| - | ===== L'arrêt ===== | + | ===== Le contact ===== |
| - | La balle ne peut traverser le sol, elle ne doit donc pas tomber si elle est en son contact. C'est le rôle d'une condition, que l'on place dans la boucle. | + | La ''position'' de la balle est un point situé en son milieu, à l'intérieur du cercle. Pour savoir quand la balle touche le sol il nous faut logiquement plutôt considérer ses bords, c'est à dire sa position plus son rayon (ici c'est ''taille''). Et puisque le sol est horizontal, on n'a finalement qu'à comparer la position verticale du bord inférieur de la balle (''position.y + taille'') à la hauteur du sol (''hauteurSol''). |
| <code javascript> | <code javascript> | ||
| function onFrame() { | function onFrame() { | ||
| - | // ajout de la force de gravité | ||
| - | vitesse += gravite | ||
| - | | ||
| // si la balle touche le sol | // si la balle touche le sol | ||
| - | if( balle.position.y + taille >= hauteurSol) { | + | if( position.y + taille >= hauteurSol) { |
| - | // on la stoppe | + | // on stoppe sa vitesse |
| vitesse = new Point() | vitesse = new Point() | ||
| + | } else { | ||
| + | // sinon, elle tombe | ||
| + | vitesse += gravite | ||
| } | } | ||
| - | else { | + | position += vitesse |
| - | // la balle tombe | + | |
| - | balle.position += vitesse | + | balle.position = position |
| - | } | + | |
| } | } | ||
| </code> | </code> | ||
| <WRAP center info > | <WRAP center info > | ||
| - | [[http://sketch.paperjs.org/#S/fVPLbsIwEPwVKz2QiCikUlELEr0g9dRDJQ49lB6MWRoXxxvZTqoK8cH9i3oDhoSiWkpk787s7MPeRZqXEE2jxRacKKI0Erim82jEFGcrrhQszVI33DDHpT+xGRvnwVShlU6i9kYNX+wFpXbxbZ6nzP+SgGqkA2uhB7pP2RnQygQ3d0U2l0YoiEP49KjdElpwZp3BLcxRofHEwc1kMtnw8eAS8CrXrqCUyUGfrwt0Iw1qDSVoF1L4MJzS7OVIZSQdos/RogqMgtcOarNA5Ul3+akntjWcSnmWGuJezDMxSTtqD3nf1yr7YH9KFUIMOllxLUtOXaLzptaiHQjqJ+MnGydsR3bml9zEh05noa/ZNxuGsT7OuuJnFq3OZWAOa1HAsRep1yGXdVhV0KVcm3kSAPuwAeUh/0iVK7hw8k+sHVsDoTZoBND+MLyfa/rDWRjtRaAS6+Z0A4K93x4iH+P0Mt/7Z7IywLcVlWWj6dv7/hc=|Voir l'exemple 5 : stop ! le sol !]] | + | [[http://sketch.paperjs.org/#S/bZPBbsIwDIZfJeoOFFGVTloPILEL0k47TOKww9ghBJdGpEmVpEwT4oF5izml7kpFD22cfP5tx+450ryCaBltjuBFGSWRMPtgz+dMcbbjSsHWbvWJW+a5RIutWJ7RVm2c9NJo3NTwwz6M1D5+zrKE4WtK1El6cA7uoDxhNyAEAuaMIrrkjYfGboxCh5cs6yDQJ2mN1lCB9sQeLA/id8oYPM1b6c6TF4UUJT8A24NjV3UNCo4k2hJJgPsyXUsrFMRUWtLV3Sq2cOq8NUdYG2UsOk6eFotFwfPJGPiUe1+G66JQri2pD/QuNcTou6CrwPOUwqa/iP5fBR2PQwshJsNStax4cA920WjRNsfoN4tdjqfsHPYZPsg62XeYedOIEgaNCIwsYjZIZ0YD8DpMbKDZ6WJA501doxan1g+RR9MwJeDCQOHZWNNJHToBt1yr3UPB2YrmoVejRT+nyIxSou+tc4OBpmUALvhj7CzwYx3SddHy6/vyBw==|Voir l'exemple 5 : stop ! le sol !]] |
| </WRAP> | </WRAP> | ||
| Ligne 46: | Ligne 44: | ||
| <code javascript> | <code javascript> | ||
| - | function onFrame() { | + | // si la balle va toucher le sol à la position suivante |
| - | // ajout de la force de gravité | + | var positionSuivante = position + vitesse + gravite |
| - | vitesse += gravite | + | if( positionSuivante.y + taille >= hauteurSol) { |
| - | + | // on la stoppe | |
| - | // calcul de la position suivante | + | vitesse = new Point() |
| - | var positionSuivante = balle.position + vitesse | + | } else { |
| - | + | // sinon, elle tombe | |
| - | // si la balle touche le sol à la position suivante | + | vitesse += gravite |
| - | if( positionSuivante.y + taille >= hauteurSol) { | + | |
| - | // on la stoppe | + | |
| - | vitesse = new Point() | + | |
| - | } | + | |
| - | else { | + | |
| - | // sinon la balle tombe | + | |
| - | balle.position = positionSuivante | + | |
| - | } | + | |
| } | } | ||
| </code> | </code> | ||
| <WRAP center info > | <WRAP center info > | ||
| - | [[http://sketch.paperjs.org/#S/fVPLasMwEPwV4R5iE5O40NAmkF4CPfVQyKGHpgdFWddqZMlIsksJ+dde+xddOZYfSajBRtqdndmXD4GkOQSLYL0Hy7IgDpjauft0SgQlWyoEbPRGVlQTSzneyJLMEm8qlOGWK4lGCV/kRXFpw9skiQl+Io+quAVjYAC6j0kHqGW8m9pssuKaCQg9fdxo1wE1eGKsVntYKaE0Bo5u5vN5Smejc8Ar39nMpewc7nV1ATFKeO2MlhZKvVYCYXdJW5qpDW1Gz1xC2KU/wxK7yCjuVfaQDH110sh2kTJjbNRLC2TFtZIScpDWZ/GhqeveoHVIP5lFvUgqeU5dn9w9LSWrR6Lkk8bZhhE5ODvBx2E/VWnJDtx0U6UZuPNJ5dfD/LzGS6/vPT0iRgUrRcPU7oEpeUVlF+Ad68aOhZzG00aMvdwVDcPbJSRWlSyDZnjk519VnoYXypNvlGpW+HHZH1DXn0YWGZHdWFUU0Hdd2+PIA47+AAIh55S9MvLtgPSsHcuLxAcCR/xDtxrovnDqJli8vR//AA==|Voir l'exemple 6 : on stoppe avant le sol]] | + | [[http://sketch.paperjs.org/#S/bVOxbsIwEP0VKx0IAoVUKgNIdEHq1KESQ4fSwZgLsTB2ZDupKpR/7cpf9BxyaUhhCLHvvXf3/JxzpPkJomW0OYIXeTSNhNmH9WzGFGc7rhRs7VZX3DLPJa7Yis1T2iqMk14ajZsavtibkdrHj2k6ZfgYE6qSHpyDG9B8yq6A0AiYM4rQOS89lHZjFBKe0rQFga6kNVrDCbQn7MHyIH6jjM2TeSPdMnmWSZHzA7A9OHZRl6DgSKKxSALc58laWqEgJmvT1nej2IAT5605wtooY5E4elgsFhmfj4aAd7n3eTguauUaS12jV6khRu6CjgLrCbVNvhH6dxRUHrYWQoz6VrU88UAP66zUognH6BeLKcdjdg77DH+IdbJLmHlTihzaINhPKHTRulJWXHsgaj/3TVvDWTr8pMt7QvkQVWbxPyoandDVeu5b7k3bToziOJjzpiigX7p3v8YEqBkorA21nNQhW7i6P+3uCk5WQwc1vfzZXRGcSvR/vQu9T4ReA6DGT21ngR+LMK6Llh+f9S8=|Voir l'exemple 6 : on stoppe avant le sol]] |
| </WRAP> | </WRAP> | ||
| - | ===== Réaction ===== | + | ===== Le rebond ===== |
| - | Lorsqu'une vraie balle touche le sol, de par son élasticité et parce qu'elle ne peut traverser ce dernier, elle s'écrase et se déforme. Une fraction de seconde plus tard, tentant de retrouver sa forme originale, elle est propulsée vers le haut. C'est une force de réaction, perpendiculaire à la surface de contact. | + | Lorsqu'une vraie balle touche le sol, elle s'écrase, se déforme et, une fraction de seconde plus tard, tentant de retrouver sa forme originale, elle est propulsée vers le haut. C'est une force de réaction, perpendiculaire à la surface de contact. |
| - | Comme notre sol est horizontal, la force de réaction est verticale. | + | Comme notre sol est horizontal, la force de réaction est verticale. Pour simplifier, on peut donc considérer que la force de réaction a pour effet de dévier la direction de la balle, tout en conservant son angle d'incidence. Notre vecteur étant décrit en séparant ses composantes ''x'' et ''y'', il nous suffit d'inverser sa valeur verticale sans toucher à sa valeur horizontale. |
| - | <code javascript> | + | Pour l'inverser, il suffit de multiplier par ''-1''. |
| - | var reaction = new Point(0, -vitesse.y * 2) | + | |
| - | </code> | + | |
| - | + | ||
| - | Dans notre condition, quand nous savons que la balle touche le sol, au lieu de la stopper nous allons calculer cette force de réaction et l'ajouter à la vitesse. | + | |
| <code javascript> | <code javascript> | ||
| - | function onFrame() { | + | // si la balle va toucher le sol à la position suivante |
| - | // ajout de la force de gravité | + | var positionSuivante = position + vitesse + gravite |
| - | vitesse += gravite | + | if( positionSuivante.y + taille >= hauteurSol) { |
| - | + | // on dévie sa direction | |
| - | // calcul de la position suivante | + | vitesse.y *= -1 |
| - | var positionSuivante = balle.position + vitesse | + | } else { |
| - | + | // sinon, elle tombe | |
| - | // si la balle touche le sol à la position suivante | + | vitesse += gravite |
| - | if( positionSuivante.y + taille >= hauteurSol) { | + | |
| - | // on calcule la force de reaction | + | |
| - | var reaction = new Point(0, -vitesse.y*2) | + | |
| - | // on l'ajoute à la vitesse | + | |
| - | vitesse += reaction | + | |
| - | } | + | |
| - | else { | + | |
| - | // sinon la balle tombe | + | |
| - | balle.position = positionSuivante | + | |
| - | } | + | |
| } | } | ||
| </code> | </code> | ||
| <WRAP center info > | <WRAP center info > | ||
| - | [[http://sketch.paperjs.org/#S/fVTLTsMwEPwVKxyS0JAGRAStVC6VOHFA6oEDcHDdDTF17Mp2iqqq/8qVv8BO4ryKiNQo3p3d2dmxevQ4LsCbe6staJJ7kUfExp6nU8QwWmPG4E2+8T2WSGNqTmiB0sSFdkJRTQU3QQ5f6FlQroPrJImQeYUOtacalIIB6C5CHaCicWms83hJJWEQuPZRw10VVOBYaSm2sBRMSFPoX8xmswyn/hjwQjc6tyPbhP1ZXYCUYI47x6WGUq4EM7DbpJWmqkA70RPlEHTjp0ZiVxlGPWX3yTBXDW26nY1MCPF7YwHfUyk4hwK4dlN8SGy3N1idaR+nYa8Sc1pguyd7zkpOKksEf5TG2yBERxtH5rHYT1FqtAHrbiYkAftds/w4mPNrsnD8LtNrRDAjJWs6tfdAlXSPeVfQvySrJmfE1Ba1VRNH+QePou1FRFqUJIfGQPT9LzPNgjPm+GCommv8sOib1O2ooTUda4XDTUnAxG3aoa1GFx8bddUIiw+XN+E5BfMrP6DWMlrCyIox9cl9ADOA8fyKctu/21yxHjQeObA429WA5mT+GNZmgO3OClPe/PX99As=|Voir l'exemple 7 : le rebond]] | + | [[http://sketch.paperjs.org/#S/bVOxbuMwDP0Vwh3iNjnXBS5DCqRLgZtuOCDDDe0NikzXRBSpkGQXRZF/vTV/UcoxXTetB9sS33vkE6m3zKo9ZrfZZodRN9ki065K6+trMAq2yhh89I+2Ux6iIl7BGpalbD27QJGc5U2LL/DHkY35TVkugF+XguooYgj4CbRcwAmQEiEEZwTdqDZi6zfOMOFnWQ4gtB15Zy3u0UbBPnmVxD8pc/Ji2UsPTFXXpBv1hFBhgKM5JoUgEr1FEVCxKe7Ja4O5WFsMvnvFHlyE6N0O751xnomzi9VqVavl7Bzwl6rYpOOSVKG3NCb6TRZz5q7kKDheSNrilaEfRyHh89Ra69nUqqW9SvS0rlur++Y4+8tzl/NLeEv7wA9jA40dhuha3eDQCPifAmNrQ0udshGFOu37ZohxLSN+Lv0WAtX5FwLbm8tA3U2NTmoc6mTJ6tgRl6agIo9a/AlmSMeSV2v4cSOhA6DhoTuXC2RTU/Fke7/Fb6RgvpbRGtXk58Pn+tyofE9DMLkb8psAB75jW49q95ymNWS3D/8O7w==|Voir l'exemple 7 : le rebond]] |
| </WRAP> | </WRAP> | ||
| - | La condition permet de passer ponctuellement d'une force de gravité à une force de réaction, et voila notre balle qui rebondis! | + | La balle rebondis, oui, mais... trop bien. En inversant comme un miroir la direction verticale, on a créé une balle rebondissante parfaite, qui à chaque rebond remonte exactement aussi haut qu'au départ, sans jamais s'essouffler. |
| - | ===== Efficience ===== | + | Dans la vie réelle, l'intensité de la force de réaction dépend d'un certains nombre de paramètres, dont le plus caractéristique est l'efficience de rebond caractérisant la matière et la structure de la balle. Cette caractéristique est un paramètre de description physique souvent nommé en anglais //bounciness//. |
| - | Vous pouvez remarquer que quel que soit le nombre de rebonds effectué par la balle, jamais elle ne s'arrête. Nous avons en effet créé ici une balle rebondissante parfaite, qui à chaque rebond remonte exactement aussi haut qu'au départ, sans jamais s'essouffler. | + | Au lieu de multiplier par ''-1'' la valeur verticale de la vitesse, on utilise donc cette nouvelle caractéristique de la balle, que l'on définit au préalable. |
| - | Pour changer cela il n'y a qu'à modifier l'**intensité de la force de réaction**. | + | <code javascript> |
| + | var bounciness = .7 | ||
| + | </code> | ||
| - | L'efficience du rebond d'une matière étant un réel paramètre de description physique (en anglais "bounciness"), si l'on veut être plus précis cela correspond à : | + | <code javascript> |
| - | + | // si la balle va toucher le sol à la position suivante | |
| - | <code python> | + | var positionSuivante = position + vitesse + gravite |
| - | # regles | + | if( positionSuivante.y + taille >= hauteurSol) { |
| - | nextPosition = vectorAdd(position, vitesse) | + | // on dévie sa direction, selon son efficience en rebond |
| - | if nextPosition[1] - taille <= sol: # rebond | + | vitesse.y *= -bounciness |
| - | bounciness = 0.75 | + | } else { |
| - | reaction = [0, -vitesse[1] * (1 + bounciness), 0] | + | // sinon, elle tombe |
| - | vitesse = vectorAdd(vitesse, reaction) | + | vitesse += gravite |
| - | else: # chute | + | } |
| - | vitesse = vectorAdd(vitesse, gravite) | + | |
| </code> | </code> | ||
| + | <WRAP center info > | ||
| + | [[http://sketch.paperjs.org/#S/bVPLbtswEPyVhXqwUjuKCtQoHMC5BOiphwI+9ND0QFGraGGaDEhKRRH4X3v1X3Qpa2XFqQHb4nJm9jGr18yqA2b32W6PUbfZKtOuTue7OzAKKmUMPvkn2ysPURGfYAvrUkKV66wmiyFwuPgi4RcXKJKzHLT4G747sjH/VJYr4J8bQfUUmYhvQOsVnAEpP0JwRtCt6iJ2fucMEz6X5QhC25N31uIBbRTss1dJ/I0yJy/Wg/TIVE1DulXPCDUGOJlTUghTZ+rc6yCgYls8ktcGc2ltNY5jUBzARYje7fHRGeeZuPiw2WwatV5cA35QHds0RUkVhpamRN94njlzNzIKvi8kbfGHoZdRyPV1aq31Yt6qpYNK9HRu2LLBHGe/ejY/v4HXFAf+MDbQZDxE1+kWRyPgb7qYrA0d9cpGFOrc9914x7VM+KX4LQRq8ncEbm8pe/Ywb3RW41gnS9annrg0BTV51GdXAppUHH8x+UtoNfKSgMfK2XquMZbDKT9u4fayyYI5Ahrezuu8gWzKg+f5HCr8jyYst7KDk5o8XAayvZ6I/J+3ZfYSyWMCHPkdrTyq/Uta65Dd//x1/Ac=|Voir l'exemple 8 : bounciness]] | ||
| + | </WRAP> | ||
| - | Quelques indications : | + | Si on multiplie par zéro, la balle ne rebondit pas une seule fois. Si on multiplie par une valeur faible, par exemple ''.2'', chaque rebond est drastiquement plus faible que le précédent et la balle rebondis peu de fois, comme pour une boule de bowling. Si on multiplie par une valeur plus proche de 1, par exemple ''.7'', chaque rebond est un peu plus faible que le précédent mais la balle rebondis beaucoup plus de fois, comme pour un ballon de foot. |
| - | * **0.0** : rebond nul, l'objet ne rebondis pas. | + | |
| - | * **0.3** : rebond réaliste peu efficient, chaque rebond est beaucoup plus faible que le précédent (type boule de bowling) | + | |
| - | * **0.7** : rebond réaliste efficient (type ballon de foot) | + | |
| - | * **0.9** : rebond réaliste très efficient, chaque rebond est presque aussi important que le précédent (type balle rebondissante) | + | |
| - | * **1.0** : rebond parfait, chaque rebond est aussi important que le précédent (mouvement perpétuel) | + | |
| - | * **>1** : rebond irréaliste, chaque rebond est plus important que le précédent (type flubber) | + | |
| - | [{{http://www.exploratorium.edu/baseball/activities_images/bounce_chart.gif|Efficience du rebond de quelques types de balles.}}] | + | [{{ http://www.exploratorium.edu/baseball/activities_images/bounce_chart.gif |Efficience du rebond de quelques types de balles.}}] |
| - | ===Friction=== | + | ===== Un peu de friction ===== |
| - | Si maintenant la taille du rebond décroit avec le temps, le mouvement de la balle initié par la force de départ est lui toujours perpétuel : même sans rebondir, elle continue de glisser sur le sol. Il nous manque un paramètre de **friction**. L'effet de la friction est de freiner un objet lorsqu'il y a contact. Qui dit freiner dit diminuer sa vitesse. | + | Si maintenant la taille du rebond décroit avec le temps, le mouvement de la balle initié par la force de départ est lui toujours perpétuel : même sans rebondir, elle continue de glisser sur le sol. Il nous manque un paramètre de friction, dont l'effet est de freiner un objet lorsqu'il y a contact. |
| - | Il nous faut donc réduire la longueur du vecteur vitesse quand il y a contact avec le sol. Comme vu dans le [[admin:scriptspython#Addition, soustraction, multiplication|chapitre sur les vecteurs]], il s'agit d'une simple multiplication du vecteur avec un nombre. Je récupère donc la fonction à cet effet : | + | Il suffit de réduire cette fois la vitesse générale de la balle lorsqu'elle est en contact avec le sol, selon une nouvelle caractéristique définie au préalable. |
| - | <code python> | + | <code javascript> |
| - | def vectorMult(a, b): | + | var friction = .9 |
| - | return [a[0]*b, a[1]*b, a[2]*b] | + | |
| </code> | </code> | ||
| - | Dans notre condition, après avoir calculé la force de réaction et la nouvelle vitesse, nous n'avons plus qu'à multiplier cette dernière : | + | <code javascript> |
| - | + | // on freine sa vitesse | |
| - | <code python> | + | vitesse *= friction |
| - | # regles | + | |
| - | nextPosition = vectorAdd(position, vitesse) | + | |
| - | if nextPosition[1] - taille <= sol: # rebond | + | |
| - | bounciness = 0.75 | + | |
| - | friction = 0.95 | + | |
| - | reaction = [0, -vitesse[1] * (1 + bounciness), 0] | + | |
| - | vitesse = vectorAdd(vitesse, reaction) | + | |
| - | vitesse = vectorMult(vitesse, friction) | + | |
| - | else: # chute | + | |
| - | vitesse = vectorAdd(vitesse, gravite) | + | |
| </code> | </code> | ||
| - | Quelques indications : | + | Si on multiplie par zéro, la balle est immédiatement stoppée au contact du sol. Avec une valeur faible, par exemple ''.2'', la balle est très vite ralentie par le sol, comme tombant dans du sable. Si on multiplie par une valeur très proche de 1, par exemple ''.9'', la balle est lentement ralentie par le sol, comme roulant sur un sol lisse. |
| - | * **0.00** : friction maximale, l'objet est immédiatement stoppé au contact de la surface. | + | |
| - | * **0.25** : friction réaliste forte, l'objet est très vite freiné par la surface (type sable) | + | |
| - | * **0.99** : friction réaliste faible, l'objet est lentement freinée par la surface (type de sol lisse) | + | |
| - | * **1.00** : friction nulle, l'objet n'est pas freiné par la surface (type glace) | + | |
| - | * **>1.00** : friction irréaliste, l'objet est accéléré par la surface (type accélérateur de jeu de course) | + | |
| - | =====Code final===== | + | En multipliant par ''1'', la balle n'est plus freinée du tout, comme sur de la glace, et avec une valeur supérieure à 1 la balle accélère même au contact du sol, comme s'il s'agissait d'un accélérateur de jeu vidéo. |
| - | <code python> | + | |
| - | from maya.cmds import polySphere, currentTime, move | + | |
| - | # fonctions | + | <WRAP center info > |
| - | def vectorAdd(a, b): | + | [[http://sketch.paperjs.org/#S/bVRNb9swDP0rhHeIu2RuBiwoXCC7FOiphwE57LDuIMt0TUSRCknOPor8113zL0Y5puOmDZDEIh8fyUfKL5lVO8xus80Wo26zRaZdnc7X12AUVMoYfPSPdq88REV8gjWslmKqXGc1WQyBzcWNmBtPOpKzyViK8dkFGowWf8E3Rzbmn5fLBfDPlaD2FJkNX4FWCzgBUlEIwRlBt6qL2PmNMxzwZbkcQGj35J21uEMbBfvkVSJ/xczJi1VPPUSqpiHdqieEGgMczTExhLFddRKgJ1CxLe7Ia4O5tLYYNOoZe3ARondbvHPGeQ6cfSjLslGr2SXgO9WxTdJKqtC3NCZ6YJFzji1FCvYXkrb4w9CzFOK+TK21nk1btbRTKTydG55jPxxn7z1vRH4FL8kO/GFsoHEbILpOtzgMAv4lxzja0NFe2YgSOp37ZvBxLSN+LvOWAGryNwHc3lyW7+u00UmNQ51MWR/3xKUpqMmjPk0loEnF8RfTfAmtRl4S8Fg5W085hnI45cc1fDqv99s8jUf2pESysq3z9NfZqAy+R/k7UcrNEMAB0HDoZR+BbKobT3rvqvcIYb6WnR7Z5OEs8PpSYfk/bd/kUspjAhz4RVB5VNvndE1Cdvvj5+E/|Voir l'exemple 9 : friction]] |
| - | '''Somme de deux vecteurs''' | + | |
| - | return [a[0] + b[0], a[1] + b[1], a[2] + b[2]] | + | |
| - | def vectorMult(a, b): | + | |
| - | '''Multiplication de vecteur par un nombre''' | + | |
| - | return [a[0] * b, a[1] * b, a[2] * b] | + | |
| - | # conditions initiales | + | [[http://sketch.paperjs.org/#S/hVTBbqMwEP0Viz0AhbXIbnMIXfZSaU9baaUc9pDmYBNTrFA7MiarquLfdwYwwWmrIkXBM++N38w88Roo9iyCPNgehS3rIA1KfcDzmRmiuCEFWWWP5lHh+aRbaaVWEFTiH/mjpbLRKstSwGSxQ9Wss6IzW90A7jab2U+GnaUVHhmodD0w8cdZ04gWALs9HittIiTKIrsj8geogb8kickrZgk8mEWJD8zW1DB10M9RfHObJaNmB+EAmTn4hJZJuCrMTeqFUV/bQvyi0C+9AsF+5Hvsl+C6U6VUUCbMPaQPq4wscZRhDgMgyVVRuvbRJ8hOohB3L03ZiMjfAa4gJSZ2xN69cIp02lqjj+JeNxonFn7ZbDYVW4fvov7Kg60B9W3ODpuhp66tIz5c0bu1tsOeZ22/ofcIam9SMloC8tQZh74A9OIPl76WVpZl6DxRwTgHz2n1y4BVo8X6PzfI0gFjDzu5v046ddtOnpkaHDpNYzZ8ApHJHPA+OXlZR1bRmzrQLfJGr5Gfy86vJI4LmC4A2k1BvnJ6sdKHWERy6sy0hPVENJD/+BqSFO810i8Pb8ZQXPiez3r4cHAj2PGEfmyDfLfv/wM=|Démo : bounciness et friction aléatoire]] |
| - | taille = 5 | + | </WRAP> |
| - | balle = polySphere(radius=taille) | + | |
| - | position = [0, 50, 0] | + | |
| - | vitesse = [1, 0, 0] | + | |
| - | bounciness = 0.75 | + | |
| - | friction = 0.95 | + | |
| - | # environnement | + | =====Conclusion===== |
| - | gravite = [0, -0.1, 0] | + | |
| - | sol = 0 | + | |
| - | # animation | + | <code javascript linenums> |
| - | time = 100 | + | // la balle |
| - | for frame in range(1, time): | + | var taille = 50 |
| - | # regles | + | var bounciness = .7 |
| - | positionGravite = vectorAdd(position, vitesse) | + | var friction = .9 |
| - | if positionGravite[1] - taille <= sol: # rebond | + | var position = new Point(100, 100) |
| - | reaction = [0, -vitesse[1] * (1 + bounciness), 0] | + | var vitesse = new Point(5, 0) |
| - | vitesse = vectorAdd(vitesse, reaction) | + | // le sol |
| - | vitesse = vectorMult(vitesse, friction) | + | var hauteurSol = 400 |
| - | else: # chute | + | // environnement |
| - | vitesse = vectorAdd(vitesse, gravite) | + | var gravite = new Point(0, .5) |
| - | # mouvement | + | // affichage des éléments |
| - | position = vectorAdd(position, vitesse) | + | var balle = new Path.Circle(position, taille) |
| - | currentTime(frame) | + | balle.strokeColor = '#999fa5' |
| - | move(position[0], position[1], position[2], balle) | + | balle.strokeWidth = 5 |
| - | </code> | + | var sol = new Path.Line(9999, 0) |
| + | sol.position.y = hauteurSol | ||
| + | sol.strokeColor = '#ccc' | ||
| - | =====Conclusion===== | + | // animation |
| - | + | function onFrame() { | |
| - | Vous remarquerez que l'on utilise seulement trois fonctions de Maya : **polySphere**, **currentTime** et **move**, qui servent uniquement à visualiser le résultat de nos calculs. Cette procédure est donc transposable à tout langage, tout logiciel permettant de programmer (Flash, Processing, Blender...) et n'est en rien rattaché à Maya. Il s'avère par la même occasion que les temps de calculs sont infiniment plus rapides que si l'on avait usé et abusé des fonctions internes au logiciel. | + | // si la balle touche le sol à la position suivante |
| + | var positionSuivante = position + vitesse | ||
| + | if( positionSuivante.y + taille >= hauteurSol) { | ||
| + | // on dévie sa direction, selon son efficience en rebond | ||
| + | vitesse.y *= -bounciness | ||
| + | // on freine sa vitesse | ||
| + | vitesse *= friction | ||
| + | } else { | ||
| + | // sinon, elle tombe | ||
| + | vitesse += gravite | ||
| + | } | ||
| + | position += vitesse | ||
| + | |||
| + | balle.position = position | ||
| + | } | ||
| + | </code> | ||
| + | Ce petit bout de code ne repose que très peu sur PaperJs, et ne lui délège principalement que la gestion du rendu visuel, sans que la mécanique de base ne repose dessus. On peut donc utiliser n'importe quel autre méthode, librairie ou logiciel pour représenter le résultat, qu'il s'agisse de déplacer des cubes sous Blender ou tracer des croix sur une feuille de papier. | ||