pooltool.objects.ball#

Submodules#

Overview#

Classes#

Ball

A billiards ball

BallHistory

A container of BallState objects

BallOrientation

Stores a ball’s rendered BallOrientation

BallParams

Ball parameters and physical constants

BallState

Holds a ball’s state

Classes#

class pooltool.objects.ball.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.objects.ball.BallHistory(states: List[BallState] = UNKNOWN)[source]#

A container of BallState objects

states#

A list of time-increasing BallState objects (default = []).

Type:

List[pooltool.objects.ball.datatypes.BallState]

property empty: bool#

Returns whether or not the ball history is empty

Returns:

True if states has no length else False

Return type:

bool

Methods:

add(state: BallState) None[source]#

Append a state to the history

Raises:

AssertionError -- If state.t < self.states[-1]

Notes

  • This appends state to states

  • state is not copied before appending to the history, so they share the same memory address.

copy() BallHistory[source]#

Create a copy

Return type:

BallHistory

vectorize() Tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]] | None[source]#

Compile the attribute from each ball state into arrays

This method unzips each BallState in states, resulting in an array of BallState.rvw values, an array of BallState.s values, and an array of BallState.t values.

The vectors have the following properties:

>>> import pooltool as pt
>>> history = pt.simulate(pt.System.example(), continuous=True).balls["cue"].history_cts
>>> rvws, ss, ts = history.vectorize()
>>> # Their lengths are equal to the BallHistory
>>> len(rvws) == len(ss) == len(ts) == len(history)
True
>>> # The indices of the arrays match the values of the history
>>> pt.objects.BallState(rvws[26], ss[26], ts[26]) == history[26]
True
Returns:

A length 3 tuple (rvws, ss and ts). Returns None if self has no length.

Return type:

Optional[Tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]]]

Example

vectorize can be useful for plotting trajectories.

import pooltool as pt
import matplotlib.pyplot as plt

system = pt.System.example()
pt.simulate(system, continuous=True, inplace=True)

for ball in system.balls.values():
    rvw, ss, ts = ball.history_cts.vectorize()
    plt.plot(rvw[:, 0, 0], rvw[:, 0, 1], color=ss)

plt.show()

See also

static from_vectorization(vectorization: Tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]] | None) BallHistory[source]#

Zips a vectorization into a BallHistory

An inverse method of vectorize().

Returns:

A BallHistory constructed from the input vectors.

Return type:

BallHistory

Example

This illustrates a round-trip with vectorize() and from_vectorization().

First create history

>>> import pooltool as pt
>>> history = pt.simulate(pt.System.example(), continuous=True).balls["cue"].history_cts

Illustrate a lossless round trip:

>>> pt.objects.BallHistory.from_vectorization(history.vectorize()) == history
True
class pooltool.objects.ball.BallOrientation(pos: Tuple[float, float, float, float], sphere: Tuple[float, float, float, float])[source]#

Stores a ball’s rendered BallOrientation

From a practical standpoint, what needs to be understood about this class is that its attributes uniquely specify a ball’s rendered orientation. Less practically, but more specifically, these attributes correspond to the nodes, ‘pos’ and ‘sphere’, that make up a ball’s visual rendering.

pos#

A quaternion.

Type:

Tuple[float, float, float, float]

sphere#

Another quaternion.

Type:

Tuple[float, float, float, float]

Methods:

static random() BallOrientation[source]#

Generate a random BallOrientation

This generates a ball orientation from a uniform sampling of possible orientations.

Returns:

A randomized ball orientation.

Return type:

BallOrientation

copy() BallOrientation[source]#

Create a copy

Note

  • Since the class is frozen and its attributes are immutable, this just returns self.

Return type:

BallOrientation

class pooltool.objects.ball.BallParams(m: float = 0.170097, R: float = 0.028575, u_s: float = 0.2, u_r: float = 0.01, u_sp_proportionality: float = 0.4444444444444444, e_c: float = 0.85, f_c: float = 0.2, g: float = 9.81)[source]#

Ball parameters and physical constants

m#

The mass of the ball (default = 0.170097

Type:

float

R#

The radius of the ball (default = 0.028575).

Type:

float

u_s#

The sliding coefficient of friction (default = 0.2).

Type:

float

u_r#

The rolling coefficient of friction (default = 0.01).

Type:

float

u_sp_proportionality#

The spinning coefficient of friction, with R factored out (default = 0.01).

See also

  • For the coefficient of spinning friction, use the property u_sp().

Type:

float

e_c#

The cushion coefficient of restitution (default = 0.85).

Note

This is a potentially model-dependent ball-cushion parameter and should be placed elsewhere, either as a model parameter or as a cushion segment parameter.

Type:

float

f_c#

The cushion coefficient of friction (default = 0.2).

Note

This is a potentially model-dependent ball-cushion parameter and should be placed elsewhere, either as a model parameter or as a cushion segment parameter.

Type:

float

g#

The gravitational constant (default = 9.81).

Type:

float

Most of the default values (SI units) are taken from or based off of https://billiards.colostate.edu/faq/physics/physical-properties/.

Some of the parameters aren’t truly ball parameters, e.g. the gravitational constant. However, it is nice to be able to tune such parameters on a ball-by-ball basis, so they are included here.

Methods:

u_sp() float#

Coefficient of spinning friction

This is equal to u_sp_proportionality * R

Cached Property Note

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

Return type:

float

copy() BallParams[source]#

Return a copy

Note

  • Since the class is frozen and its attributes are immutable, this just returns self.

Return type:

BallParams

classmethod default(game_type: pooltool.game.datatypes.GameType = GameType.EIGHTBALL) BallParams[source]#

Return prebuilt ball parameters based on game type

Parameters:

game_type (pooltool.game.datatypes.GameType) -- What type of game is being played?

Returns:

The prebuilt ball parameters associated with the passed game type.

Return type:

BallParams

classmethod prebuilt(name: PrebuiltBallParams) BallParams[source]#

Return prebuilt ball parameters based on name

Parameters:

name (PrebuiltBallParams) -- A PrebuiltBallParams member.

Return type:

BallParams

All prebuilt ball parameters are named with the PrebuiltBallParams Enum. This constructor takes a prebuilt name and returns the corresponding ball parameters.

See also

  • PrebuiltBallParams

class pooltool.objects.ball.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