
In this blog post, we’ll dive into the fascinating world of projectile motion and how we can simulate it using CesiumJS, a powerful library for creating 3D globes and maps. We’ll break down the key concepts used in our simulation, including the quadratic equation, and explain how they come together to create an interactive visualization of projectile motion.
The Basics of Projectile Motion
Projectile motion is a form of motion where an object is launched into the air and travels along a curved path under the influence of gravity. Think of a ball thrown into the air or a cannon firing a projectile. The path this object follows is called a parabola.
The Quadratic Equation in Projectile Motion
At the heart of our simulation lies the quadratic equation. In the context of projectile motion, we use two quadratic equations:
- For the horizontal distance (x):
x = v₀ * cos(θ) * t - For the vertical distance (y):
y = v₀ * sin(θ) * t – (1/2) * g * t²
Where:
- v₀ is the initial velocity
- θ is the launch angle
- t is time
- g is the acceleration due to gravity
The equation for y is a quadratic equation in its standard form (ax² + bx + c). This quadratic nature is what gives the projectile its parabolic path.
Full Source Code
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive CesiumJS Projectile Simulation</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/cesium/1.95.0/Cesium.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/cesium/1.95.0/Widgets/widgets.min.css" rel="stylesheet"> <style> html, body { height: 100%; margin: 0; padding: 0; overflow: hidden; } #cesiumContainer { position: absolute; top: 0; left: 0; height: 100%; width: 100%; } #controls { position: absolute; top: 10px; left: 10px; z-index: 1000; background-color: rgba(255, 255, 255, 0.8); padding: 10px; border-radius: 5px; } #controls label { display: block; margin-bottom: 5px; } #controls input { margin-right: 10px; } </style> </head> <body> <div id="cesiumContainer"></div> <div id="controls"> <label>Initial Velocity (m/s): <input type="number" id="velocity" value="50" min="1" max="1000"> </label> <label>Launch Angle (degrees): <input type="number" id="angle" value="45" min="0" max="90"> </label> <label>Gravity (m/s²): <input type="number" id="gravity" value="9.81" min="0" max="100" step="0.01"> </label> <button id="startSimulation">Start Simulation</button> </div> <script> // Set the access token Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkM2I3YTNiNy0wNjNiLTRmNDEtODFiMy05ODAzOGQ2ZTM0YjkiLCJpZCI6NzExNywiaWF0IjoxNjkwOTIzNDQzfQ.hI_Ri0N2Y3bWNzp7ckE4ho6nr4ZQMDMxFrluGgHSdy4'; // Initialize the Cesium viewer const viewer = new Cesium.Viewer('cesiumContainer'); // Set the camera position viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 1000) }); let redLine; let point; let animationInterval; function startSimulation() { // Clear previous simulation viewer.entities.removeAll(); clearInterval(animationInterval); // Get parameters from inputs const initialVelocity = parseFloat(document.getElementById('velocity').value); const launchAngle = parseFloat(document.getElementById('angle').value) * Math.PI / 180; // convert to radians const gravity = parseFloat(document.getElementById('gravity').value); // Calculate time of flight const timeOfFlight = 2 * initialVelocity * Math.sin(launchAngle) / gravity; // Generate positions for the projectile path const positions = []; for (let t = 0; t <= timeOfFlight; t += 0.1) { const x = initialVelocity * Math.cos(launchAngle) * t; const y = initialVelocity * Math.sin(launchAngle) * t - 0.5 * gravity * t * t; // Convert local coordinates to geographic coordinates const position = Cesium.Cartesian3.fromDegrees( -75.59777 + x / 111000, 40.03883, y // Use y directly for altitude ); positions.push(position); } // Create a polyline for the projectile path redLine = viewer.entities.add({ polyline: { positions: positions, width: 2, material: Cesium.Color.RED } }); // Add a point for the projectile point = viewer.entities.add({ position: positions[0], point: { pixelSize: 10, color: Cesium.Color.YELLOW } }); // Animate the projectile let time = 0; animationInterval = setInterval(() => { time += 0.1; if (time <= timeOfFlight) { const index = Math.floor(time / 0.1); point.position = positions[index]; } else { clearInterval(animationInterval); } }, 100); // Adjust the camera to view the entire path viewer.zoomTo(redLine); } // Add event listener to the start button document.getElementById('startSimulation').addEventListener('click', startSimulation); </script> </body> </html> |
Key Concepts in Our Simulation
1. Initialization
We start by setting up a CesiumJS viewer, which provides the 3D globe on which we’ll visualize our projectile:
const viewer = new Cesium.Viewer('cesiumContainer');
2. User Input
We allow users to input three key parameters:
- Initial velocity
- Launch angle
- Gravity
These inputs directly feed into our quadratic equations.
3. Time of Flight Calculation
We calculate the total time the projectile will be in the air:
const timeOfFlight = 2 * initialVelocity * Math.sin(launchAngle) / gravity;
This formula is derived from the quadratic equation for vertical motion, solving for when y = 0 (i.e., when the projectile hits the ground).
4. Generating Projectile Positions
We use a loop to generate positions for the projectile at small time intervals:
for (let t = 0; t <= timeOfFlight; t += 0.1) {
const x = initialVelocity * Math.cos(launchAngle) * t;
const y = initialVelocity * Math.sin(launchAngle) * t - 0.5 * gravity * t * t;
// ...
}
Here, we’re directly applying our quadratic equations to calculate x and y positions over time.
5. Visualization
We use CesiumJS entities to visualize the projectile path:
- A red polyline shows the entire trajectory.
- A yellow point represents the projectile itself.
6. Animation
We animate the projectile using setInterval, updating its position every 100 milliseconds:
animationInterval = setInterval(() => {
// Update projectile position
}, 100);
The Power of the Quadratic Equation
The quadratic equation is crucial in this simulation because it accurately models the parabolic path of a projectile under constant acceleration (gravity). The term -0.5 * gravity * t * t in our vertical distance equation is what causes the projectile to fall back to Earth, creating the characteristic parabolic arc.
The Quadratic Equation in Our Code
In our simulation code, the quadratic equation is not explicitly written out in its standard form (ax² + bx + c = 0). Instead, it’s implemented in its parametric form for projectile motion. Let’s look at the relevant part of the code:
for (let t = 0; t <= timeOfFlight; t += 0.1) {
const x = initialVelocity * Math.cos(launchAngle) * t;
const y = initialVelocity * Math.sin(launchAngle) * t - 0.5 * gravity * t * t;
// Convert local coordinates to geographic coordinates
const position = Cesium.Cartesian3.fromDegrees(
-75.59777 + x / 111000,
40.03883,
y // Use y directly for altitude
);
positions.push(position);
}
The quadratic equation is represented in the calculation of y:
const y = initialVelocity * Math.sin(launchAngle) * t - 0.5 * gravity * t * t;
This is the equation for the vertical displacement of a projectile under constant acceleration due to gravity.
Derivation of the Quadratic Equation for Projectile Motion
To understand how this equation is derived, let’s break it down step by step:
- In projectile motion, we have two key equations:
- Velocity: v = v₀ + at
- Position: y = y₀ + v₀t + ½at² Where v₀ is initial velocity, a is acceleration, t is time, and y₀ is initial position.
- For vertical motion in our simulation:
- Initial vertical velocity: v₀y = initialVelocity * sin(launchAngle)
- Acceleration: a = -gravity (negative because gravity acts downward)
- Initial position: y₀ = 0 (we start at ground level)
- Substituting these into the position equation:
y = 0 + (initialVelocity * sin(launchAngle)) * t + ½(-gravity) * t² - Simplifying:
y = (initialVelocity * sin(launchAngle)) * t – ½ * gravity * t²
This is exactly the equation we see in our code for calculating y.
The Quadratic Nature of the Equation
While it might not look like the standard form of a quadratic equation (ax² + bx + c = 0), our equation for y is indeed quadratic in terms of time t:
- The t² term: -½ * gravity * t²
- The t term: initialVelocity * sin(launchAngle) * t
- The constant term: 0 (implicit, since we start at y = 0)
This quadratic relationship between y and t is what gives the projectile its parabolic path.
How the Code Uses the Quadratic Equation
In our simulation:
- We calculate
yfor various values oftusing this quadratic equation. - We pair each
ywith a correspondingx(which has a linear relationship with t). - These (x, y) pairs form the points of our projectile’s path.
- We convert these local (x, y) coordinates to geographic coordinates for display on the globe.
By repeatedly applying this equation for different time values, we generate the entire parabolic trajectory of the projectile.
Conclusion
By combining the mathematical precision of the quadratic equation with the visualization capabilities of CesiumJS, we’ve created an interactive and educational tool for understanding projectile motion. This simulation allows users to experiment with different initial conditions and see how they affect the projectile’s path, providing an intuitive understanding of the physical principles at work.
Whether you’re a student learning about physics, an educator looking for interactive teaching tools, or just someone curious about the math behind everyday phenomena, this projectile motion simulation offers valuable insights into the elegant mathematics that governs the world around us.
I hope this tutorial will create a good foundation for you. If you want tutorials on another GIS topic or you have any queries, please send an mail at contact@spatial-dev.guru.
