Voici quelques animations génératives plus ou moins interactives pour le plaisir... Des bulles rebondissantes, quelques particules gravitantes et un bouquet d'herbes folles !
alpha
Rien de particulier à dire sur les bulles, elles rebondissent sur les murs et surtout entre elles. Chaque rebond entraîne une perte d'énergie cinétique. (Cette animation n'est pas interactive).
Chaque bulle possède une masse sur la base du volume de la sphère correspondante. Cette masse est pris en compte lors du calcul d'échange de quantité de mouvement à chaque collision.
À propos des particules + effet de gravitation interactif, je dois dire qu'une fois de plus, l'approche naïve en canvas HTML et arrays de points Javascript est étonnamment convaincante en terme de performances (je n'ignore pas qu'on peu obtenir bien plus de particules avec des outils spécialisés et une accélération matérielle mais ce n'est pas là mon objet).
Un freinage aérodynamique est implémenté, ce qui donne une certaine impression de viscosité à ce nuage de point (et évite de voir les particules partir au loin pour toujours...).
La force de gravité variant comme l'inverse du carré de la distance, il faut limiter le module du vecteur force à partir d'une certaine distance. Cela revient à appliquer une fonction de minimum sur la force.
On "plante une graine" en cliquant une ou plusieurs fois dans le canvas (plutôt dans le bas car elle va pousser :-)...
Ici le bouton "Remise à zéro" ne sert pas à effacer le canvas mais à interrompre la croissance des végétaux plantés et permettre d'en démarrer de nouveaux sans effacer les précédents ni pénaliser les performances. En effet, dans la mesure où les branches se subdivisent, on atteint rapidement un grand nombre d'objets à calculer ce qui réduit vite les performances. On peut ainsi composer un bouquet bien garni avec plusieurs semis...L'algorithme qui gère la croissance et les ramifications possède quelques finesses amusantes. Voici l'objet comment est défini ce qui "pousse" (le germe, la branche...). C'est la trajectoire de cet objet que l'on va dessiner.
var germ = {
index:gc, //identifiant unique de la branche
ox : xn, // position originale
oy : yn,
px:xn, // position courante
py:yn,
vx:vxx, // vitesse de pousse courante
vy:vyy,
angle:ang,
speed:sp,
level:1, // numéro d'ordre (génération)
parent:-1, // identifiant du parent (-1 pour le tronc)
path:0, // longueur parcourue
curl:curl // signe de la charge électrique
};
Au fur et à mesure de la pousse, on calcule une (faible) chance que cette branche se ramifie. Cette chance dépend du hasard mais aussi de la durée depuis laquelle la pousse a commencé. J'ai fixé 5 "domaines de croissance" avec des chances nulles ou faibles de division et des taux de courbure choisis :
Ceci permet de contrôler la forme générale de la plante et d'éviter que de petites pousses se ramifient trop.
Comme indiqué dans la définition de l'objet ci-dessus, nous disposons d'une charge électrique. Étrange n'est-ce pas ? Ceci est nécessaire pour courber nos branches. En effet, pour qu'elles se courbent harmonieusement et s'enroulent éventuellement sur elles-mêmes, on applique sur l'objet un champ magnétique dont la direction est perpendiculaire au plan du canvas. Une particule chargée en déplacement dans un tel champ voit sa trajectoire se courber circulairement à cause des forces de Lorentz. Voici la fonction qui calcule le vecteur de cette force exercée sur l'objet (en argument, on donne sa vitesse et sa charge). On retrouve ici la formule du produit vectoriel
function magneticForce(vx,vy, cu)
{
var z = 0.001 * cu;
var B = {x:0,y:0,z:z}; // vecteur du champ magnétique, normal au canvas
var V = {x:vx,y:vy,z:0}; // nos objets se meuvent dans le plan (z=0)
var BV = {
x:B.y*V.z - B.z*V.y,
y:B.z*V.x - B.x*V.z,
z:B.x*V.y - B.y*V.x
};
return BV;
}
Un freinage aérodynamique est également appliqué, les trajectoires se resserrent et dessinent une forme spiralée.