Name | ProjectilePy JSON |
Version |
0.2.1
JSON |
| download |
home_page | |
Summary | Simulate realistic projectile motion! |
upload_time | 2023-09-21 15:51:22 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.7 |
license | MIT License Copyright (c) 2023 Zachary Collins-Kenner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
ballistic
projectile
simulation
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# 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.
1. 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` and `initial_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)
```
2. 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()
```
3. 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 the `final_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!")
```
4. 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()
```
5. 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 the `mass`, `drag_coefficient`, and `cross_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
```
6. 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()
```
7. 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!")
```
8. 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()
```
9. 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")
```
Raw data
{
"_id": null,
"home_page": "",
"name": "ProjectilePy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "ballistic,projectile,simulation",
"author": "",
"author_email": "Zachary Collins-Kenner <zachary.ck12@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/74/4e/f0e3bd9a96628f61c72acb62c5455a227366f66b113352f0f585ccad828d/projectilepy-0.2.1.tar.gz",
"platform": null,
"description": "# ProjectilePy\nA 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. \n\n## Features:\n* Configurable drag or drag-less simulations for projectiles.\n* Real world atmospheric data for improved accuracy with Newtonian drag.\n* Itterative root finding methods for calculating firing solutions to targets.\n* Easy to use simulator object class, with included examples.\n\n## Installation:\nThe package is availble through the Python Package Index, and can be easily installed using pip.\nIn your system shell, run the command `pip install ProjectilePy`\n\n## Usage:\n\n In this example we will create a simple simulation of a pumpkin being fired from an air cannon.\n For more general eamples, please check the src/examples folder.\n\n1. 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` and `initial_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.\n ```\n import projectilepy\n mySimulator = projectilepy.model(initial_velocity=75, initial_angle=30)\n ```\n2. 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.\n ```\n mySimulator.run()\n ```\n3. 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 the `final_position()` method, which returns an x-y tuple of position values. In this case, the x-value will be the total distance in meters.\n ```\n final_position = mySimulator.final_position()\n distance = final_position[0]\n print(\"Our pumpkin flew a total of\", distance, \"meters!\")\n ```\n4. 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.\n ```\n import matplotlib.pyplot as plt\n x, y = zip(*mySimulator.positionValues) #Formats coordinate pairs into two lists\n fig, ax = plt.subplots()\n ax.plot(x, y)\n plt.show()\n ```\n5. 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 the `mass`, `drag_coefficient`, and `cross_sectional_area` for a pumpkin.\n ```\n mySimulator.drag = \"Newtonian\"\n mySimulator.mass = 8 #8kg of mass\n mySimulator.drag_coefficient = 0.35 #ballpark drag number\n mySimulator.cross_sectional_area = 0.07 #from a diameter of 30cm\n ```\n6. 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.\n ```\n mySimulator.run()\n ```\n7. We can once again check how far our pumpkin made it\n ```\n final_position = mySimulator.final_position()\n distance = final_position[0]\n print(\"With drag, our pumpkin flew a total of\", distance, \"meters!\")\n ```\n8. 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.\n ```\n x, y = zip(*mySimulator.positionValues)\n fig, ax = plt.subplots()\n ax.plot(x, y)\n plt.show()\n ```\n9. 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.\n ```\n muzzle_velocity = mySimulator.solve_velocity([1450,0])\n print(\"We would need a muzzle velocity of\", muzzle_velocity, \"m/s\")\n ```\n",
"bugtrack_url": null,
"license": "MIT License Copyright (c) 2023 Zachary Collins-Kenner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"summary": "Simulate realistic projectile motion!",
"version": "0.2.1",
"project_urls": {
"Bug Tracker": "https://github.com/ZCK12/ProjectilePy/issues",
"Homepage": "https://github.com/ZCK12/ProjectilePy"
},
"split_keywords": [
"ballistic",
"projectile",
"simulation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b65eeb7612b92412ab2b7e4c310fd77b7356d31adea54c88c8d4bbac93bf1ca2",
"md5": "441d6ddc1383d6e75b1bff1a789bbfc1",
"sha256": "93f71439f8548c64b706101212c9e91f5ac1e9b591c8cca87cf4a28c4fbffdb9"
},
"downloads": -1,
"filename": "projectilepy-0.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "441d6ddc1383d6e75b1bff1a789bbfc1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 9363,
"upload_time": "2023-09-21T15:51:20",
"upload_time_iso_8601": "2023-09-21T15:51:20.901152Z",
"url": "https://files.pythonhosted.org/packages/b6/5e/eb7612b92412ab2b7e4c310fd77b7356d31adea54c88c8d4bbac93bf1ca2/projectilepy-0.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "744ef0e3bd9a96628f61c72acb62c5455a227366f66b113352f0f585ccad828d",
"md5": "250d41c3a38200298c7ddf83a1ec908c",
"sha256": "7f135d1a1ce9670a7299b47b0a842f12e11032e44defe3ed34a36d34b314f099"
},
"downloads": -1,
"filename": "projectilepy-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "250d41c3a38200298c7ddf83a1ec908c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 9512,
"upload_time": "2023-09-21T15:51:22",
"upload_time_iso_8601": "2023-09-21T15:51:22.973142Z",
"url": "https://files.pythonhosted.org/packages/74/4e/f0e3bd9a96628f61c72acb62c5455a227366f66b113352f0f585ccad828d/projectilepy-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-21 15:51:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ZCK12",
"github_project": "ProjectilePy",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "projectilepy"
}