Skip to content
John Hodge

← Blog

pitchphys, a baseball pitch physics simulator

Earlier this year I was at a Mariners game watching them play the Atlanta Braves, my team, and a friend and I got talking about why a curveball breaks the way it does. The answer is the Magnus effect, the sideways force on a spinning ball. I could describe it in a sentence, but I could not predict it, so I went home and built a simulator to watch it work.

pitchphys is the result: a small point-mass simulator for the flight of a thrown baseball, with a live demo that runs in the browser. You set the speed, the spin rate, and the spin axis, and it integrates the trajectory and reports the movement in the units a broadcast would use.

The Magnus effect

A baseball leaves the hand spinning. As it flies, the spinning surface drags a thin layer of air around with it, so the air moves faster on one side than the other and the wake gets deflected to one side. The ball is pushed the opposite way. That push is close to perpendicular to both the direction of travel and the spin axis, which is the cross product of the two, ω×v\boldsymbol{\omega} \times \mathbf{v}.

That sign rule is most of the story. Backspin pushes the ball up, topspin pushes it down, and sidespin pushes it left or right. A curveball is thrown with topspin, so it falls faster than gravity alone would take it. A four-seam fastball is thrown with backspin, so it falls slower than gravity alone and appears to rise, even though it is dropping the entire way to the plate.

pitchphys Magnus Explorer page: a 3D view showing the velocity vector, the spin-axis vector, and the resulting Magnus force vector from their cross product at the release point.
The Magnus Explorer draws the velocity, the spin axis, and the resulting force at release.

Three forces on a thrown ball

Once you have the Magnus force, the rest of the flight is a short physics problem. Three forces act on the ball: gravity, aerodynamic drag that opposes its motion, and the Magnus force from spin.

mdvdt=Fgravity+Fdrag+FMagnusm\,\frac{d\mathbf{v}}{dt} = \mathbf{F}_\text{gravity} + \mathbf{F}_\text{drag} + \mathbf{F}_\text{Magnus} Fgravity=mg(straight down)Fdrag=12ρCdAvv(opposes the motion)FMagnus=12ρClAv2(ω^×v^)(perpendicular to both)\begin{aligned} \mathbf{F}_\text{gravity} &= m\mathbf{g} && \text{(straight down)}\\ \mathbf{F}_\text{drag} &= -\tfrac{1}{2}\,\rho\,C_d\,A\,\lVert\mathbf{v}\rVert\,\mathbf{v} && \text{(opposes the motion)}\\ \mathbf{F}_\text{Magnus} &= \tfrac{1}{2}\,\rho\,C_l\,A\,\lVert\mathbf{v}\rVert^{2}\,(\hat{\boldsymbol{\omega}}\times\hat{\mathbf{v}}) && \text{(perpendicular to both)} \end{aligned}

Here ρ\rho is the air density, AA is the ball’s cross-sectional area, and CdC_d and ClC_l are the drag and lift coefficients. Those two coefficients are where the difficulty hides. They are not constants you can derive from first principles; they are measured in wind tunnels and change with the ball’s speed and spin. pitchphys uses published fits for them, defaulting to a measurement from Lyu et al. (2022) for drag and offering a lift model from Alan Nathan, whose published deflection table it checks itself against.

There is no clean closed-form answer, so the simulator integrates the equations numerically with scipy.integrate.solve_ivp, from the release point until the ball crosses the plate. It also lets the spin fade a little over the flight, which is a small but real effect.

pitchphys Pitch Playground page: release-condition sliders on the left for speed, spin rate, tilt, active-spin fraction, and release point, with a 3D trajectory plot and break metrics on the right.
The Pitch Playground: set the release conditions on the left, and the trajectory and break metrics update.

Which part of the spin moves the ball

The knob that surprised me most is the spin axis. Only the part of the spin that points across the direction of travel does anything. Spin that points along the direction of travel, like the spiral on a well-thrown football, produces no Magnus force at all. Pitchers call that gyro spin.

So the spin rate on a pitch tracker can mislead you. A typical major-league fastball spins around 2,200 to 2,400 rpm, but two pitches at the same rpm can move completely differently depending on how much of that spin is active (across the path) and how much is gyro (along it). The simulator makes this concrete. The spin factor S=Rω/vS = R\omega / v counts only the perpendicular part of the spin, and you can slide a pitch from pure backspin toward pure gyro and watch the break collapse toward zero while the rpm never changes.

pitchphys Active Spin / Gyro page: a plot sweeping the active-spin fraction at a fixed spin rate, showing movement decreasing as more of the spin becomes gyro spin.
Sweeping the active-spin fraction at a fixed spin rate. Movement falls off as more of the spin becomes gyro.

What the model leaves out

pitchphys is a teaching model, and it is honest about its edges. The largest omission is the seam-shifted wake: the raised seams can trip the airflow and shove the ball in a direction the spin axis alone does not predict, and on some pitches that effect rivals the Magnus force. A spin-only model like this one cannot see it.

A few smaller caveats. The drag and lift coefficients are empirical fits, so they carry the error bars of the wind-tunnel data behind them. Every baseball is treated as identical, with no seam orientation or scuffing. And the movement numbers are raw physics output. They are not calibrated against real Statcast pitches, so read them as a good approximation rather than a scouting report.

Try it

The live demo runs in the browser across five pages: build a pitch, watch the force vectors, compare a fastball with a curveball, sweep active against gyro spin, and toggle each force on and off to see what it contributes. The code is MIT-licensed Python, with tutorial notebooks if you would rather drive the model directly.

For the other half of the problem, how a pitcher decides what to throw, I wrote separately about predicting the next pitch with machine learning.

pitchphys is an independent project I build on my own time using public sources and open tooling. The views are my own and do not represent any current or former employer.

Frequently asked questions

What is the Magnus effect?

The sideways force on a spinning ball moving through air. The spin drags the nearby air around with it and deflects the wake, which pushes the ball in a direction perpendicular to both its velocity and its spin axis.

Does a fastball really rise?

No. A backspinning fastball drops less than gravity alone would pull it, so it stays higher than a spinless pitch and looks like it rises. It is still falling the whole way to the plate.

Does more spin always mean more movement?

No. Only the part of the spin that points across the direction of travel (active spin) creates Magnus force. Spin that points along the direction of travel (gyro spin) adds almost none.

What forces does pitchphys model?

Gravity, aerodynamic drag, and the Magnus force on a point mass, integrated numerically until the ball reaches the plate. The drag and lift coefficients come from published wind-tunnel fits.

What does it leave out?

Seam-shifted wake, ball-to-ball seam variation, and any calibration against real Statcast data. The aerodynamic coefficients come from wind-tunnel fits rather than from first principles.

Is it open source?

Yes. pitchphys is MIT-licensed Python on GitHub, with a Streamlit web app and tutorial notebooks.