From 3a873639ce600745a1de1aa96aa486c63a311929 Mon Sep 17 00:00:00 2001 From: william Date: Fri, 15 Mar 2024 16:30:01 -0400 Subject: [PATCH] Meilleur pont --- labo_physique/ParticleSimApplication.cpp | 62 +++++++++++++++++++----- labo_physique/ParticleSystem.cpp | 18 +++---- labo_physique/Vector2d.h | 14 ++++++ 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/labo_physique/ParticleSimApplication.cpp b/labo_physique/ParticleSimApplication.cpp index 3783c96..9b6ea4f 100644 --- a/labo_physique/ParticleSimApplication.cpp +++ b/labo_physique/ParticleSimApplication.cpp @@ -236,7 +236,9 @@ namespace { 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; + const int bridge_index_start = pillar_n * 2; + + Vector bridgePositions(bridge_n * 2); // Tablier for (int i = 0; i < bridge_n; i++) { @@ -248,8 +250,9 @@ namespace { Vector2f position(current_x, current_y); Particle p(position, Vector2f(0, 0), Vector2f(0, 0), 1.0f); particleSystem.addParticle(p); + bridgePositions(i * 2 + j) = position; - const int index = pillar_n * 2 + i * 2 + j; + const int index = bridge_index_start + i * 2 + j; if (j == 0) { // Ressorts internes au tablier if (i > 0) { @@ -268,17 +271,6 @@ namespace { 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); @@ -306,6 +298,50 @@ namespace { } } + + // Toit du tablier en demi-cercle + float r = bridge_n - 1; + const float a = r / 2; + for (int i = 0; i < bridge_n; i++) { + // Calcul de y en utilisant l'équation du haut d'un cercle + float y = (float) std::sqrt(std::pow(r, 2) - std::pow(i - a, 2)) + a; + Vector position = Vector2f(x_start + bridge_dx + i * bridge_dx, bridge_dx + y * bridge_dx); + + Particle p(position, Vector2f(0, 0), Vector2f(0, 0), 1.0f); + particleSystem.addParticle(p); + + // Ressorts entre les particules du toit + int index = pillar_n * 2 + bridge_n * 2 + i; + if (i > 0) { + Spring s(index - 1, index, 0, bridge_dx); + particleSystem.addSpring(s); + } + + // Ressorts jusqu'au tablier + int bridge_index = bridge_index_start + i * 2; + float d = (position - bridgePositions(i * 2)).norm(); + Spring s1(bridge_index, index, 0, d); + particleSystem.addSpring(s1); + + // Ressorts liés aux piliers + if (i == 1 || i == bridge_n - 2) { + int p_index_m = i == 1 ? 1 : 2; + int p_index = pillar_n * p_index_m - 1; + Vector2f pp(i == 1 ? x_start : x_start + bridge_dx * (bridge_n + 1), y_start + pillar_n * pillar_dy); + + Spring p1(p_index, index, 0, (position - pp).norm() / 1.5f); + particleSystem.addSpring(p1); + } + + // Ressorts aux deux extrémités + if (i == 0 || i == bridge_n - 1) { + int p_index_m = i == 0 ? 0 : 1; + int p_index = p_index_m * pillar_n + (pillar_n / 2); + + Spring p2(p_index, index, 0, (float) std::sqrt(std::pow(bridge_dx, 2) + std::pow(bridge_dy, 2))); + particleSystem.addSpring(p2); + } + } } diff --git a/labo_physique/ParticleSystem.cpp b/labo_physique/ParticleSystem.cpp index a325c98..723b59c 100644 --- a/labo_physique/ParticleSystem.cpp +++ b/labo_physique/ParticleSystem.cpp @@ -137,17 +137,15 @@ void ParticleSystem::buildDfDx(Matrix &dfdx) { float l = (p1.x - p0.x).norm(); float a = spring.k * (1 - spring.l0 / l); + Vector dij = (1 / l) * (p1.x - p0.x); + Matrix correction = spring.k * (spring.l0 / l) * (dij.as_matrix() * dij.transpose()); - Matrix diag; - diag.setZero(); - diag(0, 0) = -a; - diag(1, 1) = -a; + Matrix ndiag = a * identity + correction; + Matrix diag = -1.0f * ndiag; - Matrix ndiag = -1.0f * diag; - - dfdx.block(spring.index0, spring.index1, 2, 2) += diag; - dfdx.block(spring.index0 + 2, spring.index1 + 2, 2, 2) += diag; - dfdx.block(spring.index0 + 2, spring.index1, 2, 2) += ndiag; - dfdx.block(spring.index0, spring.index1 + 2, 2, 2) += ndiag; + dfdx.block(spring.index0 * 2, spring.index0 * 2, 2, 2) += diag; + dfdx.block(spring.index1 * 2, spring.index1 * 2, 2, 2) += diag; + dfdx.block(spring.index0 * 2, spring.index1 * 2, 2, 2) += ndiag; + dfdx.block(spring.index1 * 2, spring.index0 * 2, 2, 2) += ndiag; } } diff --git a/labo_physique/Vector2d.h b/labo_physique/Vector2d.h index b51667f..cb0c4da 100644 --- a/labo_physique/Vector2d.h +++ b/labo_physique/Vector2d.h @@ -103,6 +103,20 @@ namespace gti320 { return sqrt(dot(*this)); } + + Matrix as_matrix() const { + Matrix mat; + mat(0, 0) = (*this)(0); + mat(1, 0) = (*this)(1); + return mat; + } + + Matrix transpose() const { + Matrix mat; + mat(0, 0) = (*this)(0); + mat(0, 1) = (*this)(1); + return mat; + } }; typedef Vector Vector2f;