I'm trying to design a space game where the user has 2 types of input:
- forward and backwards thrust in the current direction
- change orientation
The game is based on actual physics, for the sake of simplicity we can assume everything is presented as a pointmass.
A pointmass has the following attributes (known by the physics engine):
- position (vector3)
- orientation (quaternion)
- linear_velocity (vector3)
- angular_velocity (vector3)
- inverse_mass (float)
- linear_forces (vector3)
- angular_forces (vector3)
Given these values, a user clicks a point in space, and commands the spaceship to orient itself in that orientation. As such, we can ignore: position, linear_velocity, linear_forces at that point already. Furthermore we can assume that the maximum angular forces have a set maximum (angular_forces_max >= angular_forces.length()).
My question is now, what is the fastest way to get to the new orientation, given that we also want to have angular velocity set to 0 when we reach this new orientation.
In my thoughts, given these input variables:
- current orientation: quaternion
- wanted orientation: quaternion
- current angular_velocity: vector3
- wanted angular_velocity: vector3 (nilvector)
- maximum angular_acceleration: float
And as output:
- angular_acceleration, vector3 (this will determine the forces how to get to the new orientation)
- t1 time in seconds how long we will use the positive angular_acceleration forces (speeding up)
- t2 time in seconds how long we will use the negative angular_acceleration forces (slowing down)
I'm having trouble grasping this concept as a whole, I believe we will need to at least translate the quaternion to a vector + angle, so we can at least add 2 * pi to the angle so we can also calculate it while approaching it from the other side. This due to the fact you can't do a 2 * pi rotation with a quaternion and maintain the same quaternion.
To give an example how this would work in 2D:
w = wanted orientation, angle, in radians
v = wanted angular velocity, in rad/s
w0 = current orientation, angle, in radians
v0 = current angular velocity, in rad/s
a_max = max angular acceleration in rad/(s^2)
w = w0 + v0*t + (a_max/2) * t1_short^2 - (a_max/2) * t2_short^2
v = 0 = v0 + a_max * t1_short - a_max * t2_short
// fill in and substitute the formulas
// store t1_short, t2_short
w + 2*pi = w0 + v0*t + (a_max/2) * t1_long^2 - (a_max/2) * t2_long^2
v = 0 = v0 + a_max * t1_long - a_max * t2_long
// fill in and substitute the formulas
// store t1_long, t2_long
if (t1_short + t2_short) <= (t1_long + t2_long) {
return (t1_short, t2_short);
} else {
return (t1_long, t2_long);
}
This gives a deterministic manner of calculating t1 and t2 (acceleration time and deceleration time) in 2D, the forces vector is just a singular element vector here [a_max] (a_max = [a_max].length()
).
My question is pretty straightforward, how can we do this in 3D with matrices, vectors, quaternions?
(should this be instead posted to the physics / math department of stack exchange btw?)