使用四元数旋转相机
Rotate Camera With Quaternions
我正在尝试制作一个可以在按下箭头键时旋转的相机,但是,当我转动相机并尝试旋转它时,它不会绕正确的轴旋转。
例如,我的向上向量是( 0, 1, 0 )。我可以完美地左右旋转我的相机,因为这个矢量是恒定的。我的相机无法工作的地方是当我试图绕其右轴旋转时。如果我向左或向右转动我的相机并绕右轴旋转,它通常会在一个不正确的奇怪方向上处理轴。这不应该是这种情况,因为我仍然可以完美地向右移动我的相机,它只是没有正确旋转。
下面是所有相关代码。我不确定为什么旋转是围绕 y 轴而不是其他任何轴。
// m_rotation is a Quaternion and rotation is a 4x4 view matrix
// Rotate around y-axis when left arrow pressed
// This works perfectly
if ( Input::IsKeyDown( Input::KEY_LEFT_ARROW ) ) {
Rotate( Vector3<float>( 0, -1, 0 ), m_sensitivity );
}
// When down arrow is pressed, rotate around right axis
// This rotates around strange axis
if ( Input::IsKeyDown( Input::KEY_DOWN_ARROW ) ) {
Rotate( m_rotation.GetRight( rotation ), m_sensitivity );
}
// Rotate methods
void Camera::Rotate( const Vector3<float> &axis, float angle ) {
Rotate( Quaternion( axis, angle ) );
}
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( quaternion * m_rotation ).Normalized() );
}
// Quaternion code
Quaternion( const Vector3<float> &vect, float angle ) {
float sinAngle = sinf( angle / 2.0f );
float cosAngle = cosf( angle / 2.0f );
( *this )[ 0 ] = vect[ 0 ] * sinAngle;
( *this )[ 1 ] = vect[ 1 ] * sinAngle;
( *this )[ 2 ] = vect[ 2 ] * sinAngle;
( *this )[ 3 ] = cosAngle;
}
inline Quaternion operator*( const Quaternion &quat ) const {
Quaternion ret;
ret[ 3 ] = ( ( *this )[ 3 ] * quat[ 3 ] ) - ( ( *this )[ 0 ] * quat[ 0 ] ) - ( ( *this )[ 1 ] * quat[ 1 ] ) - ( ( *this )[ 2 ] * quat[ 2 ] );
ret[ 0 ] = ( ( *this )[ 3 ] * quat[ 0 ] ) + ( ( *this )[ 0 ] * quat[ 3 ] ) + ( ( *this )[ 1 ] * quat[ 2 ] ) - ( ( *this )[ 2 ] * quat[ 1 ] );
ret[ 1 ] = ( ( *this )[ 3 ] * quat[ 1 ] ) + ( ( *this )[ 1 ] * quat[ 3 ] ) + ( ( *this )[ 2 ] * quat[ 0 ] ) - ( ( *this )[ 0 ] * quat[ 2 ] );
ret[ 2 ] = ( ( *this )[ 3 ] * quat[ 2 ] ) + ( ( *this )[ 2 ] * quat[ 3 ] ) + ( ( *this )[ 0 ] * quat[ 1 ] ) - ( ( *this )[ 1 ] * quat[ 0 ] );
return ret;
}
inline Vector3<float> GetRight( const Matrix4<float> &viewMatrix ) const {
return Vector3<float>( rotation[ 0 ][ 0 ], rotation[ 1 ][ 0 ], rotation[ 2 ][ 0 ] );
}
非常感谢任何帮助或建议。谢谢
经过几天尝试各种不同的事情后,我发现了问题所在。我忘记了四元数在相乘时是不可交换的。这导致相机以奇怪的方式旋转。所以要解决这个问题,我所要做的就是更改这段代码。
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( quaternion * m_rotation ).Normalized() );
}
为此...
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( m_rotation * quaternion ).Normalized() );
}
我想要post这个,希望它能帮助将来的人。
我正在尝试制作一个可以在按下箭头键时旋转的相机,但是,当我转动相机并尝试旋转它时,它不会绕正确的轴旋转。
例如,我的向上向量是( 0, 1, 0 )。我可以完美地左右旋转我的相机,因为这个矢量是恒定的。我的相机无法工作的地方是当我试图绕其右轴旋转时。如果我向左或向右转动我的相机并绕右轴旋转,它通常会在一个不正确的奇怪方向上处理轴。这不应该是这种情况,因为我仍然可以完美地向右移动我的相机,它只是没有正确旋转。
下面是所有相关代码。我不确定为什么旋转是围绕 y 轴而不是其他任何轴。
// m_rotation is a Quaternion and rotation is a 4x4 view matrix
// Rotate around y-axis when left arrow pressed
// This works perfectly
if ( Input::IsKeyDown( Input::KEY_LEFT_ARROW ) ) {
Rotate( Vector3<float>( 0, -1, 0 ), m_sensitivity );
}
// When down arrow is pressed, rotate around right axis
// This rotates around strange axis
if ( Input::IsKeyDown( Input::KEY_DOWN_ARROW ) ) {
Rotate( m_rotation.GetRight( rotation ), m_sensitivity );
}
// Rotate methods
void Camera::Rotate( const Vector3<float> &axis, float angle ) {
Rotate( Quaternion( axis, angle ) );
}
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( quaternion * m_rotation ).Normalized() );
}
// Quaternion code
Quaternion( const Vector3<float> &vect, float angle ) {
float sinAngle = sinf( angle / 2.0f );
float cosAngle = cosf( angle / 2.0f );
( *this )[ 0 ] = vect[ 0 ] * sinAngle;
( *this )[ 1 ] = vect[ 1 ] * sinAngle;
( *this )[ 2 ] = vect[ 2 ] * sinAngle;
( *this )[ 3 ] = cosAngle;
}
inline Quaternion operator*( const Quaternion &quat ) const {
Quaternion ret;
ret[ 3 ] = ( ( *this )[ 3 ] * quat[ 3 ] ) - ( ( *this )[ 0 ] * quat[ 0 ] ) - ( ( *this )[ 1 ] * quat[ 1 ] ) - ( ( *this )[ 2 ] * quat[ 2 ] );
ret[ 0 ] = ( ( *this )[ 3 ] * quat[ 0 ] ) + ( ( *this )[ 0 ] * quat[ 3 ] ) + ( ( *this )[ 1 ] * quat[ 2 ] ) - ( ( *this )[ 2 ] * quat[ 1 ] );
ret[ 1 ] = ( ( *this )[ 3 ] * quat[ 1 ] ) + ( ( *this )[ 1 ] * quat[ 3 ] ) + ( ( *this )[ 2 ] * quat[ 0 ] ) - ( ( *this )[ 0 ] * quat[ 2 ] );
ret[ 2 ] = ( ( *this )[ 3 ] * quat[ 2 ] ) + ( ( *this )[ 2 ] * quat[ 3 ] ) + ( ( *this )[ 0 ] * quat[ 1 ] ) - ( ( *this )[ 1 ] * quat[ 0 ] );
return ret;
}
inline Vector3<float> GetRight( const Matrix4<float> &viewMatrix ) const {
return Vector3<float>( rotation[ 0 ][ 0 ], rotation[ 1 ][ 0 ], rotation[ 2 ][ 0 ] );
}
非常感谢任何帮助或建议。谢谢
经过几天尝试各种不同的事情后,我发现了问题所在。我忘记了四元数在相乘时是不可交换的。这导致相机以奇怪的方式旋转。所以要解决这个问题,我所要做的就是更改这段代码。
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( quaternion * m_rotation ).Normalized() );
}
为此...
void Camera::Rotate( const Quaternion &quaternion ) {
m_rotation = Quaternion( ( m_rotation * quaternion ).Normalized() );
}
我想要post这个,希望它能帮助将来的人。