gpt4 book ai didi

c++ - 小四元数相机错误? (在 Z 轴上略微旋转)

转载 作者:行者123 更新时间:2023-11-30 04:17:45 24 4
gpt4 key购买 nike

当我顺时针旋转鼠标时,屏幕上的对象会逆时针旋转,反之亦然。这不是一个大错误,但它似乎是错误的。

我将 Eigen 用于四元数和 vector ,因此问题应该属于我发布的代码。

相机:

#include <Eigen/Dense>
#include <cstring>
#include <math.h>

typedef Eigen::Vector3f vec3;
typedef Eigen::Quaternionf Quaternion;

namespace vec
{
//
// Constants
//
const vec3 i(1, 0, 0);
const vec3 j(0, 1, 0);
const vec3 k(0, 0, 1);
const vec3 zero(0, 0, 0);
const vec3 ones(1, 1, 1);
}

class Camera
{
void init();

void moveX(float dist);
void moveY(float dist);
void moveZ(float dist);

void rotateX(float radians); //yaw
void rotateY(float radians); //pitch
void rotateZ(float radians); //roll

void moveLeft(float dist);
void moveForward(float dist);
void moveUp(float dist);

void rotateLeft(float radians); //yaw
void rotateUp(float radians); //pitch
void rollLeft(float radians); //roll

void setPosition(const vec3 &pos);
void setDirection(const vec3 &dir);
void lookAt(const vec3 &pos); //changes direction

// Camera Vectors
vec3 left() const;
vec3 right() const;
vec3 up() const;
vec3 down() const;
vec3 forward() const;
vec3 backward() const;
const vec3 &pos() const;

protected:
Quaternion mRotation;
vec3 mPos;

void rotateL(float radians, const vec3 &axis);
void rotateR(float radians, const vec3 &axis);
};

实现:

void Camera::init()
{
mPos.setZero();
mRotation.setIdentity();
}

inline void Camera::rotateL(float radians, const vec3 &axis)
{
Quaternion q(Eigen::AngleAxis<float>(radians, axis));
mRotation = (q * mRotation).normalized();
}

inline void Camera::rotateR(float radians, const vec3 &axis)
{
Quaternion q(Eigen::AngleAxis<float>(radians, axis));
mRotation = (mRotation * q).normalized();
}

void Camera::moveX(float dist)
{
mPos.x() += dist;
}

void Camera::moveY(float dist)
{
mPos.y() += dist;
}

void Camera::moveZ(float dist)
{
mPos.z() += dist;
}

void Camera::rotateX(float radians)
{
rotateL(radians, vec::i);
}

void Camera::rotateY(float radians)
{
rotateL(radians, vec::j);
}

void Camera::rotateZ(float radians)
{
rotateL(radians, vec::k);
}

void Camera::moveLeft(float dist)
{
mPos += dist * left();
}

void Camera::moveUp(float dist)
{
mPos += dist * up();
}

void Camera::moveForward(float dist)
{
mPos += dist * forward();
}

void Camera::rotateLeft(float radians)
{
rotateL(radians, up());
}

void Camera::rotateUp(float radians)
{
rotateL(radians, left());
}

void Camera::rollLeft(float radians)
{
rotateL(radians, forward());
}

void Camera::setPosition(const vec3 &pos)
{
mPos = pos;
}

void Camera::setDirection(const vec3 &dir)
{
mRotation.setFromTwoVectors(vec::k, dir);
mRotation.normalize();
}

void Camera::lookAt(const vec3 &pos)
{
setDirection(mPos - pos);
}

// Camera Vectors
vec3 Camera::left() const
{
return mRotation._transformVector(vec::i);
}

vec3 Camera::right() const
{
return -left();
}

vec3 Camera::up() const
{
return mRotation._transformVector(vec::j);
}

vec3 Camera::down() const
{
return -up();
}

vec3 Camera::forward() const
{
return mRotation._transformVector(vec::k);
}

vec3 Camera::backward() const
{
return -forward();
}

const vec3 &Camera::pos() const
{
return mPos;
}

更新函数:

void App::onMouseMotion(int x, int y, int dx, int dy)
{
cam.rotateUp(dy * ROTATE_SCALE);
cam.rotateLeft(-dx * ROTATE_SCALE);
}


void App::update()
{
cam.moveLeft(((int)Keyboard::isKeyDown('a')) * MOVE_SCALE * mDt);
cam.moveLeft(((int)Keyboard::isKeyDown('d')) * -MOVE_SCALE * mDt);
cam.moveForward(((int)Keyboard::isKeyDown('w')) * MOVE_SCALE * mDt);
cam.moveForward(((int)Keyboard::isKeyDown('s')) * -MOVE_SCALE * mDt);

cam.rollLeft(((int)Keyboard::isKeyDown('q')) * -ROLL_SCALE * mDt);
cam.rollLeft(((int)Keyboard::isKeyDown('e')) * ROLL_SCALE * mDt);
}

我读到一些问题是由于在不正确的一侧组合四元数...例如 QR 而不是 RQ。按照建议切换 X 轴 here绝对没有帮助。

如果您对我的实现提出任何建议,我也将不胜感激。我考虑过切换到矩阵进行旋转,但对它们进行归一化和组合的成本更高。

最佳答案

当您重复应用旋转时,这是正常行为。你可以在一些允许自由旋转的应用程序或游戏中看到它。

  1. 将 ARM 放在身前。 “前进”是你的手指。 “上”是手背。
  2. 将其向上倾斜约 30°。
  3. 从新的方向向左倾斜大约 30°。
  4. 从新方向开始,将其向下倾斜约 30°。
  5. 从新方向向右倾斜约 30°。

您看到的是手现在朝向大致相同的方向,但略微逆时针转动。

这对人类来说可能看起来很奇怪,因为我们习惯于固定的向上方向。

关于c++ - 小四元数相机错误? (在 Z 轴上略微旋转),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16869892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com