pooltool.physics

Physics subpackage for pooltool

Submodules

Classes

class BallBallModel[source]

An Enum for different ball-ball collision models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

FRICTIONLESS_ELASTIC

A frictionless, instantaneous, elastic, equal mass collision resolver.

This is as simple as it gets.

FRICTIONAL_INELASTIC

A simple ball-ball collision model including ball-ball friction, and coefficient of restitution for equal-mass balls.

Largely inspired by Dr. David Alciatore’s technical proofs (https://billiards.colostate.edu/technical_proofs), in particular, TP_A-5, TP_A-6, and TP_A-14. These ideas have been extended to include motion of both balls, and a more complete analysis of velocity and angular velocity in their vector forms.

FRICTIONAL_MATHAVAN

Ball-ball collision resolver for the Mathavan et al. (2014) collision model.

The model “uses general theories of dynamics of spheres rolling on a flat surface and general frictional impact dynamics under the assumption of point contacts between the balls under collision and that of the table.”

The authors compare the model predictions to experimental exit velocities and angles measured with a high speed camera system and illustrate marked improvement over previous theories, which unlike this model, fail to account for spin.

References

Mathavan, S., Jackson, M.R. & Parkin, R.M. Numerical simulations of the frictional collisions of solid balls on a rough surface. Sports Eng 17, 227–237 (2014). https://doi.org/10.1007/s12283-014-0158-y

Available at https://billiards.colostate.edu/physics_articles/Mathavan_Sports_2014.pdf

class BallBallFrictionModel[source]

An Enum for different ball-ball friction models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

AVERAGE

The friction is calculated as the average of ball-ball sliding friction of the two balls.

ALCIATORE

Friction fit curve \(u_b = a + b e^{ -c v_{rel} }\) used in David Alciatore’s TP A-14.

class BallCCushionModel[source]

An Enum for different ball-circular cushion collision models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

HAN_2005

See BallLCushionModel.

UNREALISTIC

See BallLCushionModel.

IMPULSE_FRICTIONAL_INELASTIC

See BallLCushionModel.

MATHAVAN_2010

See BallLCushionModel.

STRONGE_COMPLIANT

See BallLCushionModel.

class BallLCushionModel[source]

An Enum for different ball-linear cushion collision models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

HAN_2005

https://ekiefl.github.io/2020/04/24/pooltool-theory/#3-han-2005.

UNREALISTIC

An unrealistic model in which balls are perfectly reflected. Spin is left untouched by the interaction.

IMPULSE_FRICTIONAL_INELASTIC

An instantaneous/non-smooth, impulse-based collision model. This model includes effects of tangential friction and normal coefficient of restitution.

MATHAVAN_2010

Ball-cushion collision resolver for the Mathavan et al. (2010) collision model.

This work predicts ball bounce angles and bounce speeds for the ball’s collisions with a cushion, under the assumption of insignificant cushion deformation. Differential equations are derived for the ball dynamics during the impact and these these equations are solved numerically.

References

Mathavan S, Jackson MR, Parkin RM. A theoretical analysis of billiard ball-cushion dynamics under cushion impacts. Proceedings of the Institution of Mechanical Engineers, Part C. 2010;224(9):1863-1873. doi:10.1243/09544062JMES1964

Available at https://drdavepoolinfo.com//physics_articles/Mathavan_IMechE_2010.pdf

STRONGE_COMPLIANT

An instantaneous/non-smooth, collision model that accounts for tangential compliance. This model includes effects of tangential friction, tangential compliance, and normal coefficient of restitution. Accounting for tangential compliance allows for reversal of the slip direction at the contact point.

This model assumes the colliding bodies (ball and rail) are rigid bodies, one of which is connected at the contact point to a massless particle via two independent springs. One of the springs is oriented in the normal direction, the other in the tangent direction. During restitution, the stiffness of the normal spring increases depending on the coefficient of restitution. The tangential spring has a constant stiffness. This results in simple harmonic motion in both the normal and tangent directions. These equations can be solved for the final velocities after some root finding to determine transitions between sticking and slipping at the contact point. There is no numerical integration to solve for the final result.

References

W. J. Stronge, “Tangential Compliance in Planar Impact of Rough Bodies,” in Impact Mechanics, Cambridge: Cambridge University Press, 2018, pp. 89–115 doi:10.1017/9781139050227

class BallPocketModel[source]

An Enum for different ball-pocket collision models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

CANONICAL

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

class BallTableModel[source]

An Enum for different ball-table collision models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

FRICTIONLESS_INELASTIC

Frictionless, instantaneous, inelastic collision.

FRICTIONAL_INELASTIC

Frictional, inelastic (https://billiards.colostate.edu/technical_proofs/new/TP_A-14.pdf).

class Resolver(ball_ball: BallBallCollisionStrategy, ball_linear_cushion: BallLCushionCollisionStrategy, ball_circular_cushion: BallCCushionCollisionStrategy, ball_pocket: BallPocketStrategy, stick_ball: StickBallCollisionStrategy, ball_table: BallTableCollisionStrategy, transition: BallTransitionStrategy, version: int | None = None)[source]

A physics engine component that characterizes event resolution

Important

For everything you need to know about this class, see Modular Physics.

Methods:

resolve(shot: System, event: Event) None[source]

Resolve an event for a system

save(path: pooltool.serialize.Pathish) Path[source]
Return type:

Path

classmethod load(path: pooltool.serialize.Pathish) Resolver[source]
Return type:

Resolver

classmethod default() Resolver[source]

Load ~/.config/pooltool/physics/resolver.yaml if exists, create otherwise

Return type:

Resolver

class StickBallModel[source]

An Enum for different stick-ball collision models

The underlying math (see cue_strike()) is fully 3D: it produces a ball velocity with a vertical component proportional to sin(theta), the cue elevation. The two members below differ only in what they do with that vertical component.

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

INSTANTANEOUS_POINT_3D

Instantaneous and point-like stick-ball interaction. The full 3D cue-strike result is applied to the ball, including any vertical velocity produced by cue elevation. Suitable for a 3D simulation that supports airborne motion.

A derivation can be found in Dr. Dave Billiard’s technical proof A-30 (https://billiards.colostate.edu/technical_proofs/new/TP_A-30.pdf). A deflection (squirt) angle is calculated via pooltool.physics.resolve.stick_ball.squirt.

INSTANTANEOUS_POINT_2D

Same 3D cue-strike math as INSTANTANEOUS_POINT_3D, followed by a clamp that zeros the vertical velocity component of the ball. Suitable for a 2D simulation: the ball never leaves the table surface regardless of cue elevation.

class BallTransitionModel[source]

An Enum for different transition models

Base Classes:

pooltool.utils.strenum.StrEnum

Attributes:

CANONICAL

Sets the ball to appropriate state. Sets any residual quantities to 0 when appropriate.

Functions

evolve_ball_motion(state: int, rvw: NDArray[float64], R: float, m: float, u_s: float, u_sp: float, u_r: float, g: float, t: float) tuple[NDArray[float64], int][source]

Evolve a ball’s kinematic state forward in time.

Contract: This function always returns a new array. The input rvw is never modified, and the returned array has no aliasing with the input. The caller owns the returned array.

Return type:

tuple[NDArray[float64], int]

display_models()[source]
get_airborne_time(rvw: NDArray[float64], R: float, g: float) float[source]

Time until an airborne ball’s bottom touches the table plane (z = R).

Solves -0.5 * g * t**2 + v_z * t + (z - R) = 0 and returns the later root (the descending-leg intersection). Returns np.inf when gravity is zero.

Return type:

float

get_ball_energy(rvw: NDArray[float64], R: float, m: float, g: float) float[source]

Get the energy of a ball.

Sum of linear kinetic, rotational kinetic, and gravitational potential energy. Potential energy is defined relative to a ball at rest on the table (z = R), so a ball sitting on the table contributes zero energy.

Return type:

float

get_roll_time(rvw: NDArray[float64], u_r: float, g: float) float[source]
Return type:

float

get_slide_time(rvw: NDArray[float64], R: float, u_s: float, g: float) float[source]
Return type:

float

get_spin_time(rvw: NDArray[float64], R: float, u_sp: float, g: float) float[source]
Return type:

float

get_u_vec(rvw: NDArray[float64], R: float, phi: float, s: int) NDArray[float64][source]
Return type:

NDArray[float64]

rel_velocity(rvw: NDArray[float64], R: float) NDArray[float64][source]

Compute velocity of ball’s point of contact with the cloth relative to the cloth

This vector is non-zero whenever the ball is sliding

Return type:

NDArray[float64]

surface_velocity(rvw: NDArray[float64], d: NDArray[float64], R: float) NDArray[float64][source]

Compute velocity of a point on ball’s surface (specified by unit direction vector)

Return type:

NDArray[float64]

Attributes

ball_ball_models: dict[BallBallModel, type[core.BallBallCollisionStrategy]]
ball_ball_friction_models: dict[BallBallFrictionModel, type[BallBallFrictionStrategy]]
ball_ccushion_models: dict[BallCCushionModel, type[core.BallCCushionCollisionStrategy]]
ball_lcushion_models: dict[BallLCushionModel, type[core.BallLCushionCollisionStrategy]]
ball_pocket_models: dict[BallPocketModel, type[BallPocketStrategy]]
ball_table_models: dict[BallTableModel, type[core.BallTableCollisionStrategy]]
RESOLVER_PATH

The location of the resolver path YAML.

stick_ball_models: dict[StickBallModel, type[core.StickBallCollisionStrategy]]
ball_transition_models: dict[BallTransitionModel, type[BallTransitionStrategy]]