diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6f3a291
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "liveServer.settings.port": 5501
+}
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..afaa5b6
--- /dev/null
+++ b/index.html
@@ -0,0 +1,67 @@
+
+
+
+
+
+ Projectile Motion Simulator
+
+
+
+
+
Projectile Motion Simulator
+
+
+
+
+
+
+
Initial Velocity
+
v₀ = 0 m/s
+
+
+
Maximum Height
+
h_max = 0 m
+
+
+
Time of Flight
+
t = 0 s
+
+
+
+
+
+
+
+ Projectile
+
+
+
+ Velocity Vectors
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/javascript.svg b/javascript.svg
new file mode 100644
index 0000000..f9abb2b
--- /dev/null
+++ b/javascript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/projectile.js b/projectile.js
new file mode 100644
index 0000000..677f650
--- /dev/null
+++ b/projectile.js
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..7581e40
--- /dev/null
+++ b/script.js
@@ -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);
+});
\ No newline at end of file
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..45e5119
--- /dev/null
+++ b/style.css
@@ -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;
+ }
\ No newline at end of file
diff --git a/visulize.js b/visulize.js
new file mode 100644
index 0000000..9e10add
--- /dev/null
+++ b/visulize.js
@@ -0,0 +1,154 @@
+class ProjectileVisualizer {
+ constructor(canvasId) {
+ this.canvas = document.getElementById(canvasId);
+ this.ctx = this.canvas.getContext('2d');
+ this.setCanvasSize();
+ this.animationId = null;
+ this.currentTime = 0;
+ this.projectile = null;
+ this.scale = 1;
+ this.padding = 20;
+ window.addEventListener('resize', () => this.setCanvasSize());
+ }
+
+ setCanvasSize() {
+ this.canvas.width = this.canvas.offsetWidth;
+ this.canvas.height = this.canvas.offsetHeight;
+ }
+
+ calculateScale(points) {
+ const maxX = Math.max(...points.map(p => p.x));
+ const maxY = Math.max(...points.map(p => p.y));
+ const scaleX = (this.canvas.width - this.padding * 2) / maxX;
+ const scaleY = (this.canvas.height - this.padding * 2) / maxY;
+ this.scale = Math.min(scaleX, scaleY);
+ }
+
+ drawAxes() {
+ this.ctx.beginPath();
+ this.ctx.strokeStyle = '#94a3b8';
+ this.ctx.lineWidth = 1;
+
+ // X-axis
+ this.ctx.moveTo(this.padding, this.canvas.height - this.padding);
+ this.ctx.lineTo(this.canvas.width - this.padding, this.canvas.height - this.padding);
+
+ // Y-axis
+ this.ctx.moveTo(this.padding, this.canvas.height - this.padding);
+ this.ctx.lineTo(this.padding, this.padding);
+
+ // Draw arrows
+ this.ctx.moveTo(this.canvas.width - this.padding, this.canvas.height - this.padding);
+ this.ctx.lineTo(this.canvas.width - this.padding - 10, this.canvas.height - this.padding - 5);
+ this.ctx.moveTo(this.canvas.width - this.padding, this.canvas.height - this.padding);
+ this.ctx.lineTo(this.canvas.width - this.padding - 10, this.canvas.height - this.padding + 5);
+
+ this.ctx.moveTo(this.padding, this.padding);
+ this.ctx.lineTo(this.padding - 5, this.padding + 10);
+ this.ctx.moveTo(this.padding, this.padding);
+ this.ctx.lineTo(this.padding + 5, this.padding + 10);
+
+ this.ctx.stroke();
+ }
+
+ drawTrajectory(points) {
+ this.ctx.beginPath();
+ this.ctx.strokeStyle = '#94a3b8';
+ this.ctx.lineWidth = 1;
+ points.forEach((point, i) => {
+ const x = point.x * this.scale + this.padding;
+ const y = this.canvas.height - (point.y * this.scale + this.padding);
+ if (i === 0) {
+ this.ctx.moveTo(x, y);
+ } else {
+ this.ctx.lineTo(x, y);
+ }
+ });
+ this.ctx.stroke();
+ }
+
+ drawProjectile(x, y) {
+ const radius = 8;
+ this.ctx.beginPath();
+ this.ctx.fillStyle = '#2563eb';
+ this.ctx.arc(
+ x * this.scale + this.padding,
+ this.canvas.height - (y * this.scale + this.padding),
+ radius,
+ 0,
+ Math.PI * 2
+ );
+ this.ctx.fill();
+ }
+
+ drawVelocityVectors(x, y, vx, vy) {
+ const scaledX = x * this.scale + this.padding;
+ const scaledY = this.canvas.height - (y * this.scale + this.padding);
+ const vectorScale = 20;
+
+ // Draw velocity vectors
+ this.ctx.beginPath();
+ this.ctx.strokeStyle = '#22c55e';
+ this.ctx.lineWidth = 2;
+
+ // Horizontal velocity
+ this.ctx.moveTo(scaledX, scaledY);
+ this.ctx.lineTo(scaledX + vx * vectorScale, scaledY);
+
+ // Vertical velocity
+ this.ctx.moveTo(scaledX, scaledY);
+ this.ctx.lineTo(scaledX, scaledY - vy * vectorScale);
+
+ // Resultant velocity
+ this.ctx.moveTo(scaledX, scaledY);
+ this.ctx.lineTo(
+ scaledX + vx * vectorScale,
+ scaledY - vy * vectorScale
+ );
+
+ this.ctx.stroke();
+ }
+
+ animate(projectile) {
+ if (this.animationId) {
+ cancelAnimationFrame(this.animationId);
+ }
+
+ this.projectile = projectile;
+ this.currentTime = 0;
+ const totalTime = projectile.calculateTimeOfFlight();
+ const points = projectile.getTrajectoryPoints();
+ this.calculateScale(points);
+
+ const animate = () => {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ // Draw background elements
+ this.drawAxes();
+ this.drawTrajectory(points);
+
+ // Calculate current position and velocities
+ const { x, y } = projectile.getPositionAtTime(this.currentTime);
+ const { vx, vy } = projectile.calculateInitialVelocities();
+ const currentVy = vy - g * this.currentTime;
+
+ // Draw velocity vectors and projectile
+ this.drawVelocityVectors(x, y, vx, currentVy);
+ this.drawProjectile(x, y);
+
+ if (this.currentTime < totalTime) {
+ this.currentTime += totalTime / 100;
+ this.animationId = requestAnimationFrame(animate);
+ }
+ };
+
+ animate();
+ }
+
+ stop() {
+ if (this.animationId) {
+ cancelAnimationFrame(this.animationId);
+ this.animationId = null;
+ }
+ }
+ }
\ No newline at end of file