Entièrement fonctionnel, pu de TODO

This commit is contained in:
FyloZ 2024-03-12 21:19:55 -04:00
parent 32236231c4
commit f41b71588f
Signed by: william
GPG Key ID: 835378AE9AF4AE97
10 changed files with 125 additions and 94 deletions

View File

@ -17,10 +17,10 @@ void GraphColoring::color(ParticleSystem &particleSystem) {
p.color = -1;
}
// TODO Calculer les couleurs de toutes les particules du syst<73>me.
// Calculer les couleurs de toutes les particules du syst<73>me.
// Boucler sur chaque particule et appeler la fonction findColor.
// TODO Construire les partitions qui correspond <20> chaque couleur.
// Construire les partitions qui correspond <20> chaque couleur.
// Les partitions sont repr<70>sent<6E>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<Particle> &particl
int count[n];
memset(count, 0, sizeof(int) * n);
// TODO Trouver la premi<6D>re couleur de la palette C qui n'est pas attribu<62>e <20> une particule voisine.
// Trouver la premi<6D>re couleur de la palette C qui n'est pas attribu<62>e <20> une particule voisine.
// Si une couleur est introuvable, ajouter une nouvelle couleur <20> la palette et retournez la couleur.
// Utiliser la fonction findNeighbors pour assembler une liste de particules qui sont directement connect<63>es <20> la particule p par un ressort (les voisines).

View File

@ -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 <EFBFBD> toutes les particules du syst<73>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<EFBFBD>e par un voisine pour la particule @a p.
//
int findColor(const Particle& p, const std::vector<Particle>& particles, const std::vector<Spring>& 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<EFBFBD>es <20> la particule @a p par un ressort..
//
NeighborList findNeighbors(const Particle& p, const std::vector<Particle>& particles, const std::vector<Spring>& springs) const;

View File

@ -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.

View File

@ -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
*
*/

View File

@ -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
*
*/

View File

@ -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<float, Dynamic> &_pos,
Vector<float, Dynamic> &_vel,
Vector<float, Dynamic> &_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<float, Dynamic> &_pos,
*/
void ParticleSystem::unpack(const Vector<float, Dynamic> &_pos,
const Vector<float, Dynamic> &_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<float, Dynamic, Dynamic> &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<float, Dynamic, Dynamic> &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.
//

View File

@ -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
*
*/

View File

@ -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<float, Dynamic, Dynamic> &A,
const Vector<float, Dynamic> &b,
Vector<float, Dynamic> &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<float, Dynamic, Dynamic> &A, const Vector<float, Dynamic> &b,
Vector<float, Dynamic> &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<float, Dynamic, Dynamic>(n, n);
@ -149,8 +143,6 @@ namespace gti320 {
}
}
// TODO
//
// Résoudre Ly = b
auto y = Vector<float, Dynamic>(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

View File

@ -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<float, 2> Vector2f;

View File

@ -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
*
*/