四元数到轴的角度
Quaternion to axis angles
我尝试根据从传感器获取的数据实现 3D 对象旋转。我有四元数 w,x,y,z 的数据,但要使用
glRotatef(xRot,1,0,0);
glRotatef(yRot,0,1,0);
glRotatef(zRot,0,0,1);
我需要 x、y、z 的旋转角度来获得这些 this 教程和 Qt 中的 QQuaternion IDE 我写下面的代码:
void quaternion2angle(float w,float x,float y,float z)
{
// Code for quaternion to rotation around axis X Y Z
QQuaternion ql;
ql.setScalar(w);
ql.setX(x);
ql.setY(y);
ql.setZ(z);
if (ql.scalar()>1) ql.normalize();
angle= 2 * acos(ql.scalar());
s= sqrt(1-ql.scalar()*ql.scalar());
if (s<0.001) {
xRot=ql.x();
yRot=ql.y();
zRot=ql.z();
}else
{
xRot=ql.x()/s;
yRot=ql.y()/s;
zRot=ql.y()/s;
}
}
然而,当我用上面的代码旋转时,运动不正确,方向不同,甚至传感器向左移动 90 度,它向另一个方向移动的很少。
当我搜索四元数和 openGL 时,一些人给出了关于可以在 openGL 上使用 glMultMatrixf(quaternion.toMatrix)
在相机上完成旋转的建议,但我无法将四元数转换为矩阵 GLFloat,它在 glMultMatrixf 中作为参数请求。 QQuaternion class 云将四元数转换为 QVector4D 并给出错误变量转换。可能做的方法不对,代码如下:
void paintGL()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// adjust camera
glTranslatef(0.0f, 0.0f, -8.0f);
glMultMatrixf(quMatrix.constData());
glRotatef(90,0,1,0);
// no need below
//glRotatef(xRot,1,0,0);
//glRotatef(yRot,0,1,0);
//glRotatef(zRot,0,0,1);
obj.Draw();
glDisable(GL_DEPTH_TEST);
}
void setquMatrix(QVector4D qvec)
{
// read data w,x,y,z
qvec=quaternionRotation(w,x,y,z);
quMatrix=qvec;
}
// Using quaternion and glMultMatrixf
QVector4D quaternionRotation(float w,float x,float y,float z)
{
QQuaternion qlm;
qlm.setScalar(w);
qlm.setX(x);
qlm.setY(y);
qlm.setZ(z);
qlm.normalize();
return qlm.toVector4D();
}
// after taking value above I set matrix which is multiplied with glMultMatrixf
总而言之,我如何解决这些四元数的问题,以便使用 openGL 解释对象上的旋转?
您不应该转换为轴角度,而是直接创建旋转矩阵并使用 glMultMatrix。
可以通过以下方式将四元数转换为矩阵:(sourced from my previous code)
inline QMatrix4x4 quatToMat(QQuaternion q)
{
//based on algorithm on wikipedia
// http://en.wikipedia.org/wiki/Rotation_matrix#Quaternion
float w = q.scalar ();
float x = q.x();
float y = q.y();
float z = q.z();
float n = q.lengthSquared();
float s = n == 0? 0 : 2 / n;
float wx = s * w * x, wy = s * w * y, wz = s * w * z;
float xx = s * x * x, xy = s * x * y, xz = s * x * z;
float yy = s * y * y, yz = s * y * z, zz = s * z * z;
float m[16] = { 1 - (yy + zz), xy + wz , xz - wy ,0,
xy - wz , 1 - (xx + zz), yz + wx ,0,
xz + wy , yz - wx , 1 - (xx + yy),0,
0 , 0 , 0 ,1 };
QMatrix4x4 result = QMatrix4x4(m,4,4);
result.optimize ();
return result;
}
然后您可以使用 constData 成员传递到 multMatrix 中:
QMatrix4x4 rotation = quatToMat(quat);
glMultMatrix(rotation.constData());
我尝试了一些其他方法 implementation.I 直接将四元数转换为 X Y Z 轴角度。我希望它对其他人也有用:
float q0 = q0Buffer.at(i);
float q1 = q1Buffer.at(i);
float q2 = q2Buffer.at(i);
float q3 = q3Buffer.at(i);
float angle_rad = acos(q0) * 2;
float angle_deg = angle_rad * 180 / PI;
float x = q1 / sin(angle_rad/2);
float y = q2 / sin(angle_rad/2);
float z = q3 / sin(angle_rad/2);
我尝试根据从传感器获取的数据实现 3D 对象旋转。我有四元数 w,x,y,z 的数据,但要使用
glRotatef(xRot,1,0,0);
glRotatef(yRot,0,1,0);
glRotatef(zRot,0,0,1);
我需要 x、y、z 的旋转角度来获得这些 this 教程和 Qt 中的 QQuaternion IDE 我写下面的代码:
void quaternion2angle(float w,float x,float y,float z)
{
// Code for quaternion to rotation around axis X Y Z
QQuaternion ql;
ql.setScalar(w);
ql.setX(x);
ql.setY(y);
ql.setZ(z);
if (ql.scalar()>1) ql.normalize();
angle= 2 * acos(ql.scalar());
s= sqrt(1-ql.scalar()*ql.scalar());
if (s<0.001) {
xRot=ql.x();
yRot=ql.y();
zRot=ql.z();
}else
{
xRot=ql.x()/s;
yRot=ql.y()/s;
zRot=ql.y()/s;
}
}
然而,当我用上面的代码旋转时,运动不正确,方向不同,甚至传感器向左移动 90 度,它向另一个方向移动的很少。
当我搜索四元数和 openGL 时,一些人给出了关于可以在 openGL 上使用 glMultMatrixf(quaternion.toMatrix)
在相机上完成旋转的建议,但我无法将四元数转换为矩阵 GLFloat,它在 glMultMatrixf 中作为参数请求。 QQuaternion class 云将四元数转换为 QVector4D 并给出错误变量转换。可能做的方法不对,代码如下:
void paintGL()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// adjust camera
glTranslatef(0.0f, 0.0f, -8.0f);
glMultMatrixf(quMatrix.constData());
glRotatef(90,0,1,0);
// no need below
//glRotatef(xRot,1,0,0);
//glRotatef(yRot,0,1,0);
//glRotatef(zRot,0,0,1);
obj.Draw();
glDisable(GL_DEPTH_TEST);
}
void setquMatrix(QVector4D qvec)
{
// read data w,x,y,z
qvec=quaternionRotation(w,x,y,z);
quMatrix=qvec;
}
// Using quaternion and glMultMatrixf
QVector4D quaternionRotation(float w,float x,float y,float z)
{
QQuaternion qlm;
qlm.setScalar(w);
qlm.setX(x);
qlm.setY(y);
qlm.setZ(z);
qlm.normalize();
return qlm.toVector4D();
}
// after taking value above I set matrix which is multiplied with glMultMatrixf
总而言之,我如何解决这些四元数的问题,以便使用 openGL 解释对象上的旋转?
您不应该转换为轴角度,而是直接创建旋转矩阵并使用 glMultMatrix。
可以通过以下方式将四元数转换为矩阵:(sourced from my previous code)
inline QMatrix4x4 quatToMat(QQuaternion q)
{
//based on algorithm on wikipedia
// http://en.wikipedia.org/wiki/Rotation_matrix#Quaternion
float w = q.scalar ();
float x = q.x();
float y = q.y();
float z = q.z();
float n = q.lengthSquared();
float s = n == 0? 0 : 2 / n;
float wx = s * w * x, wy = s * w * y, wz = s * w * z;
float xx = s * x * x, xy = s * x * y, xz = s * x * z;
float yy = s * y * y, yz = s * y * z, zz = s * z * z;
float m[16] = { 1 - (yy + zz), xy + wz , xz - wy ,0,
xy - wz , 1 - (xx + zz), yz + wx ,0,
xz + wy , yz - wx , 1 - (xx + yy),0,
0 , 0 , 0 ,1 };
QMatrix4x4 result = QMatrix4x4(m,4,4);
result.optimize ();
return result;
}
然后您可以使用 constData 成员传递到 multMatrix 中:
QMatrix4x4 rotation = quatToMat(quat);
glMultMatrix(rotation.constData());
我尝试了一些其他方法 implementation.I 直接将四元数转换为 X Y Z 轴角度。我希望它对其他人也有用:
float q0 = q0Buffer.at(i);
float q1 = q1Buffer.at(i);
float q2 = q2Buffer.at(i);
float q3 = q3Buffer.at(i);
float angle_rad = acos(q0) * 2;
float angle_deg = angle_rad * 180 / PI;
float x = q1 / sin(angle_rad/2);
float y = q2 / sin(angle_rad/2);
float z = q3 / sin(angle_rad/2);