Project: step 4.1
Waves


Disclaimer: the automatically generated English translation is provided only for convenience and it may contain wording flaws. The original French document must be taken as reference!


Goals: Model the waves emitted by lizards during their movements

Waves

We will adopt the following simplified model for the waves emitted by the lizard:

You are now asked to code a class Wavecharacterized by:

To draw the wave, you will need to draw the arcs that make it up. The buildArc method provided in Utility[.hpp][cpp] can be used. The line thickness can be proportional to the wave intensity according to a factor getAppConfig().wave_intensity_thickness_ratio .

[Question Q4.1] What inheritance relationship seems relevant to establish when coding the Wave class?

[Question Q4.2] How do you account for the time elapsed since the beginning of the wave propagation to evolve its radius ? Answer these questions in your file file REPONSES and adapt your code accordingly.

Modification to the Environment class

You will consider that waves belong to the environment and add to the Environment class a method addWave(Wave*) .

A wave whose intensity is too weak (below getAppConfig().wave_intensity_threshold) must disappear from the environment.

[Question Q4.3] What changes do you need to make to the Environment to take into account the presence of waves and see them propagate and form? Answer this question in your file ANSWERS .

Test 23: wave propagation

The provided test WaveTest.cpp , which you can launch using the waveTest target, allows you to test wave propagation and graphical representation. This test is programmed so that a left mouse click creates a wave. The wave should then propagate according to the model shown in the following short video (restart it if necessary):

[Video: wave propagation]

Obstacles on the wave's path

It is now about simulating the fact that the wave can fragment on obstacles. The wave update must therefore also take into account the possibility of a collision with an obstacle. For simplicity, we will consider that all obstacles are Collider.

Define Rock as a subclass of Collider representing a solid obstacle (you are free to extend this design and code a hierarchy of solid obstacles from which Rock will be derived). A rock is a drawable object with an orientation (angle). Its constructor will take its position (a Vec2d ) as a parameter and will randomly draw its orientation between -PI and PI using the random function uniform (provided in Random/Random.[hpp/cpp] ). The radius of a Rock will be randomly drawn between getAppConfig().simulation_world_size/50 and 2*getAppConfig().simulation_world_size/50 , but will be at least 1 .

The texture rock.png can be used for drawing. You can enrich your configuration files accordingly (this texture was not included). If you do so, it is recommended that this addition be made in app.json (which is the default configuration file from this step), appPPS.json , appTest.json , reprod.json and in any other configuration files you may have created yourself. This way, these specific configuration files will remain consistent with the evolution of the code in this stage of the project.
Modify Environment to make it compatible with the newObstacle method of WaveTest (once uncommented).

[Question Q4.4] What other changes do you need to make to the Environment class after adding the newObstacle method?

Next, modify the update method of Wave so that it also includes collision detection with environmental obstacles. A collision is detected with an environmental obstacle if it collides with the wave or is inside it (as a Collider ). For simplicity, we will only consider obstacles whose position is within one of the arcs of the wave:

Fragmentation d'arc
← the second obstacle does not fragment the wave into smaller arcs even if one of the arcs touches it slightly
(the center of the obstacle must be within an arc for it to have an effect on it)
To find if the obstacle is in one of the arcs, arc i , of the wave, it is enough to test that the angle (obstacle_position - origin).angle() , is contained in arc i (greater than or equal to the beginning of arc i and less than or equal to its end). origin is the origin of the wave and obstacle_position the position of the obstacle.

You will fragment the arc by following the indications of the following diagram:

Fragmentation d'arc
← the angle α that splits the blue arc into two red arcs
can be calculated using the formula 2 * std::atan2(r, R + r)
(the circle in the figure represents the obstacle).
R is the radius of the wave and r that of the obstacle.

Test 24: wave fragmentation

To test this part, you can again use WaveTest.cpp which you can launch using the command waveTest .

Uncomment beforehand in this test the newObstacle method as well as the right-click handling on the mouse.

Create multiple obstacles and waves, you should be able to observe the fragmentation of your waves according to the following example:

[Video: wave propagation with obstacles]
You can refine the model by preventing the emission of waves from an obstacle.

Wave-emitting lizards

A wave-emitting lizard (class WaveLizard ) is a Lizard that has the additional feature of emitting waves every 1.0/getAppConfig().wave_lizard_frequency seconds.

The emitted waves will of course be generated originating from the position of the lizard and added to the environment.

The other characteristics of the wave will be as follows:

You can code the WaveLizard class in a Animal/NeuronalScorpion/ directory.

Constructors

To be compatible with the provided test files, the WaveLizard will have constructors with signatures similar to those coded for Lizard .

You will ensure to carry out the remaining necessary initializations.

Test 25: wave-emitting lizard

You can now start using the main program corresponding to your entire project: FinalApplication.cpp. This program allows you to test the newly created lizard type.

The launch conditions of the test will be as follows:

You should see a lizard moving randomly while emitting waves at a regular frequency, as shown in the following video:

[Video: wave-emitting lizards]

Back to the project statement (part 4) Next module (part 4.2)