The trajectory
RK4 · velocity VerletSolid navy is the integrated flight; the faint navy continuation is the rest of the solved trajectory, so a paused page still shows the whole arc. The dashed grey curve is the vacuum parabola launched from the identical initial condition — the gap between the two curves is the entire lesson. The orange arrow is the velocity vector, scaled to a fixed screen length. Both axes are in metres and share one scale, so the shape you see is the shape the projectile flies. The dots on the two curves are stamped at the same time interval: on the vacuum ghost their horizontal spacing is exactly constant, because nothing acts horizontally there, while on the integrated curve they bunch together as drag eats vx. That difference in spacing is the drag force, drawn rather than tabulated.
The pale blue curve is the integrated trail; the dashed orange curve is the analytic conic section r(ν) = (h²/μ) / (1 + e cos ν) built from the orbital elements measured this instant. If the integrator were drifting, the two would separate. The central body is drawn to the same scale as the orbit, so a low orbit really does hug the surface. Periapsis and apoapsis are marked with their altitudes.
- Integrated path (with drag)
- Vacuum parabola (analytic)
- Apex
- Impact
- Equal-time marks on both curves
- Integrated trail (velocity Verlet)
- Analytic conic of the current elements
- Periapsis
- Apoapsis
Where it is now
Outcome of the flight — measured against the vacuum closed form
The object, the air, and the first law
Where it is now
Orbital elements — computed live from r and v
Conservation check — what velocity Verlet buys you
Measurements
Energy ledger — kinetic + potential + dissipated
- Kinetic ½m|v|²
- + potential mgy
- + dissipated ∫ ½ρCdA|v|³ dt
- Initial total E₀
Speed against time, with the terminal-velocity asymptote
- |v(t)|
- vₜ = √(2mg / ρCdA)
Range against launch angle — where the optimum actually is
- With drag (one integrated flight per plotted angle)
- Vacuum, R = v₀² sin 2θ / g
- Your current θ
Conservation check — drift of ε and h
- Δε / |ε₀|
- Δh / h₀
Orbital radius against time
- r(t) / R
- Periapsis a(1−e)
- Apoapsis a(1+e)
Vis-viva — speed against radius
- Integrated states
- v = √(μ(2/r − 1/a₀))
The physics
Ballistic flight with quadratic drag
- The drag force is quadratic in speed and directed exactly opposite the velocity — the |v|v product carries both facts at once. This is the high-Reynolds-number (inertial) regime, not Stokes drag.
- vt is the only speed the object has: the dimensionless group v₀²/vt² is the ratio of the drag force at launch to the weight, and it — not the mass alone — decides how badly the parabola fails.
- The integrand is the drag power −FD·v, which is positive definite: drag can only take energy out. The three terms are the three stacked bands in the first plot.
- Drag is non-conservative, so there is no symplectic structure worth protecting — what matters is local truncation error, and RK4 gives O(h⁴). With drag switched off RK4 reproduces constant acceleration exactly, which is why the vacuum comparison agrees to roundoff instead of to the step size.
- Impact and apex are found by 60 bisections of the RK4 flow map, not by taking the nearest grid point — a grid-point range would be wrong by up to vxh.
Two-body orbital motion
- Only the product GM enters, and μ is known far more precisely than G and M separately — 3.986004418 × 10¹⁴ m³·s⁻² for Earth, good to nine figures, against six for G.
- ε < 0 gives an ellipse, ε = 0 a parabola, ε > 0 a hyperbola. The period exists only in the first case, which is why the readout says "hyperbolic / escape" rather than printing a number.
- Setting a = r gives the circular speed √(μ/r); letting a → ∞ gives the escape speed √(2μ/r). At the Earth's surface those are 7.910 and 11.186 km·s⁻¹.
- Checked live here against the semi-major axis measured at t = 0 — so the residual is a statement about the integrator, not an algebraic identity.
- Symplectic and time-reversible, so the energy error is bounded and oscillatory rather than secular. Plain RK4 on the same orbit loses energy monotonically: the orbit spirals in at a rate proportional to h⁴, which is small, invisible over one orbit, and fatal over a thousand.
- The step is set from the periapsis timescale √(rp³/μ) / 1024, not the mean one, because an eccentric orbit does all its hard accelerating at the bottom.
What to try
- Confirm the numerics before believing anything else. Baseball preset, θ = 40°, v₀ = 45 m/s, h₀ = 0, and turn drag off. Expected: the navy curve disappears underneath the dashed ghost, and range, apex and flight time read 203.36 m, 42.66 m and 5.899 s — the closed forms to every digit shown. The first-law residual reads zero to about 10⁻¹³. Only now is the drag comparison worth anything.
- Turn drag back on and watch half the range vanish. Same launch. Expected: 110.2 m instead of 203.4 m — 54 % of the vacuum answer — the apex drops from 42.7 m to 29.7 m, and the flight lands 1.0 s early. The impact speed is 26.1 m/s against a launch speed of 45, and the impact angle is 54° rather than the symmetric 40°: the descent is always steeper than the ascent, because drag has eaten the horizontal component that the parabola assumed was constant. The energy ledger says 66 % of the launch energy ended up in the air.
- Show that it is not about mass — it is about v₀²/vt². Hold v₀ = 45 m/s and θ = 40° fixed and step through the objects. Expected: cannonball 190.2 m (93.5 % of vacuum, drag number 0.10), 9 mm bullet 167.6 m (82 %), golf ball 123.1 m (61 %), baseball 110.2 m (54 %), ping-pong ball 16.5 m (8.1 %, drag number 26.5). The ping-pong ball and the cannonball are the same size to within a factor of three (40 mm against 120 mm) and a factor of 97 in density (81 against 7847 kg·m⁻³) — but what actually separates their flights is the factor of 280 in the drag number, 26.5 against 0.095. Mass alone is the wrong variable to reach for: the 8 g bullet has a smaller drag number than the 46 g golf ball.
- Drop something and measure its terminal velocity. Skydiver preset (that sets v₀ = 0, h₀ = 4000 m), press Play at 10×. Expected: the speed curve rises and flattens onto the dashed asymptote at 50.61 m/s — 182 km/h, the textbook belly-to-earth figure — reaching 99.99 % of it about 30 s in. Switch to the ping-pong ball and its terminal velocity is 8.74 m/s; switch to the cannonball and it is 146 m/s and still climbing after a kilometre of fall. The number the page prints is √(2mg/ρCdA), computed independently of the integration.
- Find the optimal launch angle, and be surprised. Watch the third plot for each preset (press "Re-run the angle sweep" if you have been dragging sliders). The Skydiver is the exception: it launches from rest, so there is no launch angle to optimise and the plot and readout say so rather than inventing one. Expected: the vacuum curve always peaks at exactly 45°, and the drag curve never does — baseball 40.2°, cannonball 37.4°, ping-pong ball 33.4°, 9 mm bullet 30.2°. Those four are each at that preset's own launch speed, which is why they are not ordered by mass or by density: the cannonball is the heaviest and densest object on the page and still sits further from 45° than the baseball, because it is fired at 250 m/s rather than 45. The controlling group is the drag number. Hold v₀ = 45 m/s and h₀ = 0 and step through the presets and the trend is clean and monotonic — ping-pong 29.1°, baseball 40.2°, golf 41.0°, skydiver 41.6°, 9 mm 43.4°, cannonball 44.5°, against drag numbers 26.5, 1.31, 0.99, 0.79, 0.30, 0.095. The smaller v₀²/vt², the closer the optimum creeps back toward 45°. Every artillery table ever printed encodes this, and it is why gunners do not simply fire at 45°.
- Fly the same baseball at altitude. Leave drag on and pull ρ down from 1.225 to 0.736 kg·m⁻³ — the readout will tell you that is ISA 5.00 km. Expected: the range grows from 110.2 m to 132.9 m, 21 % further, purely because there is less air. Take ρ to 0.414 (ISA 9.97 km) and it reaches 155.3 m. This is the entire reason ballparks at altitude play as hitters' parks.
- Switch to Orbital and check that a circle stays a circle. Earth, r₀ = 1.06 R⊕, press Circular, play at one orbit per two seconds and leave it for a minute. Expected: e never rises above about 5 × 10⁻⁷, the radius plot is a dead-flat line (the whole 10-orbit run spans 3 m out of 6753 km), the measured period agrees with 2π√(a³/μ) = 5523.1 s = 92.05 min to three parts in ten million, and the two drift readouts sit at 2 × 10⁻¹¹ % and 1 × 10⁻¹² %. Now push the speed to 1.2 × vcirc: e = 0.440, the period stretches to 3.661 h, the radius trace oscillates between the two reference lines and touches each one exactly, and the energy drift is still only 3 × 10⁻⁵ %.
- Escape, exactly. Press the Escape button. Expected: at t = 0, ε reads exactly zero, e reads 1.000000, the semi-major axis reads ∞ and the conic ghost opens into a parabola that never returns. Now play it, and watch the axis stop reading ∞ — that is the point of the exercise, not a fault. a = −μ/2ε is infinitely sensitive at ε = 0, so once Verlet's bounded energy wobble puts ε a part in 10⁷ off zero, a lands on some enormous finite number of either sign. A parabola is a measure-zero condition and no integrator can sit on it; the panel keeps calling the state parabolic while |e − 1| < 10⁻⁶ precisely because a alone cannot be trusted there. Nudge the speed slider down by one notch and it snaps back to a very long ellipse; nudge it up and it becomes a hyperbola with a genuine excess speed. The boundary between "comes back" and "does not" is a single number, and the page lets you start exactly on it.
- Break the orbit deliberately. Set the flight-path angle to −30° and leave the speed at circular. Expected: the speed is exactly right and the orbit is still ruined — e jumps from 0 to 0.500, the apse line rotates, periapsis falls to 3377 km, which is 2994 km below the surface, and the status bar reports an impact 98 s in, less than 2 % of the way round. Orbit insertion is a vector problem; getting the magnitude right is only half of it.
The six objects, as configured
| Object | m (kg) | Cd | A (m²) | vt (m/s) | Note |
|---|---|---|---|---|---|
| Baseball | 0.145 | 0.35 | 4.30 × 10⁻³ | 39.3 | 74.0 mm equivalent diameter, inside MLB spec |
| Golf ball | 0.0459 | 0.25 | 1.43 × 10⁻³ | 45.3 | 42.7 mm; dimples hold the boundary layer attached |
| Cannonball | 7.10 | 0.47 | 1.13 × 10⁻² | 146.2 | 120 mm solid cast iron |
| 9 mm bullet | 0.00804 | 0.30 | 6.39 × 10⁻⁵ | 82.0 | 124 gr FMJ; constant Cd is a crude stand-in — see below |
| Ping-pong ball | 0.0027 | 0.45 | 1.26 × 10⁻³ | 8.74 | 40 mm; the lowest-density projectile in common use |
| Skydiver | 80 | 1.00 | 0.50 | 50.6 | belly to earth; CdA is a body, not a sphere |
Assumptions and limits
- Point mass, two dimensions, no rotation. There is no lift, no Magnus force and no spin. That is a serious omission for exactly the objects people care about: a backspinning golf drive carries roughly twice as far as this model predicts, and a curveball would fly straight here. Adding lift means adding a CL and a spin vector, and the trajectory stops being planar.
- Cd is constant. In reality it is a function of Reynolds number and Mach number. A smooth sphere goes through the drag crisis near Re ≈ 3 × 10⁵, where Cd falls abruptly from about 0.47 to about 0.1 — for a baseball that is right in the middle of the working speed range. A bullet's Cd more than doubles through the transonic region. Both are outside this model, and the 9 mm preset in particular should be read as "an object with that drag number", not as exterior ballistics.
- Uniform, still air of constant density. No wind, no shear, no humidity, and — importantly — no variation of ρ with height. The ρ control is a global density, so a 12 km drop happens entirely in sea-level air unless you say otherwise. Real ISA density falls by a factor of 3.8 over that climb, and a real long-range ballistic solution integrates ρ(y) along the path.
- Flat, non-rotating ground and constant g. No Coriolis deflection (which a rifle shot at 1000 m genuinely feels), no Eötvös effect, and no 1/r² weakening of gravity. At these ranges all three are far smaller than the drag modelling error.
- Impact is a stop, not a collision. The projectile is deleted at y = 0. There is no bounce, no roll, no penetration — the "range" is the first ground contact, which is not what a golfer means by carry plus roll.
- Two bodies only, both point masses. The orbital model has no J₂ oblateness term, no third-body perturbation from the Moon or Sun, no solar radiation pressure and no atmospheric drag. A real 382 km orbit decays: the ISS loses about 2 km a month and needs periodic reboosts. Nothing here decays, by construction.
- The central body is fixed. The satellite is treated as massless. That is excellent for a spacecraft about the Earth, adequate for the Moon about the Earth (the barycentre is 1700 km below the Earth's surface), and wrong for a genuine comparable-mass binary.
- Motion is planar. Real orbits need three more elements — inclination, right ascension of the ascending node and argument of periapsis. Everything on this page is the in-plane subset.
- Fixed step, so the eccentric cases cost the most. Verlet must not be given an adaptive step — varying h destroys the symplectic property that the whole conservation argument rests on. The step is therefore sized for periapsis and used everywhere, which is why a very eccentric orbit takes many more substeps per revolution.
- One fixed RK4 grid per flight, and it can be beaten. The step is sized from the flight duration and then capped at a tenth of the drag time constant 1/(k·max(v₀,vt)), which covers every realistic object. The vt half of that maximum is not decoration: a drop from rest has v₀ = 0, and 1/(k·v₀) alone would be no cap at all. Push the sliders to a gram of mass behind two square metres of area at 500 m/s and the drag transient falls to microseconds while the flight still lasts a twentieth of a second — more substeps than the solver will store. It then coarsens the grid to fit, the first-law residual blows up, and the page says so in a banner instead of plotting the nonsense. That is what a conservation check is for: it is the only thing on the page that can catch the page being wrong.
- The angle sweep is held to the same standard, separately. The ninety-odd flights behind the third plot store no history, so — unlike the main flight — they are free to vary their step, and they tighten it to a tenth of the local drag time constant wherever the transient demands it. Quadratic drag is stiff for the few dozen steps it takes a body to decay to terminal speed and is not stiff at all afterwards, so varying h costs about a hundred steps a flight where a uniform grid would cost forty thousand. Every sweep flight carries the same dissipated-energy state as the main one and the worst residual over the whole sweep is checked against the same 0.1 % bar: if it fails, or a flight does not land, or the sweep would cost more integration than it is allowed, the optimal angle and the navy curve are withheld and the banner says which. A conservation check that only covers half the page is not a conservation check.
- Numbers are only as good as the inputs. The drag coefficients here are representative textbook values, not measurements of any particular object. Treat the trends as exact and the absolute ranges as ±10 %.
Why an engineer should care
The dimensionless group on this page — v₀²/vt², the ratio of aerodynamic force to weight — is the same one that sizes a parachute, sets the settling velocity in a gravity separator, and decides whether a particle in a duct is carried along or drops out. Terminal velocity is a design quantity, not a curiosity: cyclone separators, spray dryers, sedimentation basins and pneumatic conveying lines are all specified by balancing exactly this ½ρCdAv² against a body force, and the reason the drag law is quadratic rather than linear is the reason those machines have the sizes they do. The orbital half is the same story one length scale up: vis-viva is what turns a mission requirement into a Δv budget, and a Δv budget into a propellant mass through the rocket equation. In both halves the useful engineering skill is the one this page is built to teach — knowing which closed form applies, and how far the real answer sits from it.
The numerical lesson generalises past both. An integrator is not a neutral tool: RK4 is the right answer for a dissipative system where local accuracy is everything, and the wrong answer for a conservative one that has to run for a million steps, where a scheme that respects the geometry beats a scheme with a smaller local error. That trade — accuracy per step against structure preserved over the long run — recurs in every transient simulation an engineer will ever set up, and the drift plot on this page is the cheapest way to see it.