Tech things and such
Article / Note
2017/11/26

Nuée d'oiseaux, banc de poissons, troupeau, foule : Flocking.

Voici un autre système d'agents obéissants à des règles simples au niveau individuel et adoptant à un comportement collectif intéressant. Voir cette page ou celle-ci pour une description plus détaillée.




À propos des règles et des paramètres

Chaque agent s'intéresse à ses voisins pourvu :

  • Qu'il se situe dans son champ de vision (c.à.d plus ou moins devant lui)
  • Qu'il se situe à une distance relativement proche

Si ces conditions sont remplies, alors 3 comportements sont possibles :

  • Si la distance est plus petite que le rayon de répulsion, l'agent va se détourner de son voisin
  • Si la distance est plus petite que le rayon d'alignement, l'agent va moyenner son vecteur vitesse avec son voisin. Principalement la direction, et dans une moindre mesure, le module de la vitesse.
  • Si la distance est plus petite que le rayon d'attraction, l'agent va essayer de se rapprocher de son voisin.

Ces calculs sont effectués pour tous les voisins concernés, le nouveau cap de l'agent sera obtenu via une moyenne des influences.

Calculer la moyenne de deux angles, sans être une tâche vraiment difficile, pose néanmoins quelques questions. (Quel est l'angle moyen entre 179° et -179° ?, pas 0° pour sûr, mais bien 180°). Ceci m'a conduit à l'équation suivante (moyenne pondérée de 2 angles ou plus) :

function averageAngle(angles, weights) {
    var cx = 0;
    var cy = 0;
    for(var j = 0 ; j < angles.length ; j++){
        cx = cx + Number(weights[j]) * Math.cos(Number(angles[j]));
        cy = cy + Number(weights[j]) * Math.sin(Number(angles[j]));
    }    
    return Math.atan2(cy, cx);;
}

Autre petite difficulté : trouver l'écart angulaire entre deux angles. Ceci n'est pas non plus si évident et voici l'équation qui se charge de ce calcul :

function signedMinAngleBetween(angle1, angle2) {
    return Math.atan2(Math.sin(angle1-angle2), Math.cos(angle1-angle2))
}
>> Réagir à cet article