Simulate realistic projectile motion!
Project description
ProjectilePy
A python library aimed at simulating and solving projectile motion problems. Includes various methods for running accurate numerical discrete-time simulations, both with and without drag.
Features:
- Configurable drag or drag-less simulations for projectiles.
- Real world atmospheric data for improved accuracy with Newtonian drag.
- Itterative root finding methods for calculating firing solutions to targets.
- Easy to use simulator object class, with included examples.
Installation:
The package is availble through the Python Package Index, and can be easily installed using pip.
In your system shell, run the command pip install ProjectilePy
Usage:
In this example we will create a simple simulation of a pumpkin being fired from an air cannon. For more general eamples, please check the src/examples folder.
- Create a new intance of the simulator class. The constructor can take many arguments but in this case we will only be using the
initial_velocity
andinitial_angle
arguments, and leaving everything else as default. Let's assume our theorhetical air cannon can fire a pumpkin at 75 m/s, and it's being fired at a 30 degree angle.import projectilepy mySimulator = projectilepy.model(initial_velocity=75, initial_angle=30)
- Lets start by running a simple simulation without any air resistance at all. This can be done by invoking the
run()
method on our simulator class.mySimulator.run()
- But nothing happened? That's right, the
run()
method completes a simulation, but doesn't provide us any information until we query some of the results. Let's start by seeing how far our pumpkin landed. We can do thing by invoking thefinal_position()
method, which returns an x-y tuple of position values. In this case, the x-value will be the total distance in meters.final_position = mySimulator.final_position() distance = final_position[0] print("Our pumpkin flew a total of", distance, "meters!")
- Our pumpkin flew a total of 488 meters, not bad! If you have matplotlib installed, you can visualise the trajectory of the pumpkin using a scatterplot. But first we'll need to format our data a bit. Our simulation model stores positional data as a list of x-y tuples, but matplotlib works with seperate x and y lists. We can fix this with a quick zip command on our model's position values.
import matplotlib.pyplot as plt x, y = zip(*mySimulator.positionValues) #Formats coordinate pairs into two lists fig, ax = plt.subplots() ax.plot(x, y) plt.show()
- Now dragless simulations are all well and good, but Earth has an atmosphere, so let's run a simulation using a Newtonian drag model. We'll specify this by setting the
drag
attribute of our model to "Newtonian". We'll also need to make sure our model has a couple aerodynamic values for our projectile. Specifically we need to provide themass
,drag_coefficient
, andcross_sectional_area
for a pumpkin.mySimulator.drag = "Newtonian" mySimulator.mass = 8 #8kg of mass mySimulator.drag_coefficient = 0.35 #ballpark drag number mySimulator.cross_sectional_area = 0.07 #from a diameter of 30cm
- Now that our model knows we want a Newtonian drag model and has all the required information, we can invoke the
run()
method to execute a new simulation.mySimulator.run()
- We can once again check how far our pumpkin made it
final_position = mySimulator.final_position() distance = final_position[0] print("With drag, our pumpkin flew a total of", distance, "meters!")
- Now our pumpkin only flew a total of 308 meters, drag is a killer. Let's have a look at the plot of our trajectory, it should look a little bit different now that the simulation is modelling drag.
x, y = zip(*mySimulator.positionValues) fig, ax = plt.subplots() ax.plot(x, y) plt.show()
- Those are the basics of running a simulation, but this package can do much more than run static models. Let's instead say we wanted to beat the world record Punkin Chunkin distance of 4694.68 ft (1430.94 m) set in 2013. Well then we need to know how fast to fire our pumpkin. We can find this using the
solve_velocity()
method which calculates the velocity needed to hit a target vector. In this case we want to beat the world record, so we'll set our target to[1450, 0]
which means it will have traveled a total of 1450 m before impact.muzzle_velocity = mySimulator.solve_velocity([1450,0]) print("We would need a muzzle velocity of", muzzle_velocity, "m/s")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
projectilepy-0.2.1.tar.gz
(9.5 kB
view hashes)
Built Distribution
Close
Hashes for projectilepy-0.2.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 93f71439f8548c64b706101212c9e91f5ac1e9b591c8cca87cf4a28c4fbffdb9 |
|
MD5 | 441d6ddc1383d6e75b1bff1a789bbfc1 |
|
BLAKE2b-256 | b65eeb7612b92412ab2b7e4c310fd77b7356d31adea54c88c8d4bbac93bf1ca2 |