Add 2 files
Browse files- index.html +99 -5
- prompts.txt +3 -1
index.html
CHANGED
|
@@ -38,6 +38,27 @@
|
|
| 38 |
.floating {
|
| 39 |
animation: float 3s ease-in-out infinite;
|
| 40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
</style>
|
| 42 |
</head>
|
| 43 |
<body class="bg-gray-900 text-gray-100 min-h-screen">
|
|
@@ -164,6 +185,7 @@
|
|
| 164 |
<th class="py-3 px-4">Masse (×10²⁴ kg)</th>
|
| 165 |
<th class="py-3 px-4">Rayon (km)</th>
|
| 166 |
<th class="py-3 px-4">Temps de chute de 100m</th>
|
|
|
|
| 167 |
</tr>
|
| 168 |
</thead>
|
| 169 |
<tbody id="planetData">
|
|
@@ -236,6 +258,7 @@
|
|
| 236 |
let animationId = null;
|
| 237 |
let startTime = null;
|
| 238 |
let objects = [];
|
|
|
|
| 239 |
|
| 240 |
// Éléments DOM
|
| 241 |
const simulationContainer = document.getElementById('simulationContainer');
|
|
@@ -267,7 +290,9 @@
|
|
| 267 |
});
|
| 268 |
|
| 269 |
heightSlider.addEventListener('input', function() {
|
| 270 |
-
|
|
|
|
|
|
|
| 271 |
});
|
| 272 |
|
| 273 |
startBtn.addEventListener('click', startSimulation);
|
|
@@ -284,12 +309,14 @@
|
|
| 284 |
btn.classList.add('ring-2', 'ring-blue-400');
|
| 285 |
renderPlanetSelection();
|
| 286 |
updatePlanetDataTable();
|
|
|
|
| 287 |
}
|
| 288 |
} else {
|
| 289 |
selectedPlanets.splice(index, 1);
|
| 290 |
btn.classList.remove('ring-2', 'ring-blue-400');
|
| 291 |
renderPlanetSelection();
|
| 292 |
updatePlanetDataTable();
|
|
|
|
| 293 |
}
|
| 294 |
}
|
| 295 |
|
|
@@ -342,6 +369,19 @@
|
|
| 342 |
gravityWell.style.backgroundColor = planet.color;
|
| 343 |
planetsContainer.appendChild(gravityWell);
|
| 344 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
// Ajout des statistiques de la planète
|
| 346 |
const statsEl = document.createElement('div');
|
| 347 |
statsEl.className = 'bg-gray-700 p-4 rounded-lg';
|
|
@@ -373,12 +413,36 @@
|
|
| 373 |
});
|
| 374 |
}
|
| 375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 376 |
function updatePlanetDataTable() {
|
| 377 |
planetData.innerHTML = '';
|
| 378 |
|
| 379 |
Object.keys(PLANETS).forEach(planetId => {
|
| 380 |
const planet = PLANETS[planetId];
|
| 381 |
const isSelected = selectedPlanets.includes(planetId);
|
|
|
|
|
|
|
| 382 |
|
| 383 |
const row = document.createElement('tr');
|
| 384 |
row.className = isSelected ? 'bg-gray-700' : 'border-b border-gray-700';
|
|
@@ -390,7 +454,8 @@
|
|
| 390 |
<td class="py-3 px-4">${planet.g}</td>
|
| 391 |
<td class="py-3 px-4">${planet.mass}</td>
|
| 392 |
<td class="py-3 px-4">${planet.radius}</td>
|
| 393 |
-
<td class="py-3 px-4">${
|
|
|
|
| 394 |
`;
|
| 395 |
planetData.appendChild(row);
|
| 396 |
});
|
|
@@ -404,7 +469,7 @@
|
|
| 404 |
startTime = Date.now();
|
| 405 |
objects = [];
|
| 406 |
|
| 407 |
-
const height =
|
| 408 |
const object = OBJECTS[objectType.value];
|
| 409 |
|
| 410 |
// Créer un objet pour chaque planète sélectionnée
|
|
@@ -429,9 +494,22 @@
|
|
| 429 |
falling: false,
|
| 430 |
startTime: null,
|
| 431 |
fallDuration: null,
|
| 432 |
-
finalSpeed: null
|
|
|
|
| 433 |
};
|
| 434 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
objects.push(obj);
|
| 436 |
|
| 437 |
// Mettre à jour le poids affiché
|
|
@@ -473,11 +551,19 @@
|
|
| 473 |
const fallTime = (now - obj.startTime) / 1000;
|
| 474 |
|
| 475 |
// Formule de chute libre: y = y0 + 0.5 * g * t^2
|
| 476 |
-
|
|
|
|
|
|
|
| 477 |
|
| 478 |
// Vitesse: v = g * t
|
| 479 |
obj.vy = obj.g * fallTime;
|
| 480 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
// Vérifier si l'objet a atteint le sol
|
| 482 |
if (obj.y >= obj.planetY - 30) {
|
| 483 |
obj.y = obj.planetY - 30;
|
|
@@ -549,6 +635,14 @@
|
|
| 549 |
|
| 550 |
simulationRunning = false;
|
| 551 |
startBtn.disabled = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 552 |
objects = [];
|
| 553 |
|
| 554 |
// Effacer le canvas
|
|
|
|
| 38 |
.floating {
|
| 39 |
animation: float 3s ease-in-out infinite;
|
| 40 |
}
|
| 41 |
+
.planet-stats {
|
| 42 |
+
position: absolute;
|
| 43 |
+
background: rgba(30, 41, 59, 0.8);
|
| 44 |
+
border-radius: 8px;
|
| 45 |
+
padding: 8px;
|
| 46 |
+
font-size: 12px;
|
| 47 |
+
pointer-events: none;
|
| 48 |
+
transform: translateX(-50%);
|
| 49 |
+
}
|
| 50 |
+
.fall-data {
|
| 51 |
+
position: absolute;
|
| 52 |
+
bottom: 10px;
|
| 53 |
+
left: 50%;
|
| 54 |
+
transform: translateX(-50%);
|
| 55 |
+
background: rgba(30, 41, 59, 0.8);
|
| 56 |
+
border-radius: 8px;
|
| 57 |
+
padding: 8px;
|
| 58 |
+
font-size: 12px;
|
| 59 |
+
text-align: center;
|
| 60 |
+
min-width: 120px;
|
| 61 |
+
}
|
| 62 |
</style>
|
| 63 |
</head>
|
| 64 |
<body class="bg-gray-900 text-gray-100 min-h-screen">
|
|
|
|
| 185 |
<th class="py-3 px-4">Masse (×10²⁴ kg)</th>
|
| 186 |
<th class="py-3 px-4">Rayon (km)</th>
|
| 187 |
<th class="py-3 px-4">Temps de chute de 100m</th>
|
| 188 |
+
<th class="py-3 px-4">Vitesse finale (100m)</th>
|
| 189 |
</tr>
|
| 190 |
</thead>
|
| 191 |
<tbody id="planetData">
|
|
|
|
| 258 |
let animationId = null;
|
| 259 |
let startTime = null;
|
| 260 |
let objects = [];
|
| 261 |
+
let currentHeight = 150;
|
| 262 |
|
| 263 |
// Éléments DOM
|
| 264 |
const simulationContainer = document.getElementById('simulationContainer');
|
|
|
|
| 290 |
});
|
| 291 |
|
| 292 |
heightSlider.addEventListener('input', function() {
|
| 293 |
+
currentHeight = parseInt(this.value);
|
| 294 |
+
heightValue.textContent = `${currentHeight}m`;
|
| 295 |
+
updateFallData();
|
| 296 |
});
|
| 297 |
|
| 298 |
startBtn.addEventListener('click', startSimulation);
|
|
|
|
| 309 |
btn.classList.add('ring-2', 'ring-blue-400');
|
| 310 |
renderPlanetSelection();
|
| 311 |
updatePlanetDataTable();
|
| 312 |
+
updateFallData();
|
| 313 |
}
|
| 314 |
} else {
|
| 315 |
selectedPlanets.splice(index, 1);
|
| 316 |
btn.classList.remove('ring-2', 'ring-blue-400');
|
| 317 |
renderPlanetSelection();
|
| 318 |
updatePlanetDataTable();
|
| 319 |
+
updateFallData();
|
| 320 |
}
|
| 321 |
}
|
| 322 |
|
|
|
|
| 369 |
gravityWell.style.backgroundColor = planet.color;
|
| 370 |
planetsContainer.appendChild(gravityWell);
|
| 371 |
|
| 372 |
+
// Ajout des données de chute sous chaque planète
|
| 373 |
+
const fallDataEl = document.createElement('div');
|
| 374 |
+
fallDataEl.className = 'fall-data';
|
| 375 |
+
fallDataEl.style.left = `${left}px`;
|
| 376 |
+
fallDataEl.style.color = planet.color;
|
| 377 |
+
fallDataEl.innerHTML = `
|
| 378 |
+
<div>Hauteur: ${currentHeight}m</div>
|
| 379 |
+
<div>Temps: ${calculateFallTime(currentHeight, planet.g).toFixed(2)}s</div>
|
| 380 |
+
<div>Vitesse: ${calculateFinalSpeed(currentHeight, planet.g).toFixed(2)}m/s</div>
|
| 381 |
+
`;
|
| 382 |
+
fallDataEl.id = `fall-data-${planetId}`;
|
| 383 |
+
planetsContainer.appendChild(fallDataEl);
|
| 384 |
+
|
| 385 |
// Ajout des statistiques de la planète
|
| 386 |
const statsEl = document.createElement('div');
|
| 387 |
statsEl.className = 'bg-gray-700 p-4 rounded-lg';
|
|
|
|
| 413 |
});
|
| 414 |
}
|
| 415 |
|
| 416 |
+
function calculateFallTime(height, gravity) {
|
| 417 |
+
return Math.sqrt(2 * height / gravity);
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
function calculateFinalSpeed(height, gravity) {
|
| 421 |
+
return Math.sqrt(2 * gravity * height);
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
function updateFallData() {
|
| 425 |
+
selectedPlanets.forEach(planetId => {
|
| 426 |
+
const planet = PLANETS[planetId];
|
| 427 |
+
const fallDataEl = document.getElementById(`fall-data-${planetId}`);
|
| 428 |
+
if (fallDataEl) {
|
| 429 |
+
fallDataEl.innerHTML = `
|
| 430 |
+
<div>Hauteur: ${currentHeight}m</div>
|
| 431 |
+
<div>Temps: ${calculateFallTime(currentHeight, planet.g).toFixed(2)}s</div>
|
| 432 |
+
<div>Vitesse: ${calculateFinalSpeed(currentHeight, planet.g).toFixed(2)}m/s</div>
|
| 433 |
+
`;
|
| 434 |
+
}
|
| 435 |
+
});
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
function updatePlanetDataTable() {
|
| 439 |
planetData.innerHTML = '';
|
| 440 |
|
| 441 |
Object.keys(PLANETS).forEach(planetId => {
|
| 442 |
const planet = PLANETS[planetId];
|
| 443 |
const isSelected = selectedPlanets.includes(planetId);
|
| 444 |
+
const fallTime100m = calculateFallTime(100, planet.g);
|
| 445 |
+
const finalSpeed100m = calculateFinalSpeed(100, planet.g);
|
| 446 |
|
| 447 |
const row = document.createElement('tr');
|
| 448 |
row.className = isSelected ? 'bg-gray-700' : 'border-b border-gray-700';
|
|
|
|
| 454 |
<td class="py-3 px-4">${planet.g}</td>
|
| 455 |
<td class="py-3 px-4">${planet.mass}</td>
|
| 456 |
<td class="py-3 px-4">${planet.radius}</td>
|
| 457 |
+
<td class="py-3 px-4">${fallTime100m.toFixed(2)} s</td>
|
| 458 |
+
<td class="py-3 px-4">${finalSpeed100m.toFixed(2)} m/s</td>
|
| 459 |
`;
|
| 460 |
planetData.appendChild(row);
|
| 461 |
});
|
|
|
|
| 469 |
startTime = Date.now();
|
| 470 |
objects = [];
|
| 471 |
|
| 472 |
+
const height = currentHeight;
|
| 473 |
const object = OBJECTS[objectType.value];
|
| 474 |
|
| 475 |
// Créer un objet pour chaque planète sélectionnée
|
|
|
|
| 494 |
falling: false,
|
| 495 |
startTime: null,
|
| 496 |
fallDuration: null,
|
| 497 |
+
finalSpeed: null,
|
| 498 |
+
statsEl: null
|
| 499 |
};
|
| 500 |
|
| 501 |
+
// Créer l'élément pour afficher les stats en temps réel
|
| 502 |
+
obj.statsEl = document.createElement('div');
|
| 503 |
+
obj.statsEl.className = 'planet-stats';
|
| 504 |
+
obj.statsEl.style.left = `${planetX}px`;
|
| 505 |
+
obj.statsEl.style.top = '20px';
|
| 506 |
+
obj.statsEl.style.color = planet.color;
|
| 507 |
+
obj.statsEl.innerHTML = `
|
| 508 |
+
<div>Temps: <span class="time-value">0.00</span>s</div>
|
| 509 |
+
<div>Vitesse: <span class="speed-value">0.00</span>m/s</div>
|
| 510 |
+
`;
|
| 511 |
+
planetsContainer.appendChild(obj.statsEl);
|
| 512 |
+
|
| 513 |
objects.push(obj);
|
| 514 |
|
| 515 |
// Mettre à jour le poids affiché
|
|
|
|
| 551 |
const fallTime = (now - obj.startTime) / 1000;
|
| 552 |
|
| 553 |
// Formule de chute libre: y = y0 + 0.5 * g * t^2
|
| 554 |
+
// On ajuste l'échelle pour que la chute soit visible à l'écran
|
| 555 |
+
const scaleFactor = (simulationCanvas.height / 2 - 50) / obj.height;
|
| 556 |
+
obj.y = 50 + 0.5 * obj.g * fallTime * fallTime * scaleFactor;
|
| 557 |
|
| 558 |
// Vitesse: v = g * t
|
| 559 |
obj.vy = obj.g * fallTime;
|
| 560 |
|
| 561 |
+
// Mettre à jour les stats en temps réel
|
| 562 |
+
if (obj.statsEl) {
|
| 563 |
+
obj.statsEl.querySelector('.time-value').textContent = fallTime.toFixed(2);
|
| 564 |
+
obj.statsEl.querySelector('.speed-value').textContent = obj.vy.toFixed(2);
|
| 565 |
+
}
|
| 566 |
+
|
| 567 |
// Vérifier si l'objet a atteint le sol
|
| 568 |
if (obj.y >= obj.planetY - 30) {
|
| 569 |
obj.y = obj.planetY - 30;
|
|
|
|
| 635 |
|
| 636 |
simulationRunning = false;
|
| 637 |
startBtn.disabled = false;
|
| 638 |
+
|
| 639 |
+
// Supprimer les éléments de stats
|
| 640 |
+
objects.forEach(obj => {
|
| 641 |
+
if (obj.statsEl && obj.statsEl.parentNode) {
|
| 642 |
+
obj.statsEl.parentNode.removeChild(obj.statsEl);
|
| 643 |
+
}
|
| 644 |
+
});
|
| 645 |
+
|
| 646 |
objects = [];
|
| 647 |
|
| 648 |
// Effacer le canvas
|
prompts.txt
CHANGED
|
@@ -1 +1,3 @@
|
|
| 1 |
-
Une application qui permet de faire une simulation de la gravité sur plusieurs planètes en même temps pour voir la différence. Prévoir les fonctionnalités nécessaires et utiles pour une bonne expérience.
|
|
|
|
|
|
|
|
|
| 1 |
+
Une application qui permet de faire une simulation de la gravité sur plusieurs planètes en même temps pour voir la différence. Prévoir les fonctionnalités nécessaires et utiles pour une bonne expérience.
|
| 2 |
+
Ajoutez dans la zone de simulation le temps de chute et la vitesse pour les planètes comparées.
|
| 3 |
+
Le temps de chute et la vitesse finale doivent changé en fonction de la hauteur de chute, et pour chaque planète dans la zone de simulation indiquez les valeurs du temps de chute et de la vitesse finale.
|