Projet : étape 4.1
Ondes

Buts: Modéliser les ondes émises par les lézards lors de leurs déplacements

Ondes

Nous adopterons le modèle simplifié suivant pour les ondes émises par les lézard :

Il vous est donc demandé maintenant de coder une classe Wave caractérisée par  :

Pour dessiner l'onde, il faudra dessiner les arcs qui la constituent. La méthode buildArc fournie dans Utility[.hpp][cpp] pourra être utilisée. L'épaisseur du trait pourra être proportionnel à l'intensité de l'onde selon un facteur getAppConfig().wave_intensity_thickness_ratio.

[Question Q4.1] Quel liens d'héritage vous semble t-il pertinent d'établir lors du codage de la classe Wave ?

[Question Q4.2] Comment comptabilisez-vous le temps écoulé depuis le début de la propagation de l'onde pour faire évoluer le rayon de celle-ci ? Répondez à ces questions dans votre fichier fichier REPONSES et adaptez votre code en conséquence.

Retouche à la classe Environment

Vous considérerez que les ondes appartiennent à l'environnement et ajouterez à la classe Environment une méthode addWave(Wave*).

Une onde dont l'intensité est trop faible (en dessous de getAppConfig().wave_intensity_threshold) doit disparaître de l'environnement.

[Question Q4.3] Quelles retouches devez vous faire à la Environment pour prendre en compte la présence des ondes et les voir se propager et se dessiner ? Répondez à cette question dans votre fichier fichier REPONSES.

Test 23 : propagation d'ondes

Le test fourni WaveTest.cpp que vous pouvez lancer au moyen de la cible waveTest permet de tester la propagation des ondes et leur représentation graphique. Ce test est programmé de sorte à ce qu'un clic gauche avec la souris crée un onde. Cette dernière doit alors se propager selon le modèle de la petite vidéo suivante (redémarrez-là au besoin):

[Video : propagation d'ondes]

Obstacles sur le parcours de l'onde

Il est question maintenant de simuler le fait que l'onde peut se fragmenter sur des obstacles. La mise à jour de l'onde doit donc en plus se préoccuper de l'éventualité d'une collision avec un obstacle. Nous considérerons pour simplifier que tous les obstacles sont des Collider.

Définissez Rock comme une sous classe de Collider représentant un obstacle solide (libre à vous d'étendre cette conception et de coder une hiérarchie d'obstacles solides dont dérivera Rock). Un rocher est un objet dessinable doté d'une orientation (angle). Son constructeur prendra en paramètre sa position (un Vec2d) et tirera au hasard son orientation entre -PI et PI au moyen de la fonction aléatoire uniform (fournie dans Random/Random.[hpp/cpp]). Le rayon d'un Rock sera tiré au hasard entre getAppConfig().simulation_world_size/50 et 2*getAppConfig().simulation_world_size/50, mais vaudra au minimum 1.

La texture rock.png pourra être utilisée pour le dessin. Vous pouvez enrichir vos fichiers de configuration en conséquence (cette texture n'y a pas été incluse). Si vous le faites, il est recommandé que cet ajout soit fait dans app.json (qui est le fichier de configuration par défaut à partir de cette étape), appPPS.json, appTest.json, reprod.json et dans tout autre fichier de configuration que vous auriez créé par vous même. Ainsi ces fichiers de configurations spécifiques demeureront conformes à l'évolution du code dans cette étape du projet.
Modifiez Environment pour la rendre compatible avec la méthode newObstacle de WaveTest (une fois décommentée).

[Question Q4.4] Quelle(s) autre(s) modification(s) devez vous apporter à la classe Environment suite à l'ajout de la méthode newObstacle?

Modifiez ensuite la méthode de mise à jour de Wave de sorte à ce qu'elle intègre aussi la détection de collision avec des obstacles de l'environnement. Une collision est détectée avec un obstacle de l'environnement si ce dernier est en collision avec l'onde ou est à l'intérieur de celle-ci (en tant que Collider). Pour simplifier, on ne tiendra compte que des obstacles dont la position se trouve dans un des arcs de l'onde :

Fragmentation d'arc
← le second obstacle ne fragmente pas l'onde en plus petits arcs même si un des arcs le touche un peu
(il faut que le centre de l'obstacle soit dans un arc pour qu'il ait effet sur lui)
Pour trouver si l'obstacle se trouve dans un des arcs, arci, de l'onde, il suffit de tester que l'angle (obstacle_position - origin).angle(), est contenu dans arci (supérieur ou égal au début de arci et inférieur ou égal à sa fin). origin est l'origine de l'onde et obstacle_position la position de l'obstacle.

Vous fragmenterez l'arc en vous inspirant des indications du schéma suivant:

Fragmentation d'arc
← l'angle α qui permet de scinder l'arc bleu en deux arcs rouges
peut se calculer selon la formule 2 * std::atan2(r, R + r)
(le cercle dans la figure représente l'obstacle).
R est le rayon de l'onde et r celui de l'obstacle.

Test 24 : fragmentation d'ondes

Pour tester cette partie, vous pourrez à nouveau utiliser WaveTest.cpp que vous pouvez lancer au moyen de la commande waveTest.

Décommentez au préalable dans ce test la méthode newObstacle ainsi que la gestion du clic droit sur la souris.

Créez plusieurs obstacles et ondes, vous devriez pouvoir observer la fragmentation de vos ondes selon l'exemple suivant:

[Video : propagation d'ondes avec obstacles]
Vous pouvez affiner le modèle en empêchant l'émission d'ondes à partir d'un obstacle.

Lézards émetteurs d'ondes

Un lézard émetteur d'ondes (classe WaveLizard) est une Lizard qui a en plus la particularité d'émettre des ondes toutes les 1.0/getAppConfig().wave_lizard_frequency secondes.

Les ondes émises seront bien sûr générées avec pour origine la position de la lézard et ajoutée à l'environnement.

Les autres caractéristiques de l'onde seront les suivantes :

Vous pouvez coder la classe WaveLizard dans un répertoire Animal/NeuronalScorpion/.

Constructeurs

Pour être compatible avec les fichiers de tests fourni, le WaveLizard aura des constructeurs aux signatures analogues à ceux codés pour Lizard.

Vous veillerez à faire le reste des initialisations qui s'imposent.

Test 25 : lézard émetteur d'ondes

Vous pouvez maintenant commencer à utiliser le programme principal correpondant à l'ensemble de votre projet : FinalApplication.cpp. Ce programme vous permet de tester le nouveau type de lézards ainsi créées.

Les modalités de lancement du test seront les suivantes :

Vous devriez voir une lézard se déplaçant au hasard en émettant des ondes à une fréquence régulière, tel que le montre la vidéo suivante :

[Video : lézards émetteur d'ondes]

Retour à l'énoncé du projet (partie 4) Module suivant (partie 4.2)