Meilleur pont

This commit is contained in:
william 2024-03-15 16:30:01 -04:00
parent caf83ef7ca
commit 3a873639ce
3 changed files with 71 additions and 23 deletions

View File

@ -236,7 +236,9 @@ namespace {
const int pillar_connection_index = pillar_n / 2; const int pillar_connection_index = pillar_n / 2;
const int bridge_y = y_start + pillar_connection_index * pillar_dy; 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 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<Vector2f> bridgePositions(bridge_n * 2);
// Tablier // Tablier
for (int i = 0; i < bridge_n; i++) { for (int i = 0; i < bridge_n; i++) {
@ -248,8 +250,9 @@ namespace {
Vector2f position(current_x, current_y); Vector2f position(current_x, current_y);
Particle p(position, Vector2f(0, 0), Vector2f(0, 0), 1.0f); Particle p(position, Vector2f(0, 0), Vector2f(0, 0), 1.0f);
particleSystem.addParticle(p); 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) { if (j == 0) {
// Ressorts internes au tablier // Ressorts internes au tablier
if (i > 0) { if (i > 0) {
@ -268,17 +271,6 @@ namespace {
Spring s(pillar_n + pillar_connection_index, index, 0, bridge_dx); Spring s(pillar_n + pillar_connection_index, index, 0, bridge_dx);
particleSystem.addSpring(s); 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 { } else {
Spring s1(index - 1, index, 0, bridge_dy); Spring s1(index - 1, index, 0, bridge_dy);
particleSystem.addSpring(s1); 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<float, 2> 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);
}
}
} }

View File

@ -137,17 +137,15 @@ void ParticleSystem::buildDfDx(Matrix<float, Dynamic, Dynamic> &dfdx) {
float l = (p1.x - p0.x).norm(); float l = (p1.x - p0.x).norm();
float a = spring.k * (1 - spring.l0 / l); float a = spring.k * (1 - spring.l0 / l);
Vector<float, 2> dij = (1 / l) * (p1.x - p0.x);
Matrix<float, 2, 2> correction = spring.k * (spring.l0 / l) * (dij.as_matrix() * dij.transpose());
Matrix<float, 2, 2> diag; Matrix<float, 2, 2> ndiag = a * identity + correction;
diag.setZero(); Matrix<float, 2, 2> diag = -1.0f * ndiag;
diag(0, 0) = -a;
diag(1, 1) = -a;
Matrix<float, 2, 2> ndiag = -1.0f * diag; 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, spring.index1, 2, 2) += diag; dfdx.block(spring.index0 * 2, spring.index1 * 2, 2, 2) += ndiag;
dfdx.block(spring.index0 + 2, spring.index1 + 2, 2, 2) += diag; dfdx.block(spring.index1 * 2, spring.index0 * 2, 2, 2) += ndiag;
dfdx.block(spring.index0 + 2, spring.index1, 2, 2) += ndiag;
dfdx.block(spring.index0, spring.index1 + 2, 2, 2) += ndiag;
} }
} }

View File

@ -103,6 +103,20 @@ namespace gti320
{ {
return sqrt(dot(*this)); return sqrt(dot(*this));
} }
Matrix<float, 2, 1> as_matrix() const {
Matrix<float, 2, 1> mat;
mat(0, 0) = (*this)(0);
mat(1, 0) = (*this)(1);
return mat;
}
Matrix<float, 1, 2> transpose() const {
Matrix<float, 1, 2> mat;
mat(0, 0) = (*this)(0);
mat(0, 1) = (*this)(1);
return mat;
}
}; };
typedef Vector<float, 2> Vector2f; typedef Vector<float, 2> Vector2f;