pooltool.physics.resolve.ball_cushion.unrealistic#

An unrealistic ball-cushion model#

Overview#

Classes#

Ball

A billiards ball

CircularCushionSegment

A circular cushion segment defined by a circle center and radius

LinearCushionSegment

A linear cushion segment defined by the line between points p1 and p2

CoreBallCCushionCollision

Operations used by every ball-linear cushion collision resolver

CoreBallLCushionCollision

Operations used by every ball-linear cushion collision resolver

UnrealisticLinear

Operations used by every ball-linear cushion collision resolver

UnrealisticCircular

Operations used by every ball-linear cushion collision resolver

Classes#

class pooltool.physics.resolve.ball_cushion.unrealistic.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_cushion.unrealistic.CircularCushionSegment(id: str, center: ndarray[Any, dtype[float64]], radius: float)[source]#

A circular cushion segment defined by a circle center and radius

id#

The ID of the cushion segment.

Type:

str

center#

A length-3 array specifying the circular cushion’s center.

center[0], center[1], and center[2] are the x-, y-, and z-coordinates of the cushion’s center. The circle is assumed to be parallel to the XY plane, which makes center[2] is the height of the cushion.

Type:

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

radius#

The radius of the cushion segment.

Type:

float

Methods:

height() float#

The height of the cushion

Cached Property Note

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

Return type:

float

a() float#

The x-coordinate of the cushion’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 cushion’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

get_normal(rvw: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64][source]#

Calculates the normal vector for a ball contacting the cushion

Assumes that the ball is in fact in contact with the cushion.

Parameters:

rvw (numpy.typing.NDArray[numpy.float64]) -- The kinematic state vectors of the contacting ball (see

Return type:

numpy.typing.NDArray[numpy.float64]

:param pooltool.objects.ball.datatypes.BallState.rvw).:

Returns:

The normal vector, with the z-component set to 0.

Return type:

NDArray[np.float64]

copy() CircularCushionSegment[source]#

Create a copy

Return type:

CircularCushionSegment

class pooltool.physics.resolve.ball_cushion.unrealistic.LinearCushionSegment(id: str, p1: ndarray[Any, dtype[float64]], p2: ndarray[Any, dtype[float64]], direction: int = 2)[source]#

A linear cushion segment defined by the line between points p1 and p2

id#

The ID of the cushion segment.

Type:

str

p1#

The 3D coordinate where the cushion segment starts.

Note

  • p1 and p2 must share the same height (p1[2] == p2[2]).

Type:

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

p2#

The 3D coordinate where the cushion segment ends.

Note

  • p1 and p2 must share the same height (p1[2] == p2[2]).

Type:

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

direction#

The cushion direction (default = CushionDirection.BOTH).

See CushionDirection for explanation.

Type:

int

Methods:

height() float#

The height of the cushion

Cached Property Note

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

Return type:

float

lx() float#

The x-coefficient (\(l_x\)) of the cushion’s 2D general form line equation

Cached Property Note

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

The cushion’s general form line equation in the \(XY\) plane (i.e. dismissing the z-component) is

\[l_x x + l_y y + l_0 = 0\]

where

\[\begin{split}\begin{align*} l_x &= -\frac{p_{2y} - p_{1y}}{p_{2x} - p_{1x}} \\ l_y &= 1 \\ l_0 &= \frac{p_{2y} - p_{1y}}{p_{2x} - p_{1x}} p_{1x} - p_{1y} \\ \end{align*}\end{split}\]
Return type:

float

ly() float#

The x-coefficient (\(l_y\)) of the cushion’s 2D general form line equation

See lx() for definition.

Cached Property Note

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

Return type:

float

l0() float#

The constant term (\(l_0\)) of the cushion’s 2D general form line equation

See lx() for definition.

Cached Property Note

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

Return type:

float

normal() numpy.typing.NDArray[numpy.float64]#

The line’s normal vector, with the z-component set to 0.

Warning

The returned normal vector is arbitrarily directed, meaning it may point away from the table surface, rather than towards it. This nonideality is properly handled in downstream simulation logic, however if you’re using this method for custom purposes, you may want to reverse the direction of this vector by negating it.

Return type:

numpy.typing.NDArray[numpy.float64]

get_normal(rvw: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.float64][source]#

Calculates the normal vector

Warning

The returned normal vector is arbitrarily directed, meaning it may point away from the table surface, rather than towards it. This nonideality is properly handled in downstream simulation logic, however if you’re using this method for custom purposes, you may want to reverse the direction of this vector by negating it.

Parameters:

rvw (numpy.typing.NDArray[numpy.float64]) --

The kinematic state vectors of the contacting balls.

See rvw parameter of pooltool.objects.ball.datatypes.BallState.

Returns:

The line’s normal vector, with the z-component set to 0.

Return type:

NDArray[np.float64]

Note

copy() LinearCushionSegment[source]#

Create a copy

Return type:

LinearCushionSegment

class pooltool.physics.resolve.ball_cushion.unrealistic.CoreBallCCushionCollision[source]#

Operations used by every ball-linear cushion collision resolver

Bases: abc.ABC

Methods:

make_kiss(ball: pooltool.objects.ball.datatypes.Ball, cushion: pooltool.objects.table.components.CircularCushionSegment) pooltool.objects.ball.datatypes.Ball[source]#

Translate the ball so it (almost) touches the circular cushion segment

This makes a correction such that if the ball is not a distance R from the cushion, the ball is moved along the normal such that it is. To avoid downstream float precision round-off error, a small epsilon of additional distance (constants.EPS_SPACE) is put between them, ensuring the cushion and ball are separated post-resolution.

Return type:

pooltool.objects.ball.datatypes.Ball

class pooltool.physics.resolve.ball_cushion.unrealistic.CoreBallLCushionCollision[source]#

Operations used by every ball-linear cushion collision resolver

Bases: abc.ABC

Methods:

make_kiss(ball: pooltool.objects.ball.datatypes.Ball, cushion: pooltool.objects.table.components.LinearCushionSegment) pooltool.objects.ball.datatypes.Ball[source]#

Translate the ball so it (almost) touches the linear cushion segment

This makes a correction such that if the ball is not a distance R from the cushion, the ball is moved along the normal such that it is. To avoid downstream float precision round-off error, a small epsilon of additional distance (constants.EPS_SPACE) is put between them, ensuring the cushion and ball are separated post-resolution.

Return type:

pooltool.objects.ball.datatypes.Ball

class pooltool.physics.resolve.ball_cushion.unrealistic.UnrealisticLinear(restitution: bool = True)[source]#

Bases: pooltool.physics.resolve.ball_cushion.core.CoreBallLCushionCollision

class pooltool.physics.resolve.ball_cushion.unrealistic.UnrealisticCircular(restitution: bool = True)[source]#

Bases: pooltool.physics.resolve.ball_cushion.core.CoreBallCCushionCollision