旋转局部点时的错误结果
Wrong result when rotating a local point
我已经设置了一个旋转矩阵,它似乎运行良好,但是当我围绕一个旋转点旋转一个局部点时,我在获得正确的最终结果时遇到了问题。我的代码:
glm::mat4 clsBone::Rotate( float a_Pitch, float a_Yaw, float a_Roll )
{
glm::mat4 l_M = m_MatrixHandler->GetRotationMatrix( );
OutputDebugStringA( ( "Old Rotation Matrix: \n" +
std::to_string( l_M[ 0 ][ 0 ] ) + ", " + std::to_string( l_M[ 0 ][ 1 ] ) + ", " + std::to_string( l_M[ 0 ][ 2 ] ) + ", " + std::to_string( l_M[ 0 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 1 ][ 0 ] ) + ", " + std::to_string( l_M[ 1 ][ 1 ] ) + ", " + std::to_string( l_M[ 1 ][ 2 ] ) + ", " + std::to_string( l_M[ 1 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 2 ][ 0 ] ) + ", " + std::to_string( l_M[ 2 ][ 1 ] ) + ", " + std::to_string( l_M[ 2 ][ 2 ] ) + ", " + std::to_string( l_M[ 2 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 3 ][ 0 ] ) + ", " + std::to_string( l_M[ 3 ][ 1 ] ) + ", " + std::to_string( l_M[ 3 ][ 2 ] ) + ", " + std::to_string( l_M[ 3 ][ 3 ] ) + "\n" ).c_str( ) );
glm::mat4 l_RotMatrix = m_MatrixHandler->Rotate( a_Pitch, a_Yaw, a_Roll );
l_M = l_RotMatrix;
OutputDebugStringA( ( "New Rotation Matrix: \n" +
std::to_string( l_M[ 0 ][ 0 ] ) + ", " + std::to_string( l_M[ 0 ][ 1 ] ) + ", " + std::to_string( l_M[ 0 ][ 2 ] ) + ", " + std::to_string( l_M[ 0 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 1 ][ 0 ] ) + ", " + std::to_string( l_M[ 1 ][ 1 ] ) + ", " + std::to_string( l_M[ 1 ][ 2 ] ) + ", " + std::to_string( l_M[ 1 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 2 ][ 0 ] ) + ", " + std::to_string( l_M[ 2 ][ 1 ] ) + ", " + std::to_string( l_M[ 2 ][ 2 ] ) + ", " + std::to_string( l_M[ 2 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 3 ][ 0 ] ) + ", " + std::to_string( l_M[ 3 ][ 1 ] ) + ", " + std::to_string( l_M[ 3 ][ 2 ] ) + ", " + std::to_string( l_M[ 3 ][ 3 ] ) + "\n" ).c_str( ) );
glm::vec4 l_LocalPos = glm::vec4( m_EndJoint->m_Position - m_StartJoint->m_Position, 1 );
OutputDebugStringA( ( "Old Local Pos: " + std::to_string( l_LocalPos.x ) + ", " + std::to_string( l_LocalPos.y ) + ", " + std::to_string( l_LocalPos.z ) + "\n" ).c_str( ) );
glm::vec4 l_NewLocalPos = l_LocalPos * l_RotMatrix;
OutputDebugStringA( ( "New Local Pos: " + std::to_string( l_NewLocalPos.x ) + ", " + std::to_string( l_NewLocalPos.y ) + ", " + std::to_string( l_NewLocalPos.z ) + "\n" ).c_str( ) );
return l_RotMatrix;
}
glm::mat4 clsMatrixHandler::Rotate( float a_Pitch, float a_Yaw, float a_Roll )
{
glm::mat4 l_Rotx;
glm::mat4 l_Roty;
glm::mat4 l_Rotz;
PitchYawRollToXYZMatrices( a_Pitch, a_Yaw, a_Roll, l_Rotx, l_Roty, l_Rotz );
m_PitchYawRolls.push_back( glm::vec3( a_Pitch, a_Yaw, a_Roll ) );
glm::mat4 l_RotationMatrix = l_Rotx * l_Roty * l_Rotz;
m_RotationMatrix *= l_RotationMatrix;
m_TransformMatrix = m_RotationMatrix * m_TranslationMatrix;
return m_RotationMatrix;
}
结果:
Old Rotation Matrix:
1.000000, 0.000000, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.000000, -1.000000, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
New Rotation Matrix:
0.707107, 0.707107, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.707107, -0.707107, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
Old Local Pos: 0.000000, -40.000000, -0.000002
New Local Pos: -28.284271, 0.000000, 28.284271
怎么可能新的局部位置向对角线方向旋转了 90 度,而旋转矩阵在其局部 y 轴(世界 z 轴)上旋转了 45 度?
所以看来我在这里犯了一个错误。我将局部位置与旋转矩阵相乘,但我应该反过来乘以:
glm::vec4 l_NewLocalPos = l_RotMatrix * l_LocalPos;
这将输出:
Old Rotation Matrix:
1.000000, 0.000000, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.000000, -1.000000, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
New Rotation Matrix:
0.707107, 0.707107, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.707107, -0.707107, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
Old Local Pos: 0.000000, -40.000000, -0.000002
New Local Pos: 0.000000, 0.000000, -40.000000
这是有道理的:
从恒等旋转矩阵,我首先俯仰,将局部点从 (0, -40, 0) 移动到 (0, 0, -40),然后我偏航 45 度,但由于局部点在yaw旋转轴(局部y轴,世界z轴),点不动。
我已经设置了一个旋转矩阵,它似乎运行良好,但是当我围绕一个旋转点旋转一个局部点时,我在获得正确的最终结果时遇到了问题。我的代码:
glm::mat4 clsBone::Rotate( float a_Pitch, float a_Yaw, float a_Roll )
{
glm::mat4 l_M = m_MatrixHandler->GetRotationMatrix( );
OutputDebugStringA( ( "Old Rotation Matrix: \n" +
std::to_string( l_M[ 0 ][ 0 ] ) + ", " + std::to_string( l_M[ 0 ][ 1 ] ) + ", " + std::to_string( l_M[ 0 ][ 2 ] ) + ", " + std::to_string( l_M[ 0 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 1 ][ 0 ] ) + ", " + std::to_string( l_M[ 1 ][ 1 ] ) + ", " + std::to_string( l_M[ 1 ][ 2 ] ) + ", " + std::to_string( l_M[ 1 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 2 ][ 0 ] ) + ", " + std::to_string( l_M[ 2 ][ 1 ] ) + ", " + std::to_string( l_M[ 2 ][ 2 ] ) + ", " + std::to_string( l_M[ 2 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 3 ][ 0 ] ) + ", " + std::to_string( l_M[ 3 ][ 1 ] ) + ", " + std::to_string( l_M[ 3 ][ 2 ] ) + ", " + std::to_string( l_M[ 3 ][ 3 ] ) + "\n" ).c_str( ) );
glm::mat4 l_RotMatrix = m_MatrixHandler->Rotate( a_Pitch, a_Yaw, a_Roll );
l_M = l_RotMatrix;
OutputDebugStringA( ( "New Rotation Matrix: \n" +
std::to_string( l_M[ 0 ][ 0 ] ) + ", " + std::to_string( l_M[ 0 ][ 1 ] ) + ", " + std::to_string( l_M[ 0 ][ 2 ] ) + ", " + std::to_string( l_M[ 0 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 1 ][ 0 ] ) + ", " + std::to_string( l_M[ 1 ][ 1 ] ) + ", " + std::to_string( l_M[ 1 ][ 2 ] ) + ", " + std::to_string( l_M[ 1 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 2 ][ 0 ] ) + ", " + std::to_string( l_M[ 2 ][ 1 ] ) + ", " + std::to_string( l_M[ 2 ][ 2 ] ) + ", " + std::to_string( l_M[ 2 ][ 3 ] ) + "\n" +
std::to_string( l_M[ 3 ][ 0 ] ) + ", " + std::to_string( l_M[ 3 ][ 1 ] ) + ", " + std::to_string( l_M[ 3 ][ 2 ] ) + ", " + std::to_string( l_M[ 3 ][ 3 ] ) + "\n" ).c_str( ) );
glm::vec4 l_LocalPos = glm::vec4( m_EndJoint->m_Position - m_StartJoint->m_Position, 1 );
OutputDebugStringA( ( "Old Local Pos: " + std::to_string( l_LocalPos.x ) + ", " + std::to_string( l_LocalPos.y ) + ", " + std::to_string( l_LocalPos.z ) + "\n" ).c_str( ) );
glm::vec4 l_NewLocalPos = l_LocalPos * l_RotMatrix;
OutputDebugStringA( ( "New Local Pos: " + std::to_string( l_NewLocalPos.x ) + ", " + std::to_string( l_NewLocalPos.y ) + ", " + std::to_string( l_NewLocalPos.z ) + "\n" ).c_str( ) );
return l_RotMatrix;
}
glm::mat4 clsMatrixHandler::Rotate( float a_Pitch, float a_Yaw, float a_Roll )
{
glm::mat4 l_Rotx;
glm::mat4 l_Roty;
glm::mat4 l_Rotz;
PitchYawRollToXYZMatrices( a_Pitch, a_Yaw, a_Roll, l_Rotx, l_Roty, l_Rotz );
m_PitchYawRolls.push_back( glm::vec3( a_Pitch, a_Yaw, a_Roll ) );
glm::mat4 l_RotationMatrix = l_Rotx * l_Roty * l_Rotz;
m_RotationMatrix *= l_RotationMatrix;
m_TransformMatrix = m_RotationMatrix * m_TranslationMatrix;
return m_RotationMatrix;
}
结果:
Old Rotation Matrix:
1.000000, 0.000000, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.000000, -1.000000, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
New Rotation Matrix:
0.707107, 0.707107, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.707107, -0.707107, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
Old Local Pos: 0.000000, -40.000000, -0.000002
New Local Pos: -28.284271, 0.000000, 28.284271
怎么可能新的局部位置向对角线方向旋转了 90 度,而旋转矩阵在其局部 y 轴(世界 z 轴)上旋转了 45 度?
所以看来我在这里犯了一个错误。我将局部位置与旋转矩阵相乘,但我应该反过来乘以:
glm::vec4 l_NewLocalPos = l_RotMatrix * l_LocalPos;
这将输出:
Old Rotation Matrix:
1.000000, 0.000000, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.000000, -1.000000, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
New Rotation Matrix:
0.707107, 0.707107, 0.000000, 0.000000
0.000000, -0.000000, 1.000000, 0.000000
0.707107, -0.707107, -0.000000, 0.000000
0.000000, 0.000000, 0.000000, 1.000000
Old Local Pos: 0.000000, -40.000000, -0.000002
New Local Pos: 0.000000, 0.000000, -40.000000
这是有道理的: 从恒等旋转矩阵,我首先俯仰,将局部点从 (0, -40, 0) 移动到 (0, 0, -40),然后我偏航 45 度,但由于局部点在yaw旋转轴(局部y轴,世界z轴),点不动。