--- exports: - format: pdf output: TD.pdf template: ../../template/TD - format: tex output: TDmd.tex template: ../../template/TD jupytext: text_representation: extension: .md format_name: myst format_version: 0.13 kernelspec: display_name: C++17 language: C++17 name: xcpp17 --- # TD 10 : compilation séparée, graphiques +++ {"deletable": false, "nbgrader": {"cell_type": "markdown", "checksum": "810c04226cda9f4619e3d6c4d644b336", "grade": true, "grade_id": "10", "locked": false, "points": 0, "schema_version": 3, "solution": true}} ::::{admonition} Exercice 1 : Compilation séparée Annotez les quatre fichiers suivants en précisant leurs rôles respectifs et en indiquant où se trouvent entête, définition, documentation, tests et utilisation de la fonction `factorielle`. :::{literalinclude} factorielle.hpp :caption: factorielle.hpp ::: :::{literalinclude} factorielle.cpp :caption: factorielle.cpp ::: :::{literalinclude} factorielle-test.cpp :caption: factorielle-test.cpp ::: {latexonly}`\clearpage` :::{literalinclude} factorielle-exemple.cpp :caption: factorielle-exemple.cpp ::: :::: % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE {latexonly}`\bigskip` {latexonly}`\enlargethispage{8ex}` ## Graphiques En TP, nous utiliserons la bibliothèque `SFML` [^1], une bibliothèque largement utilisée facilitant le développement de jeux ou d'applications multimédias grâce à une grande panoplie de modules (fenêtrage, graphismes, audio, réseau, ...), principalement développée par Laurent Gomila. Nous allons nous en servir pour créer une fenêtre et dessiner dedans. La `SFML` n'étant pas immédiatement intuitive à utiliser, nous avons écrit une micro bibliothèque composée de quelques primitives pour vous simplifier les premiers pas. Cette bibliothèque, documentée dans `primitives.hpp`, a vocation à être la plus transparente possible. À vous de la lire en détail pour vous l'approprier et, par la suite, vous en passer. Voici un exemple de programme utilisant la `SFML` et notre bibliothèque `primitives` : :::{literalinclude} exemple-graphisme1.cpp :caption: exemple-graphisme1.cpp ::: Notez dans cet exemple le nouveau type `RenderWindow` représentant une fenêtre et les fonctions `clear` pour effacer la fenêtre, `sleep` pour attendre un temps donné et `draw_point` (qui vient de `primitives.cpp`) pour dessiner un point. +++ {"deletable": false, "nbgrader": {"cell_type": "markdown", "checksum": "1986e35cfea627cd75aaacb627e8ad3c", "grade": true, "grade_id": "20", "locked": false, "points": 0, "schema_version": 3, "solution": true}} ::::{admonition} Exercice 2 : Premiers dessins En vous inspirant de l'exemple fourni, écrivez des instructions (fragments de programme) qui, respectivement, 1. dessinent un point noir (*Black*) de coordonnées $(418, 143)$; % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 2. dessinent un segment blanc (*White*) reliant les points $(100, 200)$ et $(200, 200)$; % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 3. dessinent un segment rouge (*Red*) reliant les points $(200, 300)$ et $(200, 400)$; % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 4. dessinent le rectangle horizontal vide de contour rouge dont les sommets diagonaux sont $(200, 200)$ et $(400, 300)$; % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 5. dessinent un rectangle horizontal plein noir dont les sommets diagonaux sont $(400, 150)$ et $(500, 200)$; % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 6. dessinent un segment rouge reliant les points $(400, 300)$ et $(500, 400)$; % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 7. dessinent un cercle noir de centre $(415, 145)$ et de rayon $10$; **Indication :** Utiliser les fonctions `cos` et `sin`. % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 8. dessinent un disque jaune (*Yellow*) de centre $(700, 100)$ et de rayon $50$; **Indication :** Utiliser la définition d'un disque. % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE :::: +++ {"deletable": false, "nbgrader": {"cell_type": "markdown", "checksum": "be45863a53351171a30bb896289f3266", "grade": true, "grade_id": "30", "locked": false, "points": 0, "schema_version": 3, "solution": true}} {latexonly}`\enlargethispage{2ex}` ::::{admonition} Exercice 3 : $\clubsuit$ Fonctions de dessin Notre bibliothèque `primitives` contient entre autres les fonctions suivantes : /** Affiche une ligne de couleur entre deux positions données * @param w une fenêtre ouverte dans laquelle dessiner * @param pos1 les coordonnées du premier point de la ligne * @param pos1 les coordonnées du dernier point de la ligne * @param color la couleur de la ligne */ void draw_line (RenderWindow& w, Point pos1, Point pos2, Color color); /** Affiche un cercle coloré vide * @param w une fenêtre ouverte dans laquelle dessiner * @param center la position du centre du cercle * @param r le rayon du cercle * @param color la couleur du trait */ void draw_circle (RenderWindow& w, Point center, int r, Color color); /** Affiche un cercle coloré plein * @param w une fenêtre ouverte dans laquelle dessiner * @param center la position du centre du cercle * @param r le rayon du cercle * @param color la couleur du trait et du remplissage */ void draw_filled_circle(RenderWindow& w, Point center, int r, Color color); À noter qu'elles prennent la fenêtre où dessiner comme premier paramètre (`w`). Le symbole `&` indique que cette fenêtre est passée par référence afin que les fonctions puissent la modifier. Vous pouvez essentiellement ignorer ce détail technique dont vous verrez les tenants et les aboutissants au deuxième semestre. Notez aussi les variables de type `Point`. Ces dernières représentent des coordonnées. On peut créer un point et accéder à ses coordonnées comme suit : ``` Point p = {42, 2713}; int x = p.x; // 42 int y = p.y; // 2713 ``` Techniquement parlant, il s'agit d'un *enregistrement* (*struct* en anglais); vous en verrez les détails au deuxième semestre. Dans notre bibliothèque, ces fonctions sont implémentées via des appels directs à des fonctions de la `SFML`. Par exemple : :::{literalinclude} primitives.cpp :start-after: BEGIN draw_filled_circle :end-before: END draw_filled_circle ::: 1. Réimplantez ces fonctions, en n'utilisant que des appels à `draw_point`. % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE :::: +++ {"deletable": false, "nbgrader": {"cell_type": "markdown", "checksum": "09775fae68e86d2b7c93e81b29b3bbb4", "grade": true, "grade_id": "40", "locked": false, "points": 0, "schema_version": 3, "solution": true}} ::::{admonition} Exercice 4 : Souris et Clavier Voici maintenant un fragment de programme interactif utilisant la `SFML` et notre bibliothèque `primitives` pour réagir à des actions avec la souris ou le clavier. :::{literalinclude} exemple-graphisme2.cpp :start-after: BEGIN :end-before: END :caption: exemple-graphisme2.cpp ::: 1. En vous inspirant du programme précédent, écrivez un programme qui attend que l'utilisateur clique sur deux points de l'écran puis qui trace le segment les reliant. % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 2. Écrivez un programme qui attend que l'utilisateur clique sur quatre points puis qui dessine le quadrilatère ayant ces quatre points comme sommets. % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE 3. Écrivez un programme qui dessine des polygones de la façon suivante : l'utilisateur clique sur des points successifs. À chaque clic, le programme relie les deux derniers points. Si l'utilisateur clique près du point initial, le polygone se ferme, et le programme commence un nouveau polygone. % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE :::: [^1]: <https://www.sfml-dev.org>