-
Notifications
You must be signed in to change notification settings - Fork 80
3D stick-ball resolver + a partially functional 3D playground #300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+217
−34
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| #! /usr/bin/env python | ||
| """Demos 3D trajectory (work in progress) | ||
|
|
||
| Usage: | ||
| python sandbox/airborne_demos.py --name drop | ||
| """ | ||
|
|
||
| import argparse | ||
|
|
||
| import attrs | ||
|
|
||
| from pooltool import constants as const | ||
| from pooltool.evolution.engine import SimulationEngine | ||
| from pooltool.evolution.event_based.simulate import simulate | ||
| from pooltool.interact import show | ||
| from pooltool.objects.ball.datatypes import Ball | ||
| from pooltool.objects.cue.datatypes import Cue | ||
| from pooltool.objects.table.datatypes import Table | ||
| from pooltool.physics.dimensionality import Dim | ||
| from pooltool.physics.resolve.resolver import Resolver | ||
| from pooltool.physics.resolve.stick_ball.instantaneous_point import ( | ||
| InstantaneousPoint3D, | ||
| ) | ||
| from pooltool.system.datatypes import System | ||
|
|
||
|
|
||
| def _build_3d_engine() -> SimulationEngine: | ||
| """Build a SimulationEngine with ``is_3d=True``. | ||
|
|
||
| Every resolver strategy that carries a ``dim`` tag is patched to | ||
| ``Dim.BOTH`` so the engine constructs; the stick-ball strategy is | ||
| swapped to ``InstantaneousPoint3D`` so cue elevation produces real | ||
| vertical velocity. | ||
| """ | ||
| # Patches all defaults to dim.BOTH so the engine constructs | ||
| resolver = Resolver.default() | ||
| for field in attrs.fields(type(resolver)): | ||
| strategy = getattr(resolver, field.name) | ||
| if hasattr(strategy, "dim"): | ||
| strategy.dim = Dim.BOTH | ||
|
|
||
| # Replace all working 3D resolvers | ||
| resolver.stick_ball = InstantaneousPoint3D() | ||
|
|
||
| return SimulationEngine(resolver=resolver, is_3d=True) | ||
|
|
||
|
|
||
| def _empty_cue() -> Cue: | ||
| """A cue with ``V0=0`` so the simulator doesn't fire a stick strike at t=0. | ||
|
|
||
| The default ``Cue`` constructor sets ``V0=2.0``; the stick-ball detector | ||
| fires whenever ``V0 > 0`` and ``_system_has_energy`` reports false. For | ||
| a ball that's airborne but momentarily at apex (vz=0), kinetic energy is | ||
| zero and the detector would trigger a strike on the handcrafted state. | ||
| Explicitly zero V0 to suppress that. | ||
|
|
||
| TODO: Fix underlying problem in codebase | ||
| """ | ||
| cue = Cue(cue_ball_id="cue") | ||
| cue.V0 = 0 | ||
| return cue | ||
|
|
||
|
|
||
| def drop() -> System: | ||
| """Ball dropped from 0.3 m with a small horizontal nudge in +x.""" | ||
| ball = Ball.create("cue", xy=(0.5, 0.5)) | ||
| ball.state.rvw[0, 2] = 0.3 | ||
| ball.state.rvw[1, 0] = 0.5 | ||
| ball.state.s = const.airborne | ||
|
|
||
| return System( | ||
| cue=_empty_cue(), | ||
| table=Table.default(), | ||
| balls=(ball,), | ||
| ) | ||
|
|
||
|
|
||
| def impulse_into() -> System: | ||
| """Strong downward strike with a small horizontal nudge in +y.""" | ||
| ball = Ball.create("cue", xy=(0.5, 0.5)) | ||
| ball.state.rvw[1, 1] = 0.5 | ||
| ball.state.rvw[1, 2] = -5.0 | ||
| ball.state.s = const.airborne | ||
|
|
||
| return System( | ||
| cue=_empty_cue(), | ||
| table=Table.default(), | ||
| balls=(ball,), | ||
| ) | ||
|
|
||
|
|
||
| def jump() -> System: | ||
| """A genuine jump shot — cue strike at 60° elevation produces vz via the 3D resolver. | ||
|
|
||
| No handcrafted ``rvw`` here: the cue strikes a ball at rest on the table | ||
| surface, and ``InstantaneousPoint3D`` lifts it off via ``v·sin(theta)``. | ||
| """ | ||
| ball = Ball.create("cue", xy=(0.5, 0.5)) | ||
| cue = Cue(cue_ball_id="cue") | ||
| cue.set_state(V0=2.0, phi=90.0, theta=60.0, a=0.0, b=0.0) | ||
|
|
||
| return System( | ||
| cue=cue, | ||
| table=Table.default(), | ||
| balls=(ball,), | ||
| ) | ||
|
|
||
|
|
||
| _map = { | ||
| "drop": drop, | ||
| "impulse_into": impulse_into, | ||
| "jump": jump, | ||
| } | ||
|
|
||
|
|
||
| def main(name: str) -> None: | ||
| engine = _build_3d_engine() | ||
| shot = _map[name]() | ||
| simulate(shot, engine=engine, inplace=True) | ||
| show(shot) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| ap = argparse.ArgumentParser("Airborne ball demos in 3D mode.") | ||
| ap.add_argument("--name", choices=list(_map.keys()) + ["all"], required=True) | ||
| args = ap.parse_args() | ||
|
|
||
| if args.name == "all": | ||
| for name in _map: | ||
| print(f"Running {name}...") | ||
| main(name) | ||
| else: | ||
| main(args.name) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Floating-point equality check is unreliable for classifying motion state.
rvw[1, 2] != 0.0will fail for near-zero values arising from floating-point arithmetic (e.g.,sin(0)producing~1e-16). Balls intended to be sliding could be misclassified as airborne.Use a tolerance-based check instead:
Proposed fix
Additionally, the parameter
Ris declared but never used in the function body. If it's reserved for future use (e.g., checking if z-position > R), consider removing it until needed, or add a comment explaining the intent.🤖 Prompt for AI Agents