Description
Split out of #218 / #229 so it doesn't expand that PR.
ballistics.py models lift as a saturating Hill function:
CL_SATURATION = 0.32
CL_HALF_SP = 0.15
# Cl = CL_SATURATION * Sp / (CL_HALF_SP + Sp)
That form is monotonic increasing and asymptotically flat. Measured golf-ball Cl is not: it rises, peaks around spin ratio S ≈ 0.5, then falls. So above roughly S ≈ 0.35 no choice of the two constants can match reality — the shape is wrong, not the numbers.
This is measurable on the capture already in the repo. Same 24 shots, same RK4 integrator, same resolve_launch/simulate path — the only thing changed is the Cd/Cl functional form, each fitted to its own optimum:
| form |
OVERALL |
driver |
7-iron |
pitching wedge |
current: Cd = a+bS, Cl = c·S/(d+S) (4 param) |
3.97 |
1.75 |
2.96 |
6.26 |
quadratic: Cd = a+bS+cS², Cl = d+eS+fS² (6 param) |
1.99 |
1.07 |
0.98 |
3.33 |
Roughly half the overall error, and it nearly halves the wedge column — which is exactly where #229 stays weak. Wedges in that capture sit at Sp 0.376-0.632, i.e. right where the Hill form flattens but real Cl is peaking and turning over.
Two independent reasons to think the quadratic is the right shape rather than just more parameters:
-
Published models use it. Ferguson, McNally & McPhee (2022, ISEA 14, open access) fit exactly Cd = a+bS+cS², Cl = d+eS+fS² to N = 1040 shots (GCQuad launch conditions + FlightScope X3 carry/apex/offline, Titleist Pro V1, S = 0.02-0.75) and report 2.51 m / 2.74 yd carry MAE. Quintavalla (2002) and Smits & Smith (1994) are the other standard references, both non-monotonic in S. Lyu/Kensrud/Smith (2018, ISEA) also state outright that lift "had a non-linear dependence on spin (fit with a 2nd order polynomial)".
-
Fitting it here reproduces their constants. Fitted to our 24 shots the quadratic gives [0.1346, 0.9438, -0.7351, 0.0548, 1.2258, -0.9196], against their published [0.1304, 0.9287, -0.8259, 0.0504, 1.2031, -1.1490] from 1040 shots. Two independent datasets converging on nearly the same coefficients is decent evidence the form is right and the fit isn't noise.
What did you expect to happen?
Not necessarily a change — mainly a decision, since it's architectural and I'd rather ask than assume.
Option A — switch Cl/Cd to 2nd-order polynomials in S. Better accuracy, aligns with the literature the file already cites, keeps everything else (RK4, Magnus geometry, spin decay) untouched. Costs: 4 constants become 6, and Cl must be clamped at >= 0 since a downward parabola eventually goes negative outside the fitted range.
Option B — leave it. Defensible if you'd rather not widen the parameter count on 24 shots of ground truth, and the current form is fine for driver/iron Sp.
Related structural gaps I noticed while looking, listed only so they're on the record — not proposing to fix them here:
- No Reynolds-number dependence anywhere (
grep -ci reynolds ballistics.py = 0). Ferguson, Quintavalla and Smits & Smith all include it; Lyu et al. measured Cd falling 0.5 -> 0.2 across the drag crisis. Cd = f(S) alone conflates speed and spin.
- No moment coefficient. Spin decay is a fixed 4%/s exponential rather than aerodynamic; Ferguson fits
C_M = g·S.
- Spin axis is constant through flight — no precession. Fine for carry, matters for curve.
Happy to implement whichever you prefer, or to leave it as a documented limitation. Worth noting these need refitting together if #169 (altitude air density) lands, since air density and the coefficients trade off against each other.
Area
Ballistics / physics model
Description
Split out of #218 / #229 so it doesn't expand that PR.
ballistics.pymodels lift as a saturating Hill function:That form is monotonic increasing and asymptotically flat. Measured golf-ball
Clis not: it rises, peaks around spin ratio S ≈ 0.5, then falls. So above roughly S ≈ 0.35 no choice of the two constants can match reality — the shape is wrong, not the numbers.This is measurable on the capture already in the repo. Same 24 shots, same RK4 integrator, same
resolve_launch/simulatepath — the only thing changed is theCd/Clfunctional form, each fitted to its own optimum:Cd = a+bS,Cl = c·S/(d+S)(4 param)Cd = a+bS+cS²,Cl = d+eS+fS²(6 param)Roughly half the overall error, and it nearly halves the wedge column — which is exactly where #229 stays weak. Wedges in that capture sit at
Sp0.376-0.632, i.e. right where the Hill form flattens but realClis peaking and turning over.Two independent reasons to think the quadratic is the right shape rather than just more parameters:
Published models use it. Ferguson, McNally & McPhee (2022, ISEA 14, open access) fit exactly
Cd = a+bS+cS²,Cl = d+eS+fS²to N = 1040 shots (GCQuad launch conditions + FlightScope X3 carry/apex/offline, Titleist Pro V1, S = 0.02-0.75) and report 2.51 m / 2.74 yd carry MAE. Quintavalla (2002) and Smits & Smith (1994) are the other standard references, both non-monotonic in S. Lyu/Kensrud/Smith (2018, ISEA) also state outright that lift "had a non-linear dependence on spin (fit with a 2nd order polynomial)".Fitting it here reproduces their constants. Fitted to our 24 shots the quadratic gives
[0.1346, 0.9438, -0.7351, 0.0548, 1.2258, -0.9196], against their published[0.1304, 0.9287, -0.8259, 0.0504, 1.2031, -1.1490]from 1040 shots. Two independent datasets converging on nearly the same coefficients is decent evidence the form is right and the fit isn't noise.What did you expect to happen?
Not necessarily a change — mainly a decision, since it's architectural and I'd rather ask than assume.
Option A — switch
Cl/Cdto 2nd-order polynomials in S. Better accuracy, aligns with the literature the file already cites, keeps everything else (RK4, Magnus geometry, spin decay) untouched. Costs: 4 constants become 6, andClmust be clamped at>= 0since a downward parabola eventually goes negative outside the fitted range.Option B — leave it. Defensible if you'd rather not widen the parameter count on 24 shots of ground truth, and the current form is fine for driver/iron
Sp.Related structural gaps I noticed while looking, listed only so they're on the record — not proposing to fix them here:
grep -ci reynolds ballistics.py= 0). Ferguson, Quintavalla and Smits & Smith all include it; Lyu et al. measuredCdfalling 0.5 -> 0.2 across the drag crisis.Cd = f(S)alone conflates speed and spin.C_M = g·S.Happy to implement whichever you prefer, or to leave it as a documented limitation. Worth noting these need refitting together if #169 (altitude air density) lands, since air density and the coefficients trade off against each other.
Area
Ballistics / physics model