Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 如何使用glm quat防止万向节锁_Opengl_Camera_Locking_Quaternions_Glm Math - Fatal编程技术网

Opengl 如何使用glm quat防止万向节锁

Opengl 如何使用glm quat防止万向节锁,opengl,camera,locking,quaternions,glm-math,Opengl,Camera,Locking,Quaternions,Glm Math,我正在尝试实现一个opengl相机,它围绕指定的世界坐标旋转相机的位置。我尝试使用glm数学库来实现这一点;我的代码如下 void Camera::dolly(double angle_x, double angle_y, const double& loc_x, const double& loc_y, const double& loc_z, const double& dt) { glm::vec3 target = glm::vec3(loc_x,l

我正在尝试实现一个opengl相机,它围绕指定的世界坐标旋转相机的位置。我尝试使用glm数学库来实现这一点;我的代码如下

void Camera::dolly(double angle_x, double angle_y, const double& loc_x, const double& loc_y, const double& loc_z, const double& dt) {

  glm::vec3 target = glm::vec3(loc_x,loc_y,loc_z);

  glm::quat Q;glm::vec3 axis0(0.0f,1.0f,0.0f);
  glm::quat R;glm::vec3 axis1(1.0f,0.0f,0.0f);

  position = position - target;

  //glm::normalize(axis0);
  glm::normalize(axis1);

  Q = glm::gtx::quaternion::angleAxis( float(angle_x ), axis0 );;
  R = glm::gtx::quaternion::angleAxis( float(andl_y ), axis1 );;

  glm::quat final =  R*Q;

  position =  final * position;

  position = position + target;
  cout << "\tPosition: " << position.x << " " << position.y << " " << position.z <<endl;
}
void摄影机::推拉(双角度x,双角度y,常数双和定位x,常数双和定位y,常数双和定位z,常数双和dt){
glm::vec3 target=glm::vec3(loc_x,loc_y,loc_z);
glm::quat Q;glm::vec3 axis0(0.0f,1.0f,0.0f);
glm::quat R;glm::vec3 axis1(1.0f,0.0f,0.0f);
位置=位置-目标;
//glm::规格化(axis0);
glm::规范化(axis1);
Q=glm::gtx::四元数::angleAxis(浮动(角度x),axis0);;
R=glm::gtx::四元数::角度轴(浮动(andl_y),轴1);;
glm::quat final=R*Q;
位置=最终*位置;
位置=位置+目标;
cout注:复制自

你所做的就是用四元数有效地实现欧拉角,这没有帮助

欧拉角的问题在于,当计算矩阵时,每个角度都与之前矩阵的旋转有关。您需要的是获取对象的当前方向,并沿某个轴应用旋转,从而生成新的方向

你不能用欧拉角。你可以用矩阵,也可以用四元数(因为它们只是矩阵的旋转部分)。但是你不能假装它们是欧拉角

这是通过根本不存储角度来实现的。相反,您只有一个表示对象当前方向的四元数。当您决定对其应用旋转(某个轴的某个角度)时,则构造一个四元数,该四元数表示绕该轴旋转的角度。然后将该四元数与当前方向四元数右乘,生成一个新的当前方向


渲染对象时,使用当前方向作为…方向。

从问题中复制:

编辑2013年5月26日我是如何解决这个问题的:

我的代码的问题是,在渲染我使用的场景时:

    matrix = glm::lookAt(position,looking_at, upDirection);
然后,我使用这个矩阵将场景放入相机的透视图中/基本上是渲染相机。但是,当我调用我的“camera::dolly”(实际上不应该称为dolly,因为我的目标是旋转相机)函数时,我旋转了相机位置,而没有旋转/更新向上方向(初始化为(0,1,0))变量。这导致了我描述的“起伏”问题,因为轴(1,0,0)旋转的结果是改变向上方向所指向的方向。新的 代码如下:

glm::quat orient = glm::gtx::quaternion::angleAxis(float(0),0.0f, 0.0f, 1.0f);
无效摄影机:旋转(双角度x、双角度y、常数双和位置x、常数双和位置y、常数双和位置z、常数双和位置双和dt){ glm::vec3 target=glm::vec3(loc_x,loc_y,loc_z)


1) 好了,dolly的意思是在直线上移动相机。2)你说的“起伏”是什么意思?x和y从何而来?现在还不清楚代码是如何产生你想要的结果的。1)原谅命名函数名的错误;2)我说的“起伏”是指当我使用Q=glm::gtx::四元数::angleAxis旋转位置时(float(angle_x),axis0);围绕轴(0,1,0)的旋转是完全圆形的,并且会继续,但是当我添加旋转轴(1,0,0)时突然,从该轴的旋转导致相机位置以意外的方式移动。感谢您的回答。我现在的问题是:如果我将所有方向表示为四元数,并使用新方向角度和方向轴应用新方向,然后将其应用于上一个方向以获得新方向(很抱歉这么长的一句话),然后我能把我的四元数转换成mat4并且仍然没有万向节锁吗?@ukaku:这是一个新问题,所以你应该用“提问”按钮提问。这也是一个在问我们之前你应该试着实现的问题。
position = position - target;

angle_x *= dt;
angle_y *= dt;

glm::quat old_orient = orient;

glm::normalize(orient);
glm::quat q_x_axis = glm::gtx::quaternion::angleAxis(float(angle_y),1.0f, 0.0f, 0.0f) ;
glm::quat q_y_axis = glm::gtx::quaternion::angleAxis(float(angle_x), 0.0f, 1.0f, 0.0f);

orient = orient * q_x_axis * q_y_axis;

upDirection = upDirection * orient;
position = position * (orient);

orient = old_orient;

position = position + target;