diff --git a/Algo/tp/Cpp/tp4/.idea/.gitignore b/Algo/tp/Cpp/tp4/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/Algo/tp/Cpp/tp4/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/Algo/tp/Cpp/tp4/.idea/discord.xml b/Algo/tp/Cpp/tp4/.idea/discord.xml new file mode 100644 index 0000000..30bab2a --- /dev/null +++ b/Algo/tp/Cpp/tp4/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/Algo/tp/Cpp/tp4/.idea/misc.xml b/Algo/tp/Cpp/tp4/.idea/misc.xml new file mode 100644 index 0000000..53624c9 --- /dev/null +++ b/Algo/tp/Cpp/tp4/.idea/misc.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/Algo/tp/Cpp/tp4/Makefile b/Algo/tp/Cpp/tp4/Makefile new file mode 100644 index 0000000..e40974c --- /dev/null +++ b/Algo/tp/Cpp/tp4/Makefile @@ -0,0 +1,20 @@ +cc=g++ -std=c++17 -g -Wall -Werror -pedantic + +all: tp + +obj/Wagon.o: src/Wagon.cpp src/Wagon.h src/Passager.h + $(cc) -c src/Wagon.cpp -o obj/Wagon.o +obj/Passager.o: src/Passager.cpp src/Passager.h + $(cc) -c src/Passager.cpp -o obj/Passager.o +obj/main.o: src/main.cpp src/Train.h src/Wagon.h src/Passager.h \ + src/TrainExceptions.h + $(cc) -c src/main.cpp -o obj/main.o +obj/Train.o: src/Train.cpp src/Train.h src/Wagon.h src/Passager.h \ + src/TrainExceptions.h + $(cc) -c src/Train.cpp -o obj/Train.o + +tp: obj/Wagon.o obj/Passager.o obj/main.o obj/Train.o + $(cc) obj/Wagon.o obj/Passager.o obj/main.o obj/Train.o -o tp + +clean: + rm -Rf obj/* tp diff --git a/Algo/tp/Cpp/tp4/obj/Passager.o b/Algo/tp/Cpp/tp4/obj/Passager.o new file mode 100644 index 0000000..aff165c Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/Passager.o differ diff --git a/Algo/tp/Cpp/tp4/obj/Train.o b/Algo/tp/Cpp/tp4/obj/Train.o new file mode 100644 index 0000000..7456024 Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/Train.o differ diff --git a/Algo/tp/Cpp/tp4/obj/Wagon.o b/Algo/tp/Cpp/tp4/obj/Wagon.o new file mode 100644 index 0000000..97ecfda Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/Wagon.o differ diff --git a/Algo/tp/Cpp/tp4/obj/main.o b/Algo/tp/Cpp/tp4/obj/main.o new file mode 100644 index 0000000..6ab5c92 Binary files /dev/null and b/Algo/tp/Cpp/tp4/obj/main.o differ diff --git a/Algo/tp/Cpp/tp4/src/Passager.cpp b/Algo/tp/Cpp/tp4/src/Passager.cpp new file mode 100644 index 0000000..80cf871 --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/Passager.cpp @@ -0,0 +1,17 @@ +#include "Passager.h" + +using namespace std; + +Passager::Passager(std::string nom, std::string prenom) + : nom{std::move(nom)}, prenom{std::move(prenom)} {} + +/*Passager& Passager::operator=(const Passager& o) { + if (o == *this) return *this; + nom = o.bom; + prenom = o.nom; + return *this; +}*/ + +std::ostream& operator<<(std::ostream& os, const Passager& passager) { + return os << passager.nom << " " << passager.prenom; +} diff --git a/Algo/tp/Cpp/tp4/src/Passager.h b/Algo/tp/Cpp/tp4/src/Passager.h new file mode 100644 index 0000000..f73cba8 --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/Passager.h @@ -0,0 +1,16 @@ +#include +#include + +class Passager { +private: + std::string nom; + std::string prenom; +public: + friend std::ostream& operator<<(std::ostream& os, const Passager& passagers); + Passager() = default; + Passager(std::string nom, std::string prenom); + Passager& operator=(const Passager& o) = default; +}; + +std::ostream& operator<<(std::ostream& os, const Passager& passager); + diff --git a/Algo/tp/Cpp/tp4/src/Train.cpp b/Algo/tp/Cpp/tp4/src/Train.cpp new file mode 100644 index 0000000..c5fdf4b --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/Train.cpp @@ -0,0 +1,138 @@ +#include "Train.h" + +#include "TrainExceptions.h" + +// Si des passagers peuvent être à deux endroits à la fois, il va potentiellement falloir le faire descendre deux fois du train. +#define UBIQUITE + +using namespace std; + +Train::Train(int nbWagons) + : lesWagons{} { + //lesWagons.reserve(nbWagons); + for (int i = 1; i <= nbWagons; ++i) { + lesWagons.emplace_back(i); + } +} + +Train::Train(std::initializer_list listeNumerosWagons) + : lesWagons{} { + //lesWagons.reserve(listeNumerosWagons.size()); + for (int numWagon : listeNumerosWagons) { + //lesWagons.push_back(new Wagon{numWagon}); + lesWagons.emplace_back(numWagon); + } +} + +void Train::demarrer() { + roule = true; +} + +void Train::arreter() { + roule = false; +} + +bool Train::isRoule() const { + return roule; +} + +void Train::monterDansLeTrain(int numeroWagon, const Passager& passager) { + if (roule) { + throw RouleException{}; + } + // -> map + for (Wagon& wagon : lesWagons) { + if (wagon.getNumero() == numeroWagon) { + if (!wagon.ajouter(passager)) { + throw WagonPleinException{}; + } + return; + } + } + throw WagonInexistantException{}; +} + +void Train::descendreDuTrain(const Passager& passager) { + if (roule) { + throw RouleException{}; + } +#ifdef UBIQUITE + bool descendu = false; + for (Wagon& wagon : lesWagons) { + descendu |= wagon.enlever(passager); + } + if (!descendu) { + throw PassagerException{}; + } +#else + for (Wagon& wagon : lesWagons) { + if (wagon.enlever(passager)) { + return; + } + } + throw PassagerException{}; +#endif +} + +void Train::deplacerAuWagonSuivant(const Passager& passager) { + if (roule) { + throw RouleException{}; + } + vector::iterator it = lesWagons.begin(); + while (it != lesWagons.end() && !it->enlever(passager)) { + ++it; + } + if (it == lesWagons.end()) { + throw PassagerException{}; + } + ++it; + if (it == lesWagons.end()) { + throw BoutDuTrainException{}; + } + if (it->estPlein()) { + throw WagonPleinException{}; + } + it->ajouter(passager); +} + +void Train::deplacerAuWagonPrecedent(const Passager& passager) { + if (roule) { + throw RouleException{}; + } + vector::reverse_iterator it = lesWagons.rbegin(); + while (it != lesWagons.rend() && !it->enlever(passager)) { + ++it; + } + if (it == lesWagons.rend()) { + throw PassagerException{}; + } + ++it; + if (it == lesWagons.rend()) { + throw BoutDuTrainException{}; + } + if (it->estPlein()) { + throw WagonPleinException{}; + } + it->ajouter(passager); +} + +int Train::monterDansLeTrainAPartirDe(int numeroWagon, const Passager& passager) { + if (roule) { + throw RouleException{}; + } + vector::iterator it = lesWagons.begin(); + while (it != lesWagons.end() && it->getNumero() != numeroWagon) { + ++it; + } + if (it == lesWagons.end()) { + throw WagonInexistantException{}; + } + while (it != lesWagons.end() && it->estPlein()) { + ++it; + } + if (it == lesWagons.end()) { + throw BoutDuTrainException{}; + } + it->ajouter(passager); + return it->getNumero(); +} diff --git a/Algo/tp/Cpp/tp4/src/Train.h b/Algo/tp/Cpp/tp4/src/Train.h new file mode 100644 index 0000000..3a03bd9 --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/Train.h @@ -0,0 +1,22 @@ +#include +#include + +#include "Wagon.h" + +class Train { +private: + std::vector lesWagons; + bool roule{}; +public: + explicit Train(int nbWagons); + Train(std::initializer_list listeNumerosWagons); + void demarrer(); + void arreter(); + bool isRoule() const; + void monterDansLeTrain(int numeroWagon, const Passager& passager); + int monterDansLeTrainAPartirDe(int numeroWagon, const Passager& passager); + void descendreDuTrain(const Passager& passager); + void deplacerAuWagonPrecedent(const Passager& passager); + void deplacerAuWagonSuivant(const Passager& passager); +}; + diff --git a/Algo/tp/Cpp/tp4/src/TrainExceptions.h b/Algo/tp/Cpp/tp4/src/TrainExceptions.h new file mode 100644 index 0000000..29f4413 --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/TrainExceptions.h @@ -0,0 +1,10 @@ +#ifndef TRAIN_EXCEPTIONS_HPP +#define TRAIN_EXCEPTIONS_HPP + +class RouleException {}; +class WagonInexistantException {}; +class WagonPleinException {}; +class PassagerException {}; +class BoutDuTrainException {}; + +#endif // TRAIN_EXCEPTIONS_HPP diff --git a/Algo/tp/Cpp/tp4/src/Wagon.cpp b/Algo/tp/Cpp/tp4/src/Wagon.cpp new file mode 100644 index 0000000..0f6d81b --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/Wagon.cpp @@ -0,0 +1,48 @@ +#include "Wagon.h" + +Wagon::Wagon(int numero) : numero{numero}, lesPassagers{} { + +} + +int Wagon::getNumero() const { + return numero; +} + +bool Wagon::estPlein() const { + return lesPassagers.size() >= capacite; +} + +bool Wagon::ajouter(const Passager& passager) { + if (lesPassagers.size() >= capacite) { + return false; + } + lesPassagers.push_front(&passager); + return true; +} + +bool Wagon::enlever(const Passager& passager) { + std::list::size_type previous = lesPassagers.size(); + lesPassagers.remove(&passager); + return previous != lesPassagers.size(); +} + +int Wagon::debarquer(int nbPassager) { + int c = nbPassager; + while (!lesPassagers.empty() && c > 0) { + lesPassagers.pop_back(); + --c; + } + return nbPassager - c; +} + +std::ostream& operator<<(std::ostream& os, const Wagon& wagon) { + if (wagon.lesPassagers.empty()) { + return os; + } + std::list::const_iterator it = wagon.lesPassagers.cbegin(); + os << **it; + while (++it != wagon.lesPassagers.cend()) { + os << ", " << **it; + } + return os; +} diff --git a/Algo/tp/Cpp/tp4/src/Wagon.h b/Algo/tp/Cpp/tp4/src/Wagon.h new file mode 100644 index 0000000..746fa4a --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/Wagon.h @@ -0,0 +1,22 @@ +#include +#include + +#include "Passager.h" + +class Wagon { +private: + constexpr static int capacite = 20; + int size; + int numero; + std::list lesPassagers; +public: + friend std::ostream& operator<<(std::ostream& os, const Wagon& wagon); + explicit Wagon(int numero); + int getNumero() const; + bool estPlein() const; + bool ajouter(const Passager& passager); + bool enlever(const Passager& passager); + int debarquer(int nbPassager); +}; + +std::ostream& operator<<(std::ostream& os, const Wagon& wagon); diff --git a/Algo/tp/Cpp/tp4/src/main.cpp b/Algo/tp/Cpp/tp4/src/main.cpp new file mode 100644 index 0000000..b64e681 --- /dev/null +++ b/Algo/tp/Cpp/tp4/src/main.cpp @@ -0,0 +1,355 @@ +#include "Train.h" +#include "TrainExceptions.h" + +#include +#include + +using namespace std; +using Gens = std::array; + +void testsWagon() { + Passager pierre("Dupont", "Pierre"); + Passager paul("Durand", "Paul"); + + cout << "Vérif si wagon gère correctement son numero... "; + Wagon wagon{42}; + cout << (wagon.getNumero() == 42 ? "OK\n" : "ERREUR\n"); + + cout << "Vérif si possible de faire monter 20 personnes dans un wagon... "; + Gens gens; + for (Gens::size_type i{0}; i < gens.size(); ++i) + gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"}; + + bool ajoutOK{true}; + for (const Passager &personne : gens) { + ajoutOK = ajoutOK && wagon.ajouter(personne); + } + cout << (ajoutOK ? "OK\n" : "ERREUR\n"); + //cout << wagon << "\n"; + + cout << "Vérif si impossible de faire monter 1 personne dans un wagon " + "plein... "; + cout << (wagon.ajouter(pierre) ? "ERREUR\n" : "OK\n"); + + cout << "Vérif si possible de faire debarquer 14 personnes sur 20... "; + cout << (wagon.debarquer(14) == 14 ? "OK\n" : "ERREUR\n"); + // cout << wagon; + + cout << "Vérif si possible de faire debarquer les 6 passagers restants... "; + cout << (wagon.debarquer(20) == 6 ? "OK\n" : "ERREUR\n"); + // cout << wagon; + + cout << "Vérif si possible de faire debarquer 1 passager donné... "; + wagon.ajouter(pierre); + cout << (wagon.enlever(pierre) ? "OK\n" : "ERREUR\n"); + + cout << "Vérif si impossible de faire debarquer 1 passager pas dans le " + "wagon... "; + cout << (wagon.enlever(paul) ? "ERREUR\n" : "OK\n"); + + cout << "Vérif si impossible de faire debarquer 1 passager d'un wagon " + "vide... "; + cout << (wagon.enlever(pierre) ? "ERREUR\n" : "OK\n"); +} + +void testMonterDansTrain() { + Passager pierre{"Dupont", "Pierre"}; + Train train(3); + + cout << "Vérif si impossible de monter dans un train qui roule... "; + train.demarrer(); + try { + train.monterDansLeTrain(1, pierre); + cout << "ERREUR\n"; + } catch (const RouleException &) { + cout << " OK\n"; + } + + cout << "Vérif si impossible de monter si numéro de wagon non existant... "; + train.arreter(); + try { + train.monterDansLeTrain(4, pierre); + cout << "ERREUR\n"; + } catch (const WagonInexistantException &) { + cout << "OK\n"; + } + + cout << "Vérif si possible de faire monter 20 personnes dans un wagon " + "existant, non complet et train arrêté... "; + Gens gens; + for (Gens::size_type i{0}; i < gens.size(); ++i) + gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"}; + + try { + for (const Passager &personne : gens) { + train.monterDansLeTrain(1, personne); + } + cout << "OK\n"; + } catch (...) { + cout << "ERREUR\n"; + } + + cout << "Vérif si impossible de monter dans le wagon si déjà complet... "; + try { + train.monterDansLeTrain(1, pierre); + cout << "ERREUR\n"; + } catch (const WagonPleinException &) { + cout << "OK\n"; + } +} + +void testDescendreDuTrain() { + Passager pierre("Dupont", "Pierre"); + Passager paul("Durand", "Paul"); + Train train(3); + + // cout << "Pierre monte dans le wagon 1\n"; + train.monterDansLeTrain(1, pierre); + + cout << "Vérif si impossible de descendre du train qui roule... "; + train.demarrer(); + try { + train.descendreDuTrain(pierre); + cout << "ERREUR\n"; + } catch (const RouleException &) { + cout << " OK\n"; + } + + // cout << "Paul n'est pas dans le train\n"; + cout << "Vérif si impossible de descendre du train sans s'y trouver... "; + train.arreter(); + try { + train.descendreDuTrain(paul); + cout << "ERREUR\n"; + } catch (const PassagerException &) { + cout << "OK\n"; + } + + cout << "Vérif si possible de descendre du wagon existant et train " + "arrêté... "; + try { + train.descendreDuTrain(pierre); + cout << " OK\n"; + } catch (...) { + cout << "ERREUR\n"; + } +} + +void testDeplacerAuWagonSuivant() { + Passager alice("Dups", "Alice"); + Passager pierre("Dupont", "Pierre"); + Passager paul("Durand", "Paul"); + Passager marie("Dumont", "Marie"); + Train train(3); + + // cout << "Pierre monte dans le premier wagon (1)\n"; + train.monterDansLeTrain(1, pierre); + // cout << "Paul monte dans le wagon 2\n"; + train.monterDansLeTrain(2, paul); + // cout << "Marie monte dans le dernier wagon (3)\n"; + train.monterDansLeTrain(3, marie); + // cout << "Alice n'est pas dans le train\n"; + + cout << "Vérif si impossible de déplacer un passager qui n'est pas dans le " + "train... "; + try { + train.deplacerAuWagonSuivant(alice); + cout << "ERREUR\n"; + } catch (const PassagerException &) { + cout << " OK\n"; + } + + cout << "Vérif si impossible de passer au wagon suivant car déjà dans le " + "dernier wagon... "; + try { + train.deplacerAuWagonSuivant(marie); + cout << "ERREUR\n"; + } catch (const BoutDuTrainException &) { + cout << " OK\n"; + } + + Gens gens; + for (Gens::size_type i{0}; i < gens.size() - 1; ++i) + gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"}; + + try { + for (const Passager &personne : gens) + train.monterDansLeTrain(3, personne); + } catch (...) { + cout << "ERREUR le wagon 3 devrait pouvoir contenir 20 passagers !\n"; + } + + cout << "Vérif si impossible de passer au wagon suivant car wagon déjà " + "complet... "; + try { + train.deplacerAuWagonSuivant(paul); + cout << "ERREUR\n"; + } catch (const WagonPleinException &) { + cout << "OK\n"; + } + + cout << "Vérif si possible de passer au wagon suivant (bonnes " + "conditions)... "; + try { + train.deplacerAuWagonSuivant(pierre); + cout << "OK\n"; + } catch (...) { + cout << "ERREUR\n"; + } +} + +void testDeplacerAuWagonPrecedent() { + Passager alice("Dups", "Alice"); + Passager pierre("Dupont", "Pierre"); + Passager paul("Durand", "Paul"); + Passager marie("Dumont", "Marie"); + Train train(3); + + // cout << "Pierre monte dans le premier wagon (1)\n"; + train.monterDansLeTrain(1, pierre); + // cout << "Paul monte dans le wagon 2\n"; + train.monterDansLeTrain(2, paul); + // cout << "Marie monte dans le dernier wagon (3)\n"; + train.monterDansLeTrain(3, marie); + // cout << "Alice n'est pas dans le train\n"; + + cout << "Vérif si impossible de déplacer au wagon précédent un passager " + "qui n'est pas dans le train... "; + try { + train.deplacerAuWagonPrecedent(alice); + cout << "ERREUR\n"; + } catch (const PassagerException &) { + cout << " OK\n"; + } + + cout << "Vérif si impossible de passer au wagon précédent car déjà dans le " + "premier wagon... "; + try { + train.deplacerAuWagonPrecedent(pierre); + cout << "ERREUR\n"; + } catch (const BoutDuTrainException &) { + cout << " OK\n"; + } + + Gens gens; + for (Gens::size_type i{0}; i < gens.size() - 1; ++i) + gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"}; + + try { + for (const Passager &personne : gens) + train.monterDansLeTrain(1, personne); + } catch (...) { + cout << "ERREUR le wagon 1 devrait pouvoir contenir 20 passagers !\n"; + } + + cout << "Vérif si impossible de passer au wagon précédent car wagon déjà " + "complet... "; + try { + train.deplacerAuWagonPrecedent(paul); + cout << "ERREUR\n"; + } catch (const WagonPleinException &) { + cout << "OK\n"; + } + + cout << "Vérif si possible de passer au wagon précédent (bonnes " + "conditions)... "; + try { + train.deplacerAuWagonPrecedent(marie); + cout << "OK\n"; + } catch (...) { + cout << "ERREUR\n"; + } +} + +void testMonterDansLeTrainAPartirDe() { + Passager pierre("Dupont", "Pierre"); + Train train(3); + + cout << "Vérif si impossible de monter à partir d'un numero de wagon non " + "existant... "; + try { + train.monterDansLeTrainAPartirDe(4, pierre); + cout << "ERREUR\n"; + } catch (const WagonInexistantException &) { + cout << "OK\n"; + } + + train.demarrer(); + cout << "Vérif si impossible de monter dans un train qui roule... "; + try { + train.monterDansLeTrainAPartirDe(1, pierre); + cout << "ERREUR\n"; + } catch (const RouleException &) { + cout << "OK\n"; + } + + train.arreter(); + Gens gens; + for (Gens::size_type i{0}; i < gens.size() - 1; ++i) + gens[i] = Passager{"Personne " + to_string(i + 1), "Autogénérée"}; + + // On remplit tous les wagons (on triche un peu) + // Magie de l'informatique, on donne le don d'ubiquité aux gens + try { + for (const Passager &personne : gens) { + train.monterDansLeTrain(1, personne); + train.monterDansLeTrain(2, personne); + train.monterDansLeTrain(3, personne); + } + } catch (...) { + cout << "ERREUR on devrait pouvoir remplir le train !\n"; + } + + cout << "Vérif si impossible de monter dans un train complet... "; + try { + train.monterDansLeTrainAPartirDe(1, pierre); + cout << "ERREUR\n"; + } catch (const BoutDuTrainException &) { + cout << "OK\n"; + } + + try { + for (const Passager &personne : gens) { + train.descendreDuTrain(personne); + } + } catch (...) { + cout << "ERREUR on devrait pouvoir vider le premier wagon !\n"; + } + + cout << "Vérif si on peut monter dans un train où il y a de la place... "; + try { + int pos = train.monterDansLeTrainAPartirDe(2, pierre); + cout << "OK, " << pierre << " est monté dans le wagon " << pos << "\n"; + } catch (...) { + cout << "ERREUR\n"; + } + + cout << "Vérif si le passager peut descendre... "; + try { + train.descendreDuTrain(pierre); + cout << "OK\n"; + } catch (...) { + cout << "ERREUR\n"; + } +} + +int main() { + cout << "---------- TESTS WAGONS ------------\n"; + testsWagon(); + + cout << "---------- TEST MONTER DANS LE TRAIN ------------\n"; + testMonterDansTrain(); + + cout << "---------- TEST DESCENDRE DU TRAIN ------------\n"; + testDescendreDuTrain(); + + cout << "---------- TEST DEPLACER AU WAGON SUIVANT ------------\n"; + testDeplacerAuWagonSuivant(); + + cout << "---------- TEST DEPLACER AU WAGON PRECEDENT ------------\n"; + testDeplacerAuWagonPrecedent(); + + cout << "---------- TEST MONTER DANS LE TRAIN A PARTIR DE " + "------------\n"; + testMonterDansLeTrainAPartirDe(); +} diff --git a/Algo/tp/Cpp/tp4/tp b/Algo/tp/Cpp/tp4/tp new file mode 100755 index 0000000..7fb2c7f Binary files /dev/null and b/Algo/tp/Cpp/tp4/tp differ diff --git a/Maths/tp/Bezier/tp3 - polices de caractères-20230210/TP3_polices.pdf b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/TP3_polices.pdf new file mode 100644 index 0000000..0d7d04e Binary files /dev/null and b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/TP3_polices.pdf differ diff --git a/Maths/tp/Bezier/tp3 - polices de caractères-20230210/m.svg b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/m.svg new file mode 100644 index 0000000..71ac257 --- /dev/null +++ b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/m.svg @@ -0,0 +1,208 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + (5.8;2.5) + (4.8;2.5) + (3.7;2.5) + (0.8;2.5) + (0.8;0.7) + (0.8;1.7) + (0.9;3.5) + (1;4.3) + (1;4.9) + (1.35;5.2) + (1;5.2) + + + + + diff --git a/Maths/tp/Bezier/tp3 - polices de caractères-20230210/tp3_exo2.py b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/tp3_exo2.py new file mode 100644 index 0000000..ae68fb7 --- /dev/null +++ b/Maths/tp/Bezier/tp3 - polices de caractères-20230210/tp3_exo2.py @@ -0,0 +1,274 @@ + +import numpy as np +import matplotlib.pyplot as plt + +# k l m + +################################################################################################# +### +### EXERCICE 2 : Définir une nouvelle police de caractères sous Python +### +################################################################################################# + + +# On active le "mode interactif" de pyplot. Ainsi, les plt.show() ne sont plus nécessaires. +plt.ion() + +# -------------------------------------------------------------------------------------- +# Fonction de "fin temporaire" pendant l'avancée du TP. Attend une frappe Entrée, puis quitte le script. + +def stop_ici(): + plt.pause(0.1) # nécessaire pour que matplotlib ait le temps d'afficher les figures + input() + exit() + +# -------------------------------------------------------------------------------------- +# Tous les passages indiqués "TODO()" sont à remplacer par vos soins + +def TODO(): + print("à vous!") + stop_ici() + + +###################################################################### +### Fonctions de tracé de courbes de Bézier : reprises du TP2 +###################################################################### + +# -------------------------------------------------------------------------------------- +# Calcul d'un point d'une courbe de Bézier +# +# - t = paramètre du point de la courbe à calculer [nombre réel entre 0 et 1] +# - P = points de contrôle [au même format qu'au TP2 : np.array de taille (N+1,2)] + +def bezierCasteljau(t,P): + while(P.shape[0]>1): + P = (1-t)*P[:-1] + t*P[1:] + return P[0] + +# -------------------------------------------------------------------------------------- +# Traçage d'une courbe dans sa totalité +# +# - P = points de contrôle [au même format qu'au TP2 : np.array de taille (N+1,2)] +# - trace_controle = True pour tracer également le polygone de controle +# - kwargs permet de passer tous les arguments habituels de la commande plt.plot (couleur, markers, etc.) + +def traceBezier(P, trace_controle=False, **kwargs): + if trace_controle: + plt.plot( P[:,0], P[:,1], linestyle='--', color='black') + Nt = 100 + Ft = np.array( [ bezierCasteljau(t,P) for t in np.linspace(0,1,Nt) ] ) + plt.plot( Ft[:,0], Ft[:,1], **kwargs) + +# -------------------------------------------------------------------------------------- +# Traçage d'un carré de coté 1 +# +# - offset = coordonnées du coin en bas à gauche du carré ([0,0] par défaut) +# - kwargs permet de passer tous les arguments habituels de la commande plt.plot (couleur, markers, etc.) + +def traceCarre(offset=[0,0], **kwargs): + Carre = np.array( [ [0,0], [1,0], [1,1], [0,1], [0,0] ] ) + Carre = Carre + np.array(offset) + plt.plot( Carre[:,0], Carre[:,1], **kwargs) + + +print("-"*80) +print(''' QUESTION 1 : Prise en main des fonctions. + +Dans une première figure, tracez : +- En VERT: un carré de coté 1 (et tel que son coin en bas à gauche soit aux coordonnées [0,0]) +- En BLEU: la courbe de Bézier associée aux points de contrôle +P0=[0,0], P1=[2,2], P2=[2,-2], P3=[0,2], P4=[0,0] +''') + + + +plt.figure() +plt.title("Question 1") + +traceCarre(offset=[0,0], color='green') +P = np.array( [ [0,0], [2,2], [2,-2], [0,2], [0,0] ] ) +traceBezier(P, color='blue') + +plt.axis('equal') + +# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + + +print("-"*80) +print(''' QUESTION 2. +Complétez le code de tracé de la fonction traceLettre ci-dessous [le TODO() à la fin de la fonction]. + +Pour ce faire, réfléchissez bien aux points suivants : +- Sous quel format la fonction traceBezier doit-elle recevoir les points de contrôle ? +- Comment 'transmettre' à la fonction traceBezier le fait qu'on veut ou non tracer le polygone de contrôle ? +- Comment 'transmettre' à la fonction traceBezier les options de traçage (couleur, etc.) passées à la fonction traceLettres ? + +Vérification : une fois le TODO() complété, le code de test suivant devra tracer la lettre "a" en bleu (et ses points de controle) +''') + + +################################################################### +# Fonction de tracé d'une lettre quelconque. +# C'est la fonction principale de cet exercice. +# On vous donne un squelette, que vous allez compléter progressivement. +################################################################### +# +# - char : caractère qu'on souhaite tracer ("a", "b", etc., ainsi que l'espace " ") +# - offset = coordonnées du point auquel on souhaite tracer la lettre ([0,0] si on ne précise pas) +# - trace_controle, kwargs : même signification que pour la fonction traceBezier + +def traceLettre(char, offset=[0,0], trace_controle=False, **kwargs): + + # Définition de la liste des points de contrôle pour cette lettre + # ( strokes[0]=points de contrôle pour le 1er trait, strokes[1]=points de contrôle pour le 2è trait, etc. ) + strokes = [] + + if char =="a": + strokes.append( [ [.8,.05], [.8,1] , [.75,1.1], [.1,.85] ] ) # premier trait du 'a' + strokes.append( [ [.78,.1], [-.25,-.3], [-.3,.7], [.8, .5] ] ) # deuxième trait du 'a' + + elif char=="m": + strokes.append( [ [1.1,0], [1.1,1.1], [0,1.1], [0,0] ] ) + strokes.append( [ [1.1,0], [1.1,1.1], [2.1,1.1], [2.1,0] ] ) + # B = np.array([[4.3,1.4], [4.3,1.2]]) # Permet de faire un bout de sein si on inverse les appends de [A B C D] en [B A D C] + # plt.plot(B[:,0], B[:,1], linestyle='--', color='black') + + elif char=="k": + strokes.append( [ [0,0], [0,1.1], [1.1,0], [0,0] ] ) + strokes.append( [ [1.1,1.1], [1.1,0], [0,1.1], [1.1,1.1] ] ) + + elif char=="l": + strokes.append( [ [0,0], [0,1.1], [1.1,1.1], [0,0] ] ) + strokes.append( [ [1.1,0], [1.1,1.1], [0,1.1], [1.1,0] ] ) + + elif char==" ": + pass # pour 'tracer' le caractère espace... on ne trace rien ! ^^ + + else: + raise("character '"+char+"' is not implemented yet") + + ### Le tracé proprement dit + for lst in strokes: + print(lst) # pour que vous compreniez ce que contient la variable lst (vous pouvez ensuite supprimer cette ligne) + P = np.array(lst) + traceBezier(P) # Tracer la courbe de Bézier définie par la liste de points lst + + + +### Code de test: +plt.figure() +traceLettre("m", trace_controle=True, color="blue", linewidth=3) +# traceCarre(color="green") +plt.axis("equal") + +stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + + +print("-"*80) +print(''' QUESTION 3 : trois nouvelles lettres. + +À ce stade, la fonction traceLettre sait uniquement tracer un "a". Rajoutez le code (=les 'strokes') permettant de tracer les lettres "g", "t" et "c". + +Méthode conseillée : construisez la lettre sous inkscape (exo 1), puis relevez la position des points de contrôle et rentrez-les sous Python. + +Attention : chaque lettre doit "tenir" dans un carré unité (le "g" pouvant dépasser un peu vers le bas, et le "t" un peu vers le haut) +''') + +### Teste le "g": +plt.figure() +traceLettre("g", trace_controle=True, color="blue", linewidth=3) +traceCarre(color="green") +plt.axis("equal") + +stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + +### Teste le "t": +plt.figure() +traceLettre("t", trace_controle=True, color="blue", linewidth=3) +traceCarre(color="green") +plt.axis("equal") + +stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + +### Teste le "c": +plt.figure() +traceLettre("c", trace_controle=True, color="blue", linewidth=3) +traceCarre(color="green") +plt.axis("equal") + +stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + + +print("-"*80) +print(''' QUESTION 4 : Gestion de l'offset. + +Modifiez votre fonction traceLettre afin de pouvoir passer en option l'OFFSET (=décalage) auquel on souhaite tracer la lettre. +Inspirez-vous de la fonction traceCarre, pour laquelle cette fonctionnalité est déjà implémentée. + +Vérification : une fois votre code écrit, le code ci-dessous représentera les 4 lettres a,c,g,t dans la disposition suivante: + ac + gt +''') + +### Vérification: +plt.figure() +traceLettre("a", offset = [0,0], color="blue", linewidth=3) +traceCarre(color="green", offset=[0,0] ) +traceLettre("c", offset = [2,0], color="blue", linewidth=3) +traceCarre(color="green", offset=[2,0] ) +traceLettre("g", offset = [0,-2], color="blue", linewidth=3) +traceCarre(color="green", offset=[0,-2] ) +traceLettre("t", offset = [2,-2], color="blue", linewidth=3) +traceCarre(color="green", offset=[2,-2] ) +plt.axis("equal") + +stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + + +print("-"*80) +print(''' QUESTION 5. +Répartissez-vous le travail dans le groupe TP afin de coder TOUTES les lettres de l'alphabet ! +(Il faudra donc vous "passer" le code de chaque lettre les uns aux autres, au fur et à mesure que vous les écrivez.) + +Attention : chaque lettre doit toujours tenir dans un carré unité (en dépassant un peu vers le haut ou le bas pour certaines lettres comme le "l", le "j", etc.). +''') + +### Vérification (par exemple, pour vérifier le code du "b" une fois qu'il est défini): +plt.figure() +traceLettre("b", trace_controle=True, color="blue", linewidth=3) +traceCarre(color="green") +plt.axis("equal") + +stop_ici() # -------------- Supprimez cette ligne pour passer à la suite -------------- + + +print("-"*80) +print(''' QUESTION 6 : tracé d'une phrase quelconque. + +Écrivez une fonction traceStr, avec le prototype défini ci-dessous, qui trace une chaîne de caractères quelconque (sans ponctuation) dans votre police. + +Consigne pour le OFFSET (décalage) : chaque caractère de la chaîne doit être tracé avec un décalage de +1 vers la droite par rapport au caractère précédent. +''') + +# -------------------------------------------------------------------------------------- +# Fonction de tracé d'une chaîne de caractères quelconque (sans ponctuation) +# +# - chaine = chaîne de caractères qu'on souhaite tracer +# - trace_controle et kwargs : même signification que pour la fonction traceBezier + +def traceStr(chaine, trace_controle=False, **kwargs): + TODO() + + +### Vérification: + +phrase = "gattaca taca tagata" # version basique avec uniquement les lettre a,c,g,t +# phrase = "portez ce vieux whisky au juge blond qui fume" # pangramme (phrase avec les 26 lettres de l'alphabet) + +plt.figure() +traceStr(phrase, color="blue", linewidth=3) +plt.axis("equal") + + + +stop_ici() # FINI !