mirror of
https://github.com/NotAShelf/projectile-simulation.git
synced 2024-11-22 13:20:47 +00:00
put stuff on git so they don't get lost
This commit is contained in:
parent
37d095a459
commit
c1c0b5c162
6 changed files with 120 additions and 0 deletions
20
README.md
Normal file
20
README.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Projectile Simulation
|
||||
|
||||
This project simulates the motion of a projectile with air resistance.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone this repository.
|
||||
2. Install the required packages using pip:
|
||||
|
||||
```shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Run the main.py script:
|
||||
|
||||
```shell
|
||||
python main.py
|
||||
```
|
13
main.py
Normal file
13
main.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from projectile.simulation import ProjectileSimulation
|
||||
import numpy as np
|
||||
|
||||
|
||||
def main():
|
||||
sim = ProjectileSimulation(v_init=100, theta=np.radians(45))
|
||||
sim.run()
|
||||
sim.plot()
|
||||
sim.print_range()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
0
projectile/__init__.py
Normal file
0
projectile/__init__.py
Normal file
76
projectile/simulation.py
Normal file
76
projectile/simulation.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
class ProjectileSimulation:
|
||||
def __init__(
|
||||
self,
|
||||
g=9.81,
|
||||
C_d=0.01,
|
||||
v_init=100,
|
||||
theta=np.radians(180),
|
||||
h_init=10,
|
||||
dt=0.01,
|
||||
t_end=10,
|
||||
):
|
||||
self.g = g
|
||||
self.C_d = C_d
|
||||
self.v_init = v_init
|
||||
self.theta = theta
|
||||
self.h_init = h_init
|
||||
self.dt = dt
|
||||
self.t_end = t_end
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
self.x = [0]
|
||||
self.y = [self.h_init]
|
||||
self.vx = [self.v_init * np.cos(self.theta)]
|
||||
self.vy = [self.v_init * np.sin(self.theta)]
|
||||
self.t = [0]
|
||||
|
||||
def calculate_acceleration(self, t, state):
|
||||
x, y, vx, vy = state
|
||||
v = np.sqrt(vx**2 + vy**2)
|
||||
F_air_x = -self.C_d * v * vx
|
||||
F_air_y = -self.C_d * v * vy
|
||||
ax = F_air_x
|
||||
ay = F_air_y - self.g
|
||||
return [vx, vy, ax, ay]
|
||||
|
||||
def update_state(self, t, state):
|
||||
k1 = self.calculate_acceleration(t, state)
|
||||
k2 = self.calculate_acceleration(
|
||||
t + 0.5 * self.dt, [s + 0.5 * self.dt * k for s, k in zip(state, k1)]
|
||||
)
|
||||
k3 = self.calculate_acceleration(
|
||||
t + 0.5 * self.dt, [s + 0.5 * self.dt * k for s, k in zip(state, k2)]
|
||||
)
|
||||
k4 = self.calculate_acceleration(
|
||||
t + self.dt, [s + self.dt * k for s, k in zip(state, k3)]
|
||||
)
|
||||
return [
|
||||
s + self.dt / 6 * (k1_i + 2 * k2_i + 2 * k3_i + k4_i)
|
||||
for s, k1_i, k2_i, k3_i, k4_i in zip(state, k1, k2, k3, k4)
|
||||
]
|
||||
|
||||
def run(self):
|
||||
while self.t[-1] < self.t_end:
|
||||
state = [self.x[-1], self.y[-1], self.vx[-1], self.vy[-1]]
|
||||
state = self.update_state(self.t[-1], state)
|
||||
self.x.append(state[0])
|
||||
self.y.append(state[1])
|
||||
self.vx.append(state[2])
|
||||
self.vy.append(state[3])
|
||||
self.t.append(self.t[-1] + self.dt)
|
||||
|
||||
def plot(self):
|
||||
plt.plot(self.x, self.y)
|
||||
plt.xlabel("Horizontal distance (m)")
|
||||
plt.ylabel("Vertical distance (m)")
|
||||
plt.title("Projectile Motion with Air Resistance")
|
||||
plt.show()
|
||||
|
||||
def print_range(self):
|
||||
range_projectile = self.x[-1]
|
||||
print(f"Range of projectile: {range_projectile:.2f} m")
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
numpy
|
||||
matplotlib
|
9
shell.nix
Normal file
9
shell.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{pkgs ? import <nixpkgs> {}}: let
|
||||
my-python-packages = ps:
|
||||
with ps; [
|
||||
matplotlib
|
||||
numpy
|
||||
];
|
||||
my-python = pkgs.python3.withPackages my-python-packages;
|
||||
in
|
||||
my-python.env
|
Loading…
Reference in a new issue