Source code for pooltool.physics.resolve.ball_cushion.unrealistic
"""An unrealistic ball-cushion model"""fromtypingimportTuple,TypeVarimportattrsimportnumpyasnpimportpooltool.constantsasconstimportpooltool.ptmathasptmathfrompooltool.objects.ball.datatypesimportBallfrompooltool.objects.table.componentsimport(CircularCushionSegment,LinearCushionSegment,)frompooltool.physics.resolve.ball_cushion.coreimport(CoreBallCCushionCollision,CoreBallLCushionCollision,)frompooltool.physics.resolve.modelsimportBallCCushionModel,BallLCushionModelCushion=TypeVar("Cushion",LinearCushionSegment,CircularCushionSegment)def_solve(ball:Ball,cushion:Cushion,restitution:bool=True)->Tuple[Ball,Cushion]:"""Given ball and cushion, unrealistically reflect the ball's momentum Args: restitution: By default, the ball's momentum is reflected without loss. Set this to true if the ball's restitution coefficient should dampen the outgoing velocity. """rvw=ball.state.rvw# Two things about the normal:# 1) Cushions have a get_normal method that returns the normal. For linear# cushions this is determined solely by it's geometry. For circular# cushions, the normal is a function of the ball's position (specifically,# it is the line connecting the ball's and cushion's centers). To retain# symmetry between method calls, both linear and circular cushion segments# accept `rvw` as a parameter# 2) The cushion normal is arbitrarily assigned to face either into the table# or away from the table. That's my bad--a mishap during development that# we're still living with the consequences of. The burden is that you must# assign a convention. Here I opt to orient the normal so it points away# from the playing surface.normal=cushion.get_normal(rvw)normal=normalifnp.dot(normal,rvw[1])>0else-normal# Rotate frame of reference to the cushion frame. The cushion frame is defined# by the cushion's normal vector (convention: points away from table) being# parallel with <1,0,0>.psi=ptmath.angle(normal)rvw_R=ptmath.coordinate_rotation(rvw.T,-psi).T# Reverse velocity component lying in normal directionrvw_R[1,0]*=-1*(1ifnotrestitutionelseball.params.e_c)# Rotate frame of reference back to the table framervw=ptmath.coordinate_rotation(rvw_R.T,psi).T# Set the ball's rvwball.state.rvw=rvw# You'll also want to set the motion state of the ball to slidingball.state.s=const.slidingreturnball,cushion