pooltool.physics.resolve.ball_pocket#

Defining and handling ball pocket collisions#

Note

If this module is ever extended to support multiple treatments for ball pocket collisions, expand this file into a file structure modelled after ../ball_ball or ../ball_cushion

Overview#

Classes#

Ball

A billiards ball

BallState

Holds a ball’s state

Pocket

A circular pocket

StrEnum

Enum where members are also (and must be) strings

BallPocketStrategy

Ball-pocket collision models must satisfy this protocol

BallPocketModel

An Enum for different ball-pocket collision models

Function#

get_ball_pocket_model(model, params)

Returns a ball-pocket collision model

Attributes#

ModelArgs

A mapping of argument names to argument values

Classes#

class pooltool.physics.resolve.ball_pocket.Ball(id: str, state: BallState = BallState.default, params: BallParams = BallParams.default, ballset: BallSet | None = None, initial_orientation: BallOrientation = BallOrientation.random, history: BallHistory = BallHistory.factory, history_cts: BallHistory = BallHistory.factory)[source]#

A billiards ball

This class represents a billiards ball. It stores its parameters (mass, radius, etc.), it’s state (coordinates, velocity, spin, etc), its history (a time-resolved trajectory of its state), amongst other things.

id#

An ID for the ball.

Use strings (e.g. “1” not 1).

Type:

str

state#

The ball’s state.

This is the current state of the ball.

See also

  • See the Important section in Ball for a description of the role of states during simulation.

Type:

pooltool.objects.ball.datatypes.BallState

params#

The ball’s physical parameters.

The physical parameters of the ball.

Type:

pooltool.objects.ball.params.BallParams

ballset#

The ball set that the ball belongs to.

Important if rendering the ball in a scene.

See also

Type:

pooltool.objects.ball.sets.BallSet | None

initial_orientation#

The initial rendered orientation of the ball.

Important if rendering the ball in a scene.

This is the orientation of the ball at \(t = 0\).

Type:

pooltool.objects.ball.datatypes.BallOrientation

history#

The ball’s state history

The historical states of the ball from \(t_{initial}\) to \(t_{final}\).

See also

  • See the Important section in Ball for a description of the role of history during simulation.

Type:

pooltool.objects.ball.datatypes.BallHistory

history_cts#

The ball’s continuous state history

The historical states of the ball from \(t_{initial}\) to \(t_{final}\) densely sampled with respect to time.

See also

  • See pooltool.evolution.event_based.continuize.continuize() for a details about continuizing a simulated system.

  • See the Important section in Ball for a description of the role of history_cts during simulation.

Type:

pooltool.objects.ball.datatypes.BallHistory

Important

To instantiate this class, consider using the create() constructor. Or, use functions within pooltool.layouts to generate entire collection of balls. Or, of course, construct as normal with __init__.

Important

The following explains how a Ball object is modified when its parent system is simulated (pooltool.evolution.event_based.simulate.simulate()).

At the start of the simulation process, state represents the ball state at \(t = 0\). A copy of state is appended to history.

For each timestep of the simulation, state is used to inform how the system should advance forward in time. Once determined, state is updated to reflect the ball’s new state. A copy of state is appended to history.

When the simulation is finished, state represents the final resting state of the ball. So too does history[-1].

Finally, if the system is continuized (see pooltool.evolution.continuize.continuize()), history_cts is populated. Otherwise it remains empty.

property xyz#

The displacement (from origin) vector of the ball.

A shortcut for self.state.rvw[0].

property vel#

The velocity vector of the ball.

A shortcut for self.state.rvw[1].

property avel#

The angular velocity vector of the ball.

A shortcut for self.state.rvw[2].

Methods:

set_ballset(ballset: pooltool.objects.ball.sets.BallSet) None[source]#

Update the ballset

Raises:

ValueError -- If the ball ID doesn’t match to a model name of the ballset.

See also

copy(drop_history: bool = False) Ball[source]#

Create a copy

Parameters:

drop_history (bool) -- If True, the returned copy history and history_cts attributes are both set to empty BallHistory objects.

Return type:

Ball

static create(id: str, *, xy: Sequence[float] | None = None, ballset: pooltool.objects.ball.sets.BallSet | None = None, **kwargs) Ball[source]#

Create a ball using keyword arguments.

This constructor flattens the tunable parameter space, allowing one to construct a Ball without directly instancing objects like like pooltool.objects.balls.params.BallParams and BallState.

Parameters:
  • xy (Optional[Sequence[float]]) -- The x and y coordinates of the ball position.

  • ballset (Optional[pooltool.objects.ball.sets.BallSet]) -- A ballset.

  • **kwargs -- Arguments accepted by pooltool.objects.balls.params.BallParams

Return type:

Ball

class pooltool.physics.resolve.ball_pocket.BallState(rvw: ndarray[Any, dtype[float64]], s, t=0)[source]#

Holds a ball’s state

The ball’s state is defined (1) the kinematic state of the ball, (2) a label specifying the ball’s motion state, and (3) the point in time that the ball exists in.

rvw#

The kinematic state of the ball.

rvw is a \(3\times3\) matrix that stores the 3 vectors that characterize a ball’s kinematic state:

  1. \(r\): The displacement (from origin) vector (accessed with rvw[0])

  2. \(v\): The velocity vector (accessed with rvw[1])

  3. \(w\): The angular velocity vector (accessed with rvw[2])

Type:

numpy.ndarray[Any, numpy.dtype[numpy.float64]]

s#

The motion state label of the ball.

s is an integer corresponding to the following motion state labels:

0 = stationary
1 = spinning
2 = sliding
3 = rolling
4 = pocketed
Type:

int

t#

The simulated time.

Type:

float

Methods:

copy() BallState[source]#

Create a copy

Return type:

BallState

static default() BallState[source]#

Construct a default BallState

Returns:

A valid yet undercooked state.

>>> import pooltool as pt
>>> pt.objects.BallState.default()
BallState(rvw=array([[nan, nan, nan],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]]), s=0, t=0.0)

Return type:

BallState

class pooltool.physics.resolve.ball_pocket.Pocket(id: str, center: ndarray[Any, dtype[float64]], radius: float, depth: float = 0.08, contains: set = UNKNOWN)[source]#

A circular pocket

id#

The ID of the pocket.

Type:

str

center#

A length-3 array specifying the pocket’s position.

  • center[0] is the x-coordinate of the pocket’s center

  • center[1] is the y-coordinate of the pocket’s center

  • center[2] must be 0.0

Type:

numpy.ndarray[Any, numpy.dtype[numpy.float64]]

radius#

The radius of the pocket.

Type:

float

depth#

How deep the pocket is.

Type:

float

contains#

Stores the ball IDs of pocketed balls (default = set()).

Type:

set

Methods:

a() float#

The x-coordinate of the pocket’s center

Cached Property Note

This is a cached property, and should be accessed as an attribute, not as a method call.

Return type:

float

b() float#

The y-coordinate of the pocket’s center

Cached Property Note

This is a cached property, and should be accessed as an attribute, not as a method call.

Return type:

float

add(ball_id: str) None[source]#

Add a ball ID to contains

remove(ball_id: str) None[source]#

Remove a ball ID from contains

copy() Pocket[source]#

Create a copy

Return type:

Pocket

class pooltool.physics.resolve.ball_pocket.StrEnum(value)[source]#

Enum where members are also (and must be) strings

Bases: str, enum.Enum

class pooltool.physics.resolve.ball_pocket.BallPocketStrategy(*args, **kwargs)[source]#

Ball-pocket collision models must satisfy this protocol

Bases: Protocol

Methods:

resolve(ball: pooltool.objects.ball.datatypes.Ball, pocket: pooltool.objects.table.components.Pocket, inplace: bool = False) Tuple[pooltool.objects.ball.datatypes.Ball, pooltool.objects.table.components.Pocket][source]#

This method resolves a ball-circular cushion collision

Return type:

Tuple[pooltool.objects.ball.datatypes.Ball, pooltool.objects.table.components.Pocket]

class pooltool.physics.resolve.ball_pocket.BallPocketModel(value)[source]#

An Enum for different ball-pocket collision models

CANONICAL#

Sets the ball into the bottom of pocket and sets the state to pocketed (CanonicalBallPocket).

Bases: pooltool.utils.strenum.StrEnum

Functions#

pooltool.physics.resolve.ball_pocket.get_ball_pocket_model(model: BallPocketModel | None = None, params: pooltool.physics.resolve.types.ModelArgs = {}) BallPocketStrategy[source]#

Returns a ball-pocket collision model

Parameters:
  • model (Optional[BallPocketModel]) -- An Enum specifying the desired model. If not passed, CanonicalBallPocket is passed with empty params.

  • params (pooltool.physics.resolve.types.ModelArgs) -- A mapping of parameters accepted by the model.

Returns:

An instantiated model that satisfies the BallPocketStrategy protocol.

Return type:

BallPocketStrategy

Attributes#

pooltool.physics.resolve.ball_pocket.ModelArgs#

A mapping of argument names to argument values