The green axis of the gizmo is pointing at the ball. The red and blue axes twitch when the ball passes a certain point (ignore the discontinuity of the GIF):
This is from a simple game engine so it's easier to analyse, but I've seen this behaviour in plenty of other cases (including animation software, with aim constraints).
Is there a way to avoid this flipping? Is there a method of rotation that doesn't need to adjust the blue and red axes, where it just points the green to the target and the other axes can freely rotate and accumulate rotation, rather than having to do this "reset"? I'm asking this as an animation character rigger, working with some bones with look-at constraints that have this same flipping \ twitching behaviour.
For reference, the source code of the look-at from the image:
The look-at function (from here):
void bbPointEntity( Entity *e,Entity *t,float roll ){
if( debug ){ debugEntity(e);debugEntity(t); }
Vector v=t->getWorldTform().v-e->getWorldTform().v;
e->setWorldRotation( rotationQuat( v.pitch(),v.yaw(),roll*dtor ) );
}
From that, the v.pitch() and v.yaw() methods (from here):
float yaw()const{
return -atan2f( x,z );
}
float pitch()const{
return -atan2f( y,sqrtf( x*x+z*z ) );
}
...and the rotationQuat function that creates the quaternion (from here and here):
inline Quat pitchQuat( float p ){
return Quat( cosf(p/-2),Vector( sinf(p/-2),0,0 ) );
}
inline Quat yawQuat( float y ){
return Quat( cosf(y/2),Vector( 0,sinf(y/2),0 ) );
}
inline Quat rollQuat( float r ){
return Quat( cosf(r/-2),Vector( 0,0,sinf(r/-2) ) );
}
(...)
Quat rotationQuat( float p,float y,float r ){
return yawQuat(y)*pitchQuat(p)*rollQuat(r);
}