Source code for pooltool.physics.resolve.transition
"""Defining and handling ball state transitionsNote: If this module is ever extended to support multiple treatments for ball transitions, expand this file into a file structure modelled after ../ball_ball or ../ball_cushion"""fromtypingimportDict,Optional,Protocol,Tuple,Typeimportnumpyasnpimportpooltool.constantsasconstfrompooltool.events.datatypesimportEventTypefrompooltool.objects.ball.datatypesimportBallfrompooltool.physics.resolve.typesimportModelArgsfrompooltool.utils.strenumimportStrEnum,auto
[docs]classBallTransitionStrategy(Protocol):"""Ball transition models must satisfy this protocol"""
[docs]defresolve(self,ball:Ball,transition:EventType,inplace:bool=False)->Ball:"""This method resolves a ball transition"""...
classCanonicalTransition:defresolve(self,ball:Ball,transition:EventType,inplace:bool=False)->Ball:ifnotinplace:ball=ball.copy()asserttransition.is_transition()start,end=_ball_transition_motion_states(transition)assert(ball.state.s==start),f"Start state was {ball.state.s}, expected {start}"ball.state.s=endifend==const.spinning:# Assert that the velocity components are nearly 0, and that the x and y# angular velocity components are nearly 0. Then set them to exactly 0.v=ball.state.rvw[1]w=ball.state.rvw[2]assert(np.abs(v)<const.EPS_SPACE).all()assert(np.abs(w[:2])<const.EPS_SPACE).all()ball.state.rvw[1,:]=[0.0,0.0,0.0]ball.state.rvw[2,:2]=[0.0,0.0]ifend==const.stationary:# Assert that the linear and angular velocity components are nearly 0, then# set them to exactly 0.v=ball.state.rvw[1]w=ball.state.rvw[2]assert(np.abs(v)<const.EPS_SPACE).all()assert(np.abs(w)<const.EPS_SPACE).all()ball.state.rvw[1,:]=[0.0,0.0,0.0]ball.state.rvw[2,:]=[0.0,0.0,0.0]returnballdef_ball_transition_motion_states(event_type:EventType)->Tuple[int,int]:"""Return the ball motion states before and after a transition"""assertevent_type.is_transition()ifevent_type==EventType.SPINNING_STATIONARY:returnconst.spinning,const.stationaryelifevent_type==EventType.ROLLING_STATIONARY:returnconst.rolling,const.stationaryelifevent_type==EventType.ROLLING_SPINNING:returnconst.rolling,const.spinningelifevent_type==EventType.SLIDING_ROLLING:returnconst.sliding,const.rollingraiseNotImplementedError()
[docs]classBallTransitionModel(StrEnum):"""An Enum for different transition models Attributes: CANONICAL: Sets the ball to appropriate state. Sets any residual quantities to 0 when appropriate (:class:`CanonicalTransition`). """CANONICAL=auto()
[docs]defget_transition_model(model:Optional[BallTransitionModel]=None,params:ModelArgs={},)->BallTransitionStrategy:"""Returns a transition model Args: model: An Enum specifying the desired model. If not passed, :class:`CanonicalTransition` is passed with empty params. params: A mapping of parameters accepted by the model. Returns: An instantiated model that satisfies the :class:`BallTransitionStrategy` protocol. """ifmodelisNone:returnCanonicalTransition()return_ball_transition_models[model](**params)