我尝试根据从传感器获取的数据实现3D对象旋转。我有数据作为四元数w,x,y,z但是要使用
glRotatef(xRot,1,0,0);
glRotatef(yRot,0,1,0);
glRotatef(zRot,0,0,1);
我需要跨越x,y,z的旋转角度,以便在Qt IDE中使用this教程和QQuaternion获取这些,我在下面编写代码:
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时,有些人提出了关于旋转的建议可以通过使用glMultMatrixf(quaternion.toMatrix)
在openGL上的相机上完成,但我无法将四元数转换为矩阵GLFloat,它是glMultMatrixf中作为参数请求的。 QQuaternion类云将四元数转换为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解释对象旋转的问题?
答案 0 :(得分:1)
您不应该转换为轴角,而是直接创建旋转矩阵并使用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());
答案 1 :(得分:1)
我尝试了其他一些实现方法。我直接将四元数转换为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);