-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2291314
Showing
7 changed files
with
430 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"liveServer.settings.port": 5501 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Projectile Motion Simulator</title> | ||
<link rel="stylesheet" href="style.css" /> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<h1>Projectile Motion Simulator</h1> | ||
|
||
<div class="simulator"> | ||
<div class="inputs"> | ||
<div class="input-group"> | ||
<label for="mass">Mass (kg):</label> | ||
<input type="number" id="mass" value="1" min="0.1" step="0.1"> | ||
</div> | ||
<div class="input-group"> | ||
<label for="angle">Angle (degrees):</label> | ||
<input type="number" id="angle" value="45" min="0" max="90"> | ||
</div> | ||
<div class="input-group"> | ||
<label for="force">Initial Force (N):</label> | ||
<input type="number" id="force" value="100" min="1"> | ||
</div> | ||
<button id="calculate">Launch Projectile</button> | ||
</div> | ||
|
||
<div class="results"> | ||
<div class="result-group"> | ||
<h3>Initial Velocity</h3> | ||
<p>v₀ = <span id="initial-velocity">0</span> m/s</p> | ||
</div> | ||
<div class="result-group"> | ||
<h3>Maximum Height</h3> | ||
<p>h_max = <span id="max-height">0</span> m</p> | ||
</div> | ||
<div class="result-group"> | ||
<h3>Time of Flight</h3> | ||
<p>t = <span id="time-of-flight">0</span> s</p> | ||
</div> | ||
<div class="result-group"> | ||
<h3>Range</h3> | ||
<p>R = <span id="range">0</span> m</p> | ||
</div> | ||
</div> | ||
|
||
<div class="legend"> | ||
<div class="legend-item"> | ||
<span class="legend-color" style="background: #2563eb"></span> | ||
<span>Projectile</span> | ||
</div> | ||
<div class="legend-item"> | ||
<span class="legend-color" style="background: #22c55e"></span> | ||
<span>Velocity Vectors</span> | ||
</div> | ||
</div> | ||
|
||
<canvas id="trajectory"></canvas> | ||
</div> | ||
</div> | ||
<script src="./projectile.js"></script> | ||
<script src="./visulize.js"></script> | ||
<script src="script.js"></script> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
const g = 9.81; // Acceleration due to gravity (m/s²) | ||
|
||
class ProjectileMotion { | ||
constructor(mass, angle, force) { | ||
this.mass = mass; | ||
this.angle = angle * (Math.PI / 180); // Convert to radians | ||
this.force = force; | ||
this.initialVelocity = this.force / this.mass; | ||
} | ||
|
||
calculateInitialVelocities() { | ||
return { | ||
vx: this.initialVelocity * Math.cos(this.angle), | ||
vy: this.initialVelocity * Math.sin(this.angle) | ||
}; | ||
} | ||
|
||
calculateMaxHeight() { | ||
const { vy } = this.calculateInitialVelocities(); | ||
return (vy * vy) / (2 * g); | ||
} | ||
|
||
calculateTimeOfFlight() { | ||
const { vy } = this.calculateInitialVelocities(); | ||
return (2 * vy) / g; | ||
} | ||
|
||
calculateRange() { | ||
const { vx } = this.calculateInitialVelocities(); | ||
return vx * this.calculateTimeOfFlight(); | ||
} | ||
|
||
getPositionAtTime(t) { | ||
const { vx, vy } = this.calculateInitialVelocities(); | ||
return { | ||
x: vx * t, | ||
y: vy * t - (0.5 * g * t * t) | ||
}; | ||
} | ||
|
||
getTrajectoryPoints() { | ||
const points = []; | ||
const totalTime = this.calculateTimeOfFlight(); | ||
const steps = 100; | ||
const dt = totalTime / steps; | ||
|
||
for (let t = 0; t <= totalTime; t += dt) { | ||
points.push(this.getPositionAtTime(t)); | ||
} | ||
|
||
return points; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Initialize visualizer | ||
const visualizer = new ProjectileVisualizer('trajectory'); | ||
|
||
// Setup event listeners | ||
document.getElementById('calculate').addEventListener('click', () => { | ||
const mass = parseFloat(document.getElementById('mass').value); | ||
const angle = parseFloat(document.getElementById('angle').value); | ||
const force = parseFloat(document.getElementById('force').value); | ||
|
||
const projectile = new ProjectileMotion(mass, angle, force); | ||
|
||
// Update results | ||
document.getElementById('initial-velocity').textContent = | ||
projectile.initialVelocity.toFixed(2); | ||
document.getElementById('max-height').textContent = | ||
projectile.calculateMaxHeight().toFixed(2); | ||
document.getElementById('time-of-flight').textContent = | ||
projectile.calculateTimeOfFlight().toFixed(2); | ||
document.getElementById('range').textContent = | ||
projectile.calculateRange().toFixed(2); | ||
|
||
// Start animation | ||
visualizer.animate(projectile); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
:root { | ||
--primary-color: #2563eb; | ||
--background-color: #f8fafc; | ||
--text-color: #1e293b; | ||
--border-color: #e2e8f0; | ||
} | ||
|
||
body { | ||
margin: 0; | ||
font-family: system-ui, -apple-system, sans-serif; | ||
background-color: var(--background-color); | ||
color: var(--text-color); | ||
line-height: 1.5; | ||
} | ||
|
||
.container { | ||
max-width: 1200px; | ||
margin: 0 auto; | ||
padding: 2rem; | ||
} | ||
|
||
h1 { | ||
text-align: center; | ||
color: var(--primary-color); | ||
margin-bottom: 2rem; | ||
} | ||
|
||
.simulator { | ||
background: white; | ||
border-radius: 1rem; | ||
padding: 2rem; | ||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); | ||
} | ||
|
||
.inputs { | ||
display: grid; | ||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | ||
gap: 1.5rem; | ||
margin-bottom: 2rem; | ||
} | ||
|
||
.input-group { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 0.5rem; | ||
} | ||
|
||
label { | ||
font-weight: 500; | ||
color: var(--text-color); | ||
} | ||
|
||
input { | ||
padding: 0.5rem; | ||
border: 1px solid var(--border-color); | ||
border-radius: 0.5rem; | ||
font-size: 1rem; | ||
} | ||
|
||
button { | ||
background-color: var(--primary-color); | ||
color: white; | ||
border: none; | ||
padding: 0.75rem 1.5rem; | ||
border-radius: 0.5rem; | ||
cursor: pointer; | ||
font-size: 1rem; | ||
font-weight: 500; | ||
transition: background-color 0.2s; | ||
} | ||
|
||
button:hover { | ||
background-color: #1d4ed8; | ||
} | ||
|
||
.results { | ||
display: grid; | ||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | ||
gap: 1.5rem; | ||
margin-bottom: 2rem; | ||
padding: 1rem; | ||
background-color: var(--background-color); | ||
border-radius: 0.5rem; | ||
} | ||
|
||
.result-group { | ||
text-align: center; | ||
} | ||
|
||
.result-group h3 { | ||
margin: 0; | ||
color: var(--primary-color); | ||
font-size: 1.1rem; | ||
} | ||
|
||
.result-group p { | ||
margin: 0.5rem 0 0 0; | ||
font-size: 1.1rem; | ||
font-weight: 500; | ||
} | ||
|
||
.legend { | ||
display: flex; | ||
gap: 2rem; | ||
justify-content: center; | ||
margin-bottom: 1rem; | ||
} | ||
|
||
.legend-item { | ||
display: flex; | ||
align-items: center; | ||
gap: 0.5rem; | ||
} | ||
|
||
.legend-color { | ||
width: 20px; | ||
height: 20px; | ||
border-radius: 50%; | ||
} | ||
|
||
canvas { | ||
width: 100%; | ||
height: 400px; | ||
border: 1px solid var(--border-color); | ||
border-radius: 0.5rem; | ||
margin-top: 1rem; | ||
background-color: white; | ||
} |
Oops, something went wrong.