Hi everyone,
I’m making a physics pool engine in python and cannot seem to get the ‘roll’ of the balls to work. In my application, the ball histories are all precomputed. So I basically have an array that stores, as a function of time, the
- linear velocity
- displacement vector
- angular velocity of each ball around its center of mass
- the “angular displacement”, i.e. the time integration of angular velocity
I’ve had a lot of success so far translating the balls with panda3d, but giving them the correct roll using the angular displacement has been extremely difficult. What I’m currently doing to calculate Heading Pitch Roll (HPR) from angular displacement is this:
I have an array of angular displacements, which is like the integral of angular velocity. So for example, if a ball spins with an angular velocity <0,0,1>
for 2 seconds, the angular displacement would be <0,0,2>
. To convert this into HPR, I am using scipy
:
import numpy as np
from scipy.spatial.transform import Rotation
def as_euler_angle(theta):
return Rotation.from_rotvec(theta).as_euler('zxy', degrees=True)
print(as_euler_angle(np.array([0,0,2])))
This yields [114.5915590262 0. 0. ]
, i.e. it changes the Heading, as expected.
As a reminder, I have this precomputed for each timepoint, and so to update the positions and orientations of the ball I have an update
method I call each frame:
def update(self, frame):
self.node.setPos(self.xs[frame], self.ys[frame], self.zs[frame] + self._ball.R)
self.node.setHpr(self.hs[frame], self.ps[frame], self.rs[frame])
This works perfectly for translating the balls, but rotating the balls only kind of works. Here is a gif:
Ball 1 hits Ball 2. After their first collision, they are both moving in the y direction with rotations that look correct. After their second collision, they move mostly in the x direction with an obviously incorrect roll. Yet when I study the angular velocity of the Ball 1, it’s angular velocity is dominantly in the +y direction, as one would expect for a ball rolling without slipping with a velocity in the +x direction. Correspondingly, the angular displacement is also in the +y direction.
Does anyone understand what has gone wrong, or have suggestions on how I can get away from the scipy function and calculate this myself? I am also not married to doing this with angular displacement. For example, maybe angular velocities are all I need and using quaternions?
Thanks so much for your time.
EDIT: After writing this up, I think the issue might be that the direction of the ball changes, but somehow this is not reflected in the HPR?