Кватернионы в программировании игр. (комментарии)
Это сообщение сгенерировано автоматически.
там функция, которая переделывает матрицу поворота в кватернион работает не правильно!
Может знает кто нибудь как правильно?
Я тут посмотрел D3DXQuaternionRotationMatrix котрая в d3dx9.lib d3dxmath.obj получилась примерно такая логика:
struct D3DXQUATERNION * D3DXQuaternionRotationMatrix(struct D3DXQUATERNION *pD3DQuaternion,
struct D3DXMATRIX const *pD3DMatrix)
{
float Diag, Diag1, Diag2, Diag3;
Diag = pD3DMatrix->_22 + pD3DMatrix->_11 + pD3DMatrix->_33;
if(Diag > 0){
Diag = (sqrt(Diag+1.0f))*0.5f;
pD3DQuaternion->w = Diag;
Diag = 0.25f/Diag;
pD3DQuaternion->x = (pD3DMatrix->_23 - pD3DMatrix->_32)*Diag;
pD3DQuaternion->y = (pD3DMatrix->_31 - pD3DMatrix->_13)*Diag;
pD3DQuaternion->z = (pD3DMatrix->_12 - pD3DMatrix->_21)*Diag;
}
else{
Diag1 = pD3DMatrix->_11 - pD3DMatrix->_22 - pD3DMatrix->_33;
Diag2 = pD3DMatrix->_22 - pD3DMatrix->_11 - pD3DMatrix->_33;
Diag3 = pD3DMatrix->_22 + pD3DMatrix->_11 - pD3DMatrix->_33;
if(Diag2 > Diag1)
Diag = Diag2;
else
Diag = Diag1;
if(Diag3 > Diag)
Diag = Diag3;
if(Diag == Diag1){
Diag = (sqrt(Diag + 1.0f))*0.5f;
pD3DQuaternion->x = Diag;
Diag = 0.25f/Diag;
pD3DQuaternion->y = Diag*(pD3DMatrix->_21 + pD3DMatrix->_12);
pD3DQuaternion->z = Diag*(pD3DMatrix->_31 + pD3DMatrix->_13);
pD3DQuaternion->w = Diag*(pD3DMatrix->_23 - pD3DMatrix->_32);
}
if(Diag == Diag2){
Diag = (sqrt(Diag + 1.0f))*0.5f;
pD3DQuaternion->y = Diag;
Diag = 0.25f/Diag;
pD3DQuaternion->z = Diag*(pD3DMatrix->_32 + pD3DMatrix->_23);
pD3DQuaternion->x = Diag*(pD3DMatrix->_12 + pD3DMatrix->_21);
pD3DQuaternion->w = Diag*(pD3DMatrix->_31 - pD3DMatrix->_13);
}
if(Diag == Diag3){
Diag = (sqrt(Diag + 1.0f))*0.5f;
pD3DQuaternion->z = Diag;
Diag = 0.25f/Diag;
pD3DQuaternion->x = Diag*(pD3DMatrix->_13 + pD3DMatrix->_31);
pD3DQuaternion->y = Diag*(pD3DMatrix->_23 + pD3DMatrix->_32);
pD3DQuaternion->w = Diag*(pD3DMatrix->_12 - pD3DMatrix->_21);
}
}
return pD3DQuaternion;
}
Так правильно?
В разделе Основные операции и свойства кватернионов опечатка:
>qq' = [ww' – v·v', vxv' + wv' + w'v]
>, где x - скалярное произведение, а · — векторное.
but-cher
поправил.
Вариант, написанный ранее мной, считал не совсем то, что нужно. Перепроверив его я убедился в том, что автор был абсолютно прав в следующих строках:
tr = m[0][0] + m[1][1] + m[2][2]; s = sqrt (tr + 1.0); quat->w = s / 2.0; s = 0.5 / s; quat->x = ( m[1][2] - m[2][1]) * s; quat->y = ( m[2][0] - m[0][2]) * s; quat->z = ( m[0][1] - m[1][0]) * s;
Одно непонятно: откуда получили выражение для tr < 0. Если бы автор прокомментировал это место, был бы очень признателен.
Нашел ошибку в функции QuaternionToMatrix. Там автор получает транспонированную матрицу. Т.е. для получения правильной матрицы полученную матрицу надо транспонировать.
Вообще, для функции преобразования матрицы в кватернион я подобрал метод, работающий при любых значениях tr.
void MatrixToQuaternion(Quaternion * quat, float m[4][4])
{
float tr;
tr = m[0][0] + m[1][1] + m[2][2];
quat->w = 0.5 * sqrt(1.0 + tr);
quat->x = 0.5 * sqrt(1.0 + m[0][0] + m[0][0] - tr);
quat->y = 0.5 * sqrt(1.0 + m[1][1] + m[1][1] - tr);
quat->z = 0.5 * sqrt(1.0 + m[2][2] + m[2][2] - tr);
if (m[1][2] < m[2][1]) quat->x = - quat->x;
if (m[2][0] < m[0][2]) quat->y = - quat->y;
if (m[0][1] < m[1][0]) quat->z = - quat->z;
}
По-моему здесь ошибка
q^(–1)=q*/norm(q)
если исходить из формулы
norm(q) = sqrt(w^2+x^2+y^2+z^2)
или
norm(q)=sqrt(qq*)
тогда наверно будет правильней написать
q^(–1)=q*/(norm(q)^2)
народ, а скажите кватернион центр поворота содержит или нет? а то я не понял этго момента
Поворот вокруг центра системы координат.
а никто не знает можно ли из матрицы выделить центр поворота?
Barbar1an
Какова размерность матрицы?
ну стандартная 4 на 4
Barbar1an
Поиск: декомпозиция матрицы.
В разделе Что это такое судя из контекста опечатка:
, где i2= j2 = z2 = –1.
должно быть:
i2= j2 = k2= –1.
Тема в архиве.