Dynamics
fpc.dynamics
dynamics.py - kinematics and rigid-body dynamics calculations.
Dynamics is the study of motion and the forces that cause it. This class
collects the everyday formulas an engineer reaches for: kinematic equations,
projectile motion, Newton's second law, and momentum/energy relations. It also
includes a solve_ivp example - projectile flight WITH air drag, which has
no closed-form solution and so must be integrated numerically.
Every method takes keyword-only arguments (note the leading *) so that
calls are self-documenting, and every method returns a plain number or tuple so
results compose easily with numpy and scipy.
Dynamics
Kinematics and rigid-body dynamics helpers.
The methods are stateless, so one shared instance is fine::
dyn = Dynamics()
v = dyn.final_velocity(initial_velocity=0.0, acceleration=9.81, time=2.0)
Source code in fpc/dynamics.py
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
displacement_constant_acceleration(*, initial_position, initial_velocity, acceleration, time)
Displacement under constant acceleration: x = x0 + v0t + 1/2a*t^2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_position
|
starting position x0 [m] |
required | |
initial_velocity
|
starting velocity v0 [m/s] |
required | |
acceleration
|
constant acceleration a [m/s^2] |
required | |
time
|
elapsed time t [s] |
required |
Returns:
| Type | Description |
|---|---|
|
position x at time t [m] |
Source code in fpc/dynamics.py
35 36 37 38 39 40 41 42 43 44 45 46 | |
final_velocity(*, initial_velocity, acceleration, time)
Velocity after constant acceleration: v = v0 + a*t.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_velocity
|
starting velocity v0 [m/s] |
required | |
acceleration
|
constant acceleration a [m/s^2] |
required | |
time
|
elapsed time t [s] |
required |
Returns:
| Type | Description |
|---|---|
|
velocity v at time t [m/s] |
Source code in fpc/dynamics.py
48 49 50 51 52 53 54 55 56 | |
velocity_from_distance(*, initial_velocity, acceleration, distance)
Velocity after travelling a distance: v^2 = v0^2 + 2ad.
Useful when you know how far something moved but not how long it took.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_velocity
|
starting velocity v0 [m/s] |
required | |
acceleration
|
constant acceleration a [m/s^2] |
required | |
distance
|
distance travelled d [m] |
required |
Returns:
| Type | Description |
|---|---|
|
final speed v [m/s] (always non-negative) |
Source code in fpc/dynamics.py
58 59 60 61 62 63 64 65 66 67 68 69 | |
projectile_range(*, speed, angle_deg, gravity=GRAVITY)
Horizontal range of a projectile launched over flat ground.
R = v^2 * sin(2*theta) / g.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
speed
|
launch speed [m/s] |
required | |
angle_deg
|
launch angle above horizontal [degrees] |
required | |
gravity
|
gravitational acceleration [m/s^2], defaults to Earth |
GRAVITY
|
Returns:
| Type | Description |
|---|---|
|
horizontal range [m] |
Source code in fpc/dynamics.py
71 72 73 74 75 76 77 78 79 80 81 82 83 | |
projectile_time_of_flight(*, speed, angle_deg, gravity=GRAVITY)
Time a projectile spends in the air over flat ground.
t = 2 * v * sin(theta) / g.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
speed
|
launch speed [m/s] |
required | |
angle_deg
|
launch angle above horizontal [degrees] |
required | |
gravity
|
gravitational acceleration [m/s^2] |
GRAVITY
|
Returns:
| Type | Description |
|---|---|
|
time of flight [s] |
Source code in fpc/dynamics.py
85 86 87 88 89 90 91 92 93 94 95 96 | |
newtons_second_law(*, mass, acceleration)
Net force from Newton's second law: F = m*a.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mass
|
mass [kg] |
required | |
acceleration
|
acceleration [m/s^2] |
required |
Returns:
| Type | Description |
|---|---|
|
force [N] |
Source code in fpc/dynamics.py
98 99 100 101 102 103 104 105 | |
kinetic_energy(*, mass, velocity)
Translational kinetic energy: KE = 1/2 * m * v^2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mass
|
mass [kg] |
required | |
velocity
|
speed [m/s] |
required |
Returns:
| Type | Description |
|---|---|
|
kinetic energy [J] |
Source code in fpc/dynamics.py
107 108 109 110 111 112 113 114 | |
momentum(*, mass, velocity)
Linear momentum: p = m*v.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mass
|
mass [kg] |
required | |
velocity
|
velocity [m/s] |
required |
Returns:
| Type | Description |
|---|---|
|
momentum [kg*m/s] |
Source code in fpc/dynamics.py
116 117 118 119 120 121 122 123 | |
centripetal_acceleration(*, speed, radius)
Centripetal acceleration for circular motion: a = v^2 / r.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
speed
|
tangential speed [m/s] |
required | |
radius
|
radius of the circular path [m] |
required |
Returns:
| Type | Description |
|---|---|
|
centripetal acceleration [m/s^2] |
Source code in fpc/dynamics.py
125 126 127 128 129 130 131 132 | |
simulate_projectile_drag(*, speed, angle_deg, mass, drag_coefficient, frontal_area, air_density=1.225, gravity=GRAVITY, max_time=60.0)
Simulate 2-D projectile flight WITH quadratic air drag.
Without drag, projectile_range has a tidy formula. Add air
resistance - drag force = 1/2 * rho * Cd * A * v^2 opposing the motion -
and the equations couple the x and y motion in a way no formula solves.
This is exactly what scipy.integrate.solve_ivp is for: give it the
derivatives, the start state, and a time span, and it marches the system
forward adaptively.
We also attach an event so the integration stops the instant the projectile returns to the ground (y crosses zero going down).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
speed
|
launch speed [m/s] |
required | |
angle_deg
|
launch angle above horizontal [degrees] |
required | |
mass
|
projectile mass [kg] |
required | |
drag_coefficient
|
dimensionless drag coefficient Cd [-] |
required | |
frontal_area
|
cross-sectional area facing the flow [m^2] |
required | |
air_density
|
air density rho [kg/m^3], defaults to sea level |
1.225
|
|
gravity
|
gravitational acceleration [m/s^2] |
GRAVITY
|
|
max_time
|
safety cap on simulated time [s] |
60.0
|
Returns:
| Type | Description |
|---|---|
|
tuple of numpy arrays (time [s], x [m], y [m]) ending at impact |
Source code in fpc/dynamics.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |