5 Best Ways to Model Projectile Motion Using Python

πŸ’‘ Problem Formulation: Understanding the dynamics of a projectile can be crucial for various applications, from sports to launching satellites. This article explores the computational approach to simulate projectile motion using Python, covering five different methods for modeling. For instance, given input parameters like initial velocity and angle of projection, the desired output would be the trajectory path, time of flight, and maximum height reached.

Method 1: Using Basic Kinematics Formulas

This method involves applying the fundamental kinematics equations to compute projectile motion parameters such as the trajectory, time of flight, and maximum height. The principle is governed by Newton’s laws of motion, considering the velocity decomposition into horizontal and vertical components, and the effect of gravity.

Here’s an example:

import matplotlib.pyplot as plt
import numpy as np

def projectile_motion(v0, angle):
    g = 9.81 
    theta = np.radians(angle)
    v0x = v0 * np.cos(theta)
    v0y = v0 * np.sin(theta)
    tf = (2 * v0y) / g
    t = np.linspace(0, tf, num=100)
    x = v0x * t
    y = v0y * t - 0.5 * g * t**2
    return x, y, tf

x, y, time_of_flight = projectile_motion(50, 45)
plt.plot(x, y)
plt.title("Projectile Motion")
plt.xlabel("Distance (m)")
plt.ylabel("Height (m)")
plt.show()

Output: A plot representing the trajectory of the motion.

In the above code, the projectile_motion function calculates the x and y coordinates of the projectile over time, given an initial velocity and angle. The matplotlib library is used to visualize the trajectory of the projectile.

Method 2: Using the sympy library for Symbolic Mathematics

Sympy is a Python library for symbolic mathematics. It can solve algebraic equations which represent the projectile motion. This method is beneficial to derive formulas or expressions for various projectile motion parameters.

Here’s an example:

from sympy import symbols, Eq, solve, sin, cos, pi

v0, angle, t, g = symbols('v0 angle t g')
x, y = symbols('x y')
theta = angle * pi / 180

eq1 = Eq(x, v0 * cos(theta) * t)
eq2 = Eq(y, v0 * sin(theta) * t - 0.5 * g * t**2)

trajectory_eq = solve((eq1, eq2), (x, y))
print(trajectory_eq)

Output: An expression representing the x and y coordinates of the projectile in terms of variables v0, angle, and t.

This example demonstrates how to use the sympy library to set up and solve equations for the projectile’s position at any point in time. The results are symbolic expressions that can be evaluated further for specific values.

Method 3: Object-Oriented Programming Approach

The object-oriented approach models the projectile as an object with properties such as position and velocity, and methods to update these properties over time using Newton’s laws. This method provides a modular and reusable structure for simulation.

Here’s an example:

import matplotlib.pyplot as plt

class Projectile:
    def __init__(self, v0, angle):
        self.x = 0
        self.y = 0
        self.v_x = v0 * np.cos(np.radians(angle))
        self.v_y = v0 * np.sin(np.radians(angle))
        self.g = 9.81

    def update(self, dt):
        self.x += self.v_x * dt
        self.y += self.v_y * dt
        self.v_y -= self.g * dt

    def plot_trajectory(self, total_time):
        timesteps = int(total_time / dt)
        x_vals, y_vals = [], []

        for _ in range(timesteps):
            self.update(dt)
            if self.y < 0: break
            x_vals.append(self.x)
            y_vals.append(self.y)

        plt.plot(x_vals, y_vals)
        plt.title("Projectile Motion (OOP Approach)")
        plt.xlabel("Distance (m)")
        plt.ylabel("Height (m)")
        plt.show()

dt = 0.01
projectile = Projectile(50, 45)
projectile.plot_trajectory(5)

Output: A plot representing the trajectory of the motion, generated using object-oriented concepts.

This code snippet defines a Projectile class with methods update and plot_trajectory. An instance of the class is created to simulate and visualize the projectile’s path over a specified interval.

Method 4: Simulating Projectile Motion with Air Resistance

Real-world projectile motion is subject to air resistance. This method takes into account the drag force, which is generally proportional to the velocity squared. It requires iterating through small time steps to update the projectile’s velocity and position.

Here’s an example:

import matplotlib.pyplot as plt

# Constants
g = 9.81
dt = 0.01
b = 0.001 # Drag coefficient

# Initial Conditions
v0 = 50
angle = 45
vx = v0 * np.cos(np.radians(angle))
vy = v0 * np.sin(np.radians(angle))
x, y = 0, 0

# Lists to store positions
x_positions, y_positions = [], []

while y >= 0:
    # Update velocities with drag
    v = np.sqrt(vx**2 + vy**2)
    drag = b * v**2
    angle_of_velocity = np.arctan2(vy, vx)
    vx -= drag * np.cos(angle_of_velocity) * dt
    vy -= (g + drag * np.sin(angle_of_velocity)) * dt

    # Update positions
    x += vx * dt
    y += vy * dt
    x_positions.append(x)
    y_positions.append(y)

plt.plot(x_positions, y_positions)
plt.title("Projectile Motion with Air Resistance")
plt.xlabel("Distance (m)")
plt.ylabel("Height (m)")
plt.show()

Output: A plot showing the path of the projectile affected by air resistance.

This code snippet calculates projectile motion considering air resistance. The drag force is applied to the velocity components, and the position is updated accordingly during each small timestep.

Bonus One-Liner Method 5: Using numpy to Calculate Trajectory Instantly

NumPy is a powerful library that can compute arrays of values instantly. This one-liner approach uses NumPy functions to calculate the entire trajectory without a loop, suitable for simple dragless projectile motion simulations.

Here’s an example:

import matplotlib.pyplot as plt
import numpy as np

v0, angle = 50, 45 # Initial conditions
g = 9.81 # Acceleration due to gravity
theta = np.radians(angle)
t = np.linspace(0, 2 * v0 * np.sin(theta) / g, 100)

plt.plot(v0 * np.cos(theta) * t, v0 * np.sin(theta) * t - 0.5 * g * t**2)
plt.title("Quick Projectile Motion using Numpy")
plt.xlabel("Distance (m)")
plt.ylabel("Height (m)")
plt.show()

Output: A plot showing a dragless projectile trajectory.

The code uses NumPy to create time steps and computes the trajectory positions at each step, which is then plotted using Matplotlib. This method is extremely fast, but does not account for air resistance.

Summary/Discussion

  • Method 1: Basic Kinematics Formulas. Simple and intuitive. Limited to ideal conditions without air resistance.
  • Method 2: sympy library for Symbolic Mathematics. Useful for deriving exact equations. Computationally intensive for numerical simulations.
  • Method 3: Object-Oriented Programming Approach. Modular and reusable code. More complex to set up for simple problems.
  • Method 4: Projectile Motion with Air Resistance. Realistic simulations. Computation involves iterations and is more complex.
  • Bonus Method 5: NumPy for Instant Calculations. Fast and efficient for dragless scenarios. Not suitable for more nuanced real-life conditions.