Skip to content

Cl Hill form is monotonic, so it cannot represent the measured lift peak near S~0.5 #230

Description

@cvrt-jh

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:

  1. 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)".

  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions