【问题标题】:Quaternion rotation does not work四元数旋转不起作用
【发布时间】:2017-06-13 23:25:55
【问题描述】:

我想制作一个基于四元数的相机。在互联网上我发现了这个: https://www.gamedev.net/resources/_/technical/math-and-physics/a-simple-quaternion-based-camera-r1997

我从中获取了代码:

typedef struct { float w, x, y, z; } quaternion;

double length(quaternion quat)
{
  return sqrt(quat.x * quat.x + quat.y * quat.y +
              quat.z * quat.z + quat.w * quat.w);
}

quaternion normalize(quaternion quat)
{
  double L = length(quat);

  quat.x /= L;
  quat.y /= L;
  quat.z /= L;
  quat.w /= L;

  return quat;
}

quaternion conjugate(quaternion quat)
{
  quat.x = -quat.x;
  quat.y = -quat.y;
  quat.z = -quat.z;
  return quat;
}

quaternion mult(quaternion A, quaternion B)
{
  quaternion C;

  C.x = A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
  C.y = A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
  C.z = A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
  C.w = A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
  return C;
}

void RotateCamera(double Angle, double x, double y, double z)
{
  quaternion temp, quat_view, result;

  temp.x = x * sin(Angle/2);
  temp.y = y * sin(Angle/2);
  temp.z = z * sin(Angle/2);
  temp.w = cos(Angle/2);

  quat_view.x = View.x;
  quat_view.y = View.y;
  quat_view.z = View.z;
  quat_view.w = 0;

  result = mult(mult(temp, quat_view), conjugate(temp));
  View.x = result.x;
  View.y = result.y;
  View.z = result.z;
}

但是我在尝试实现这一行时遇到了问题:

gluLookAt(Position.x, Position.y, Position.z,
      View.x, View.y, View.z, Up.x, Up.y, Up.z).

因为我不知道用什么作为“向上”,所以我尝试使用 0,0,0,但它只显示黑屏。非常感谢任何帮助!

编辑:

在这个网站的某个地方,我发现了类似的东西,可以将四元数转换为矩阵。如何使用glMultMatrixf(); 使用这个矩阵

float *quat_to_matrix(quaternion quat) {
    float matrix[16];
    double qx=quat.x;
    double qy=quat.y;
    double qz=quat.z;
    double qw=quat.w;
    const double n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw);
    qx *= n;
    qy *= n;
    qz *= n;
    qw *= n;
    matrix={1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
    2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
    2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f};
    return matrix;
}

编辑 2:

我使用了glMultMatrixf(),它成功了。但我终于发现,RotateCamera() 的输出使我的四元数为零? 有人知道这种方法有什么问题吗:

void RotateCamera(double Angle, double x, double y, double z)
{
  quaternion temp, quat_view, result;

  temp.x = x * sin(Angle/2);
  temp.y = y * sin(Angle/2);
  temp.z = z * sin(Angle/2);
  temp.w = cos(Angle/2);

  quat_view.x = View.x;
  quat_view.y = View.y;
  quat_view.z = View.z;
  quat_view.w = 0;

  result = mult(mult(temp, quat_view), conjugate(temp));
  View.x = result.x;
  View.y = result.y;
  View.z = result.z;
}

【问题讨论】:

    标签: c++ c opengl 3d rotation


    【解决方案1】:

    这对我来说真的没有意义,但无论如何我都会尝试回答:D ...你为什么不使用 glRotatef(angle,0,0,1) 旋转它来旋转 z 轴,由于这个函数的定义如下: glRotatef(angle,x_axis,y_axis,z_axis) 最后3个参数clamp到[0,1]。

    对于第二个问题,据我所知,您应该减小角度,无论如何您都可以尝试使用该功能来亲眼看看;)。

    【讨论】:

    • 我的问题是google.de/… Gimbal Lock。我在数学网站上问了一个类似的问题:有没有一种简单的方法可以克服 Gimbal Lock 而不是四元数旋转?
    • 我不这么认为,因为我很困惑你遇到的同样的问题......根据我之前获得的经验,我也发现很难在相机旋转和移动中实现四元数 * 。我尝试使用 View 矩阵,然后先进行平移,然后进行 2 次旋转(y 轴然后 x 轴),这在某种程度上是有效的,但是你被困在一个固定的 y 位置,这意味着你不能使用相机视图向下或向上 :) .. .
    • 哦,我没有提到...另一种方法是使用足以进行实验的欧拉角。您应该查看此链接:learnopengl.com/#!Getting-started/Camera 这是我学习如何实现我的第一个摄像头系统的地方...感谢该网站的作者 :) ...我认为这肯定会对您有所帮助 :D跨度>
    • 是的,但我没有glm
    • 如果你想学习图形,我可以说 glm 非常有用。它有很大帮助:)。你可以在这里得到它:glm.g-truc.net/0.9.8/index.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 2019-02-10
    • 2017-05-14
    • 2020-04-11
    相关资源
    最近更新 更多