pooltool.evolution.continuize

Module for building a time-dense system trajectory

For an explanation, see continuize()

Overview

Function

continuize(system, dt, inplace)

Create a BallHistory for each ball with many timepoints

Functions

pooltool.evolution.continuize.continuize(system: pooltool.system.datatypes.System, dt: float = 0.01, inplace: bool = False) pooltool.system.datatypes.System[source]

Create a BallHistory for each ball with many timepoints

When pooltool simulates a shot, it evolves the system using an event-based shot evolution algorithm. This means pooltool only timestamps the ball states during events--not between events. This makes simulation fast, but provides insufficient trajectory information if you wanted to visualize or plot ball trajectories over time.

Continuizing the shot means tracking the ball states with higher temporal resolution, so that the ball trajectories between events can be recapitulated. It’s a misnomer because the states are still tracked over discrete time steps dt seconds apart. i.e. not continuous.

This function calculates the “continous” timestamps for each ball and stores them in pooltool.objects.ball.datatypes.Ball.history_cts (the event-based timestamps are preserved, and are stored in pooltool.objects.ball.datatypes.Ball.history)

The continous timepoints are shared between all balls and are uniformly spaced (except for the last timepoint, which occurs at the final event, which necessarily occurs less than dt after the second last timepoint).

Parameters:
  • dt (float) -- This is the spacing between each timepoint. 0.01 looks visually accurate at 60fps at a playback speed of 1. Function runtime is inversely proportional to dt.

  • inplace (bool) -- By default, a copy of the passed system is continuized and returned. This leaves the passed system unmodified. If inplace is set to True, the passed system is modified in place, meaning no copy is made and the returned system is the passed system. For a more practical distinction, see Examples below.

Return type:

pooltool.system.datatypes.System

Examples

Standard usage:

>>> import pooltool as pt
>>> system = pt.simulate(pt.System.example())

The system has been simulated, so their history attributes are populated:

>>> len(system.balls["cue"].history)
14
>>> system.balls["cue"].history[0]
BallState(rvw=array([[0.4953  , 0.9906  , 0.028575],
       [0.      , 0.      , 0.      ],
       [0.      , 0.      , 0.      ]]), s=0, t=0.0)
>>> system.balls["cue"].history[-1]
BallState(rvw=array([[0.7464286761774921, 1.247940272192023 , 0.028575          ],
       [0.                , 0.                , 0.                ],
       [0.                , 0.                , 0.                ]]), s=0, t=5.193035203405666)

However, the system has not been continuized, so their history_cts attributes are empty:

>>> len(system.balls["cue"].history_cts)
0

After continuizing, the continuous ball histories are populated with many timestamps:

>>> continuized_system = pt.continuize(system, inplace=False)
>>> continuized_system.continuized
True
>>> len(continuized_system.balls["cue"].history_cts)
523

You can also modify the system in place:

>>> import pooltool as pt
>>> system = pt.simulate(pt.System.example())
>>> continuized_system = pt.continuize(system, inplace=True)
>>> assert system.continuized
>>> assert continuized_system.continuized
>>> assert system is continuized_system

Notice that the returned system is the continuized system. Therefore, there is no point catching the return object when inplace is True:

>>> import pooltool as pt
>>> system = pt.simulate(pt.System.example())
>>> assert not system.continuized
>>> pt.continuize(system, inplace=True)
>>> assert system.continuized