From f41b71588fc9719d3f40d1075e3bfd5de65c84a8 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Tue, 12 Mar 2024 21:19:55 -0400 Subject: [PATCH] =?UTF-8?q?Enti=C3=A8rement=20fonctionnel,=20pu=20de=20TOD?= =?UTF-8?q?O?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labo_physique/GraphColoring.cpp | 6 +- labo_physique/GraphColoring.h | 12 +- labo_physique/ParticleSimApplication.cpp | 136 ++++++++++++++++------- labo_physique/ParticleSimApplication.h | 6 +- labo_physique/ParticleSimGLCanvas.h | 6 +- labo_physique/ParticleSystem.cpp | 12 -- labo_physique/ParticleSystem.h | 6 +- labo_physique/Solvers.h | 16 +-- labo_physique/Vector2d.h | 13 +-- labo_physique/main.cpp | 6 +- 10 files changed, 125 insertions(+), 94 deletions(-) diff --git a/labo_physique/GraphColoring.cpp b/labo_physique/GraphColoring.cpp index f1d8744..6045e48 100644 --- a/labo_physique/GraphColoring.cpp +++ b/labo_physique/GraphColoring.cpp @@ -17,10 +17,10 @@ void GraphColoring::color(ParticleSystem &particleSystem) { p.color = -1; } - // TODO Calculer les couleurs de toutes les particules du syst�me. + // Calculer les couleurs de toutes les particules du syst�me. // Boucler sur chaque particule et appeler la fonction findColor. - // TODO Construire les partitions qui correspond � chaque couleur. + // Construire les partitions qui correspond � chaque couleur. // Les partitions sont repr�sent�es par un tableau d'indices de particules, un pour chaque couleur. // Stocker les partitions dans m_partitions. @@ -45,7 +45,7 @@ GraphColoring::findColor(const Particle &p, const std::vector &particl int count[n]; memset(count, 0, sizeof(int) * n); - // TODO Trouver la premi�re couleur de la palette C qui n'est pas attribu�e � une particule voisine. + // Trouver la premi�re couleur de la palette C qui n'est pas attribu�e � une particule voisine. // Si une couleur est introuvable, ajouter une nouvelle couleur � la palette et retournez la couleur. // Utiliser la fonction findNeighbors pour assembler une liste de particules qui sont directement connect�es � la particule p par un ressort (les voisines). diff --git a/labo_physique/GraphColoring.h b/labo_physique/GraphColoring.h index 96793eb..95cead1 100644 --- a/labo_physique/GraphColoring.h +++ b/labo_physique/GraphColoring.h @@ -5,9 +5,9 @@ * * @brief Algorithme glouton pour la coloration de graphe. * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ @@ -26,7 +26,7 @@ namespace gti320 class GraphColoring { public: - // Attribuer des couleurs à toutes les particules du système. + // Attribuer des couleurs � toutes les particules du syst�me. // void color(ParticleSystem& particleSystem); @@ -36,11 +36,11 @@ namespace gti320 private: - // Trouver une couleur qui n'est pas partagée par un voisine pour la particule @a p. + // Trouver une couleur qui n'est pas partag�e par un voisine pour la particule @a p. // int findColor(const Particle& p, const std::vector& particles, const std::vector& springs, ColorList& C) const; - // Retourner toutes les particules qui sont directement raccordées à la particule @a p par un ressort.. + // Retourner toutes les particules qui sont directement raccord�es � la particule @a p par un ressort.. // NeighborList findNeighbors(const Particle& p, const std::vector& particles, const std::vector& springs) const; diff --git a/labo_physique/ParticleSimApplication.cpp b/labo_physique/ParticleSimApplication.cpp index 3c62261..3783c96 100644 --- a/labo_physique/ParticleSimApplication.cpp +++ b/labo_physique/ParticleSimApplication.cpp @@ -196,56 +196,116 @@ namespace { /** - * TODO Créez votre propre exemple + * Créez votre propre exemple */ static inline void createVotreExemple(ParticleSystem &particleSystem, float k) { particleSystem.clear(); - // TODO Amusez-vous. Rendu ici, vous le méritez. - const int N = 20; + // Amusez-vous. Rendu ici, vous le méritez. + // Pont const int x_start = 200; - const int y_start = 400; - const int dx = 32; - const int dy = 32; + const int y_start = 200; - Particle p1(Vector2f(x_start + dx * 2, y_start + dy * 4), Vector2f(0, 0), Vector2f(0, 0), 1.0); - particleSystem.addParticle(p1); + const int pillar_n = 6; + const int pillar_dy = 64; - Particle p2(Vector2f(x_start, y_start), Vector2f(0, 0), Vector2f(0, 0), 1.0); - particleSystem.addParticle(p2); + const int bridge_n = 10; + const int bridge_dx = 32; + const int bridge_dy = 32; - Particle p3(Vector2f(x_start + dx * 4, y_start), Vector2f(0, 0), Vector2f(0, 0), 1.0); - particleSystem.addParticle(p3); + // Piliers de gauche et droite + for (int pillar = 0; pillar < 2; pillar++) { + const auto pillar_x = (float) (x_start + pillar * bridge_dx * (bridge_n + 1)); + const int spring_offset = pillar * pillar_n; - Particle p4(Vector2f(x_start + dx * 2, y_start + dy * 2), Vector2f(0, 0), Vector2f(0, 0), 1.0); - particleSystem.addParticle(p4); + for (int i = 0; i < pillar_n; i++) { + Vector2f position(pillar_x, (float) (y_start + i * pillar_dy)); + Particle p(position, Vector2f(0, 0), Vector2f(0, 0), 1.0f); + p.fixed = i == 0 || i == pillar_n - 1; - Particle p5(Vector2f(x_start + dx, y_start + dy), Vector2f(0, 0), Vector2f(0, 0), 1.0); - particleSystem.addParticle(p5); + particleSystem.addParticle(p); - Particle p6(Vector2f(x_start + dx * 3, y_start + dy), Vector2f(0, 0), Vector2f(0, 0), 1.0); - particleSystem.addParticle(p6); + if (i > 0) { + // Le ressort a déjà de la tension pour pas que tout s'écroule immédiatement + Spring s(spring_offset + i - 1, spring_offset + i, 0, pillar_dy / 1.2f); + particleSystem.addSpring(s); + } + } + } - Spring s1(0, 1, 0, dx); - particleSystem.addSpring(s1); - Spring s2(0, 2, 0, dx); - particleSystem.addSpring(s2); - Spring s3(1, 2, 0, dx); - particleSystem.addSpring(s3); + const int pillar_connection_index = pillar_n / 2; + const int bridge_y = y_start + pillar_connection_index * pillar_dy; + const auto l0_diag = (float) std::sqrt(std::pow(bridge_dx, 2) + std::pow(bridge_dy, 2)); + const int bridge_half = bridge_n / 2; - Spring s4(3, 4, 0, dx); - particleSystem.addSpring(s4); - Spring s5(3, 5, 0, dx); - particleSystem.addSpring(s5); - Spring s6(4, 5, 0, dx); - particleSystem.addSpring(s6); + // Tablier + for (int i = 0; i < bridge_n; i++) { + const auto current_x = (float) (x_start + (i + 1) * bridge_dx); - Spring s7(1, 4, 0, dx); - particleSystem.addSpring(s7); - Spring s8(0, 3, 0, dx); - particleSystem.addSpring(s8); - Spring s9(2, 5, 0, dx); - particleSystem.addSpring(s9); + for (int j = 0; j < 2; j++) { + const auto current_y = (float) (bridge_y - j * bridge_dy); + + Vector2f position(current_x, current_y); + Particle p(position, Vector2f(0, 0), Vector2f(0, 0), 1.0f); + particleSystem.addParticle(p); + + const int index = pillar_n * 2 + i * 2 + j; + if (j == 0) { + // Ressorts internes au tablier + if (i > 0) { + Spring s1(index - 1, index, 0, l0_diag); + Spring s2(index - 2, index, 0, bridge_dx); + particleSystem.addSpring(s1); + particleSystem.addSpring(s2); + } + + // Ressorts entre les extrémités du tablier et les piliers + if (i == 0) { + Spring s(pillar_connection_index, index, 0, bridge_dx); + particleSystem.addSpring(s); + } + if (i == bridge_n - 1) { + Spring s(pillar_n + pillar_connection_index, index, 0, bridge_dx); + particleSystem.addSpring(s); + } + + // Ressorts entre le milieu du tablier et le haut des piliers + if (i + 1 == bridge_half || i == bridge_half) { + const int pillar_index = i == bridge_half ? pillar_n * 2 : pillar_n; + const auto l0 = + (float) std::sqrt(std::pow(current_x - x_start, 2) + std::pow(current_y - y_start, 2)) / + 1.2f; + + Spring s(pillar_index - 1, index, 0, l0); + particleSystem.addSpring(s); + } + } else { + Spring s1(index - 1, index, 0, bridge_dy); + particleSystem.addSpring(s1); + + // Ressorts internes au tablier + if (i > 0) { + Spring s2(index - 2, index, 0, bridge_dx); + particleSystem.addSpring(s2); + } + + // Ressorts entre les extrémités du tablier et les piliers + if (i == 0) { + Spring s3(pillar_connection_index, index, 0, bridge_dx); + particleSystem.addSpring(s3); + Spring s4(pillar_connection_index - 1, index, 0, l0_diag); + particleSystem.addSpring(s4); + } + if (i == bridge_n - 1) { + Spring s3(pillar_n + pillar_connection_index, index, 0, bridge_dx); + particleSystem.addSpring(s3); + Spring s4(pillar_n + pillar_connection_index - 1, index, 0, l0_diag); + particleSystem.addSpring(s4); + } + } + + } + } } @@ -505,7 +565,7 @@ void ParticleSimApplication::step(float dt) { m_particleSystem.pack(m_x, m_v, m_f); ////////////////////////////////////////////////////////////////////////////////// - // TODO Construire le système d'équation linéaire sous la forme `A*v_plus = b`. + // Construire le système d'équation linéaire sous la forme `A*v_plus = b`. // la construction de A et b est donnée dans les diapos du Cours 8. // // Note : lors du calcul de b, NE PAS calculer `Mg + Kx` ce @@ -557,7 +617,7 @@ void ParticleSimApplication::step(float dt) { break; } - // TODO Mise à jour du vecteur d'état de position via l'intégration d'Euler + // Mise à jour du vecteur d'état de position via l'intégration d'Euler // implicite. Les nouvelles position sont calculées à partir des position // actuelles m_x et des nouvelles vitesses v_plus. Les nouvelles positions // sont stockées directement dans le vecteur m_x. diff --git a/labo_physique/ParticleSimApplication.h b/labo_physique/ParticleSimApplication.h index 541b2dc..89a1d53 100644 --- a/labo_physique/ParticleSimApplication.h +++ b/labo_physique/ParticleSimApplication.h @@ -6,9 +6,9 @@ * @brief Partir applicative du laboratoire 3 : contrôle de la simulaiton via * l'interface graphique. * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ diff --git a/labo_physique/ParticleSimGLCanvas.h b/labo_physique/ParticleSimGLCanvas.h index 4cea2a8..88f840e 100644 --- a/labo_physique/ParticleSimGLCanvas.h +++ b/labo_physique/ParticleSimGLCanvas.h @@ -5,9 +5,9 @@ * * @brief Classe Canvas pour l'affichage via OpenGL. * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ diff --git a/labo_physique/ParticleSystem.cpp b/labo_physique/ParticleSystem.cpp index 5e4a9df..178f08b 100644 --- a/labo_physique/ParticleSystem.cpp +++ b/labo_physique/ParticleSystem.cpp @@ -9,16 +9,12 @@ using namespace gti320; * Les forces prisent en compte sont : la gravité et la force des ressorts. */ void ParticleSystem::computeForces() { - // TODO - // // Calcul de la force gravitationnelle sur chacune des particules for (Particle &p: m_particles) { p.f(0) = 0; // x p.f(1) = -p.m * 9.81f; // y } - // TODO - // // Pour chaque ressort, ajouter la force exercée à chacune des extrémités sur // les particules appropriées. Pour un ressort s, les deux particules // auxquelles le ressort est attaché sont m_particles[s.index0] et @@ -43,8 +39,6 @@ void ParticleSystem::computeForces() { void ParticleSystem::pack(Vector &_pos, Vector &_vel, Vector &_force) { - // TODO - // // Copier les données des particules dans les vecteurs. Attention, si on a // changé de modèle, il est possible que les vecteurs n'aient pas la bonne // taille. Rappel : la taille de ces vecteurs doit être 2 fois le nombre de @@ -76,8 +70,6 @@ void ParticleSystem::pack(Vector &_pos, */ void ParticleSystem::unpack(const Vector &_pos, const Vector &_vel) { - // TODO - // // Mise à jour des propriétés de chacune des particules à partir des valeurs // contenues dans le vecteur d'état. @@ -103,8 +95,6 @@ void ParticleSystem::buildMassMatrix(Matrix &M) { M.resize(dim, dim); M.setZero(); - // TODO - // // Inscrire la masse de chacune des particules dans la matrice de masses M // for (int i = 0; i < numParticles; ++i) { @@ -136,8 +126,6 @@ void ParticleSystem::buildDfDx(Matrix &dfdx) { // Pour chaque ressort... for (const Spring &spring: m_springs) { - // TODO - // // Calculer le coefficients alpha et le produit dyadique tel que décrit au cours. // Utiliser les indices spring.index0 et spring.index1 pour calculer les coordonnées des endroits affectés. // diff --git a/labo_physique/ParticleSystem.h b/labo_physique/ParticleSystem.h index 2a24ca6..95813f3 100644 --- a/labo_physique/ParticleSystem.h +++ b/labo_physique/ParticleSystem.h @@ -5,9 +5,9 @@ * * @brief Système de particules de type masse-ressort * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ diff --git a/labo_physique/Solvers.h b/labo_physique/Solvers.h index d593d23..957b80d 100644 --- a/labo_physique/Solvers.h +++ b/labo_physique/Solvers.h @@ -6,9 +6,9 @@ * @brief Implémentation de plusieurs algorihtmes de solveurs pour un système * d'équations linéaires * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ @@ -30,8 +30,6 @@ namespace gti320 { static void gaussSeidel(const Matrix &A, const Vector &b, Vector &x, int k_max) { - // TODO - // // Implémenter la méthode de Gauss-Seidel int n = b.size(); @@ -75,8 +73,6 @@ namespace gti320 { */ static void gaussSeidelColor(const Matrix &A, const Vector &b, Vector &x, const Partitions &P, const int maxIter) { - // TODO - // // Implémenter la méthode de Gauss-Seidel avec coloration de graphe. // Les partitions avec l'index de chaque particule sont stockées dans la table des tables, P. int n = b.size(); @@ -128,8 +124,6 @@ namespace gti320 { x.resize(n); x.setZero(); - // TODO - // // Calculer la matrice L de la factorisation de Cholesky auto L = Matrix(n, n); @@ -149,8 +143,6 @@ namespace gti320 { } } - // TODO - // // Résoudre Ly = b auto y = Vector(n); for (int i = 0; i < n; i++) { @@ -163,8 +155,6 @@ namespace gti320 { y(i) /= L(i, i); } - // TODO - // // Résoudre L^t x = y // // Remarque : ne pas calculer la transposée de L, c'est inutilement diff --git a/labo_physique/Vector2d.h b/labo_physique/Vector2d.h index 5f16e1e..b51667f 100644 --- a/labo_physique/Vector2d.h +++ b/labo_physique/Vector2d.h @@ -5,9 +5,9 @@ * * @brief Vecteur 2D * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ @@ -103,13 +103,6 @@ namespace gti320 { return sqrt(dot(*this)); } - - Matrix<_Scalar, 2, 1> as_matrix() const { - Matrix<_Scalar, 2, 1> mat; - mat(0, 0) = (*this)(0); - mat(1, 0) = (*this)(1); - return mat; - } }; typedef Vector Vector2f; diff --git a/labo_physique/main.cpp b/labo_physique/main.cpp index 003e10a..857988c 100644 --- a/labo_physique/main.cpp +++ b/labo_physique/main.cpp @@ -3,9 +3,9 @@ * * @brief GTI320 Simulation d'un système masse-ressort * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */