Vendor airborne primitives from the 3d branch#295
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #295 +/- ##
==========================================
- Coverage 47.45% 47.41% -0.05%
==========================================
Files 153 153
Lines 10479 10509 +30
==========================================
+ Hits 4973 4983 +10
- Misses 5506 5526 +20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Vendor airborne primitives from the 3d branch
Summary
The next step against the 2D/3D vendoring plan. The previous PR delivered the architectural slot for 3D —
SimulationEngine.is_3d,Dimcapability declarations on every strategy,EventDetectoras a peer toResolver. This stage vendors the prerequisite primitives from the3dbranch: the airborne motion state, the BALL_TABLE event type, and airborne equations of motion.No simulation behavior changes. The constants and event types exist as enum members, an airborne ball has well-defined parabolic evolution under gravity, but nothing in this PR wires these into resolution or detection. The default 2D simulation is byte-identical to before.
What's in this PR
New motion state (
pooltool/constants.py):airborne: int = 5motion statestate_dictand to theenergeticseton_tableandnontranslatingleft alone — airborne is correctly excluded from bothNew event type (
pooltool/events/):EventType.BALL_TABLEindatatypes.py+ entries inis_collision()/has_ball()ball_table_collision(ball, time, set_initial=False)factory infactory.pyEventType.BALL_TABLE: {0}registry entry inutils.py::event_type_to_ball_indicesball_table_collisionfromevents/__init__.pyAirborne kinematics (
pooltool/physics/):get_airborne_time(rvw, R, g)inphysics/utils.py— time until an airborne ball's bottom intersects the table plane. Routes through the existingpooltool.ptmath.roots.quadratic.solverather than inlining the quadratic-solver math (a small departure from the strict-vendor path; see "What's not in this PR" below)._evolve_airborne_state(rvw, g, t)inphysics/evolve/__init__.py— parabolic position, linear velocity, conserved angular velocity. Verbatim from the 3d branch.evolve_ball_motionforstate == const.airborne. Airborne does not cascade to another state on a timer — it only transitions via BALL_TABLE collision, which Stage 3 wires up.get_airborne_timere-exported frompooltool/physics/__init__.py.Tests:
tests/physics/evolve/test_airborne.py— five tests covering xy-velocity conservation, angular velocity conservation, linear xy-displacement, gravity direction, parabolic z. Ported byte-identical from the3dbranch viagit show.tests/physics/test_utils.pyextended with a parametrizedtest_get_airborne_time(zero gravity → ∞, drop from apex, xy-velocity independence, ball at z=R with downward v_z → 0).What's NOT in this PR (and shouldn't be)
pooltool/physics/resolve/ball_table/resolver package — Stage 3BallTableDetectionstrategy — Stage 3Dim.THREE-tagged strategies — Stage 4on_table(rvw, R)predicate function (the 3d branch adds this inphysics/utils.py, but it's only used by airborne-aware code; defer to Stage 3)ball_cushion/ball_pocket/stick_ballresolvers that produce vz — Stage 4Vendor faithfulness
Three function bodies were re-typed from the 3d branch rather than piped —
_evolve_airborne_state,ball_table_collision, and the function-body ofget_airborne_time(before its quadratic-solver refactor). All three were verified byte-faithful via AST comparison after stripping docstrings (the function bodies proved to be identical to the 3d source). The test filetest_airborne.pywas piped directly viagit show 3d:... > pathand is byte-identical by construction.