gpt4 book ai didi

c++ - 将 OpenGL 坐标系统转换为自定义并返回

转载 作者:行者123 更新时间:2023-11-30 04:44:50 25 4
gpt4 key购买 nike

我的任务是使用 OpenGL 在地面上绘制 3D 对象。我使用 Y 轴向上的 OpenGL 左手坐标系。但是 3D 物体和相机轨道物体应该使用具有以下属性的不同坐标系:

  • XY平面为地平面;
  • Z轴向上;
  • Y轴为“北”;
  • X轴为“东”;
  • 方位(或水平)角为[0, 360]度;
  • 仰角(或垂直)角与 XY 平面成 [0, 90] 度。最终用户使用方位角和仰角围绕某个中心旋转相机。所以我编写了以下代码以将球坐标转换为四元数:
//polar: x - radius, y - horizontal angle, z - vertical 
QQuaternion CoordinateSystemGround::fromPolarToQuat(const QVector3D& polar) const {
QQuaternion dest = QQuaternion::fromEulerAngles({0, polar.y(), polar.z()});
//convert user coord system back to OpenGL by rotation around X-axis
QQuaternion orig = QQuaternion::fromAxisAndAngle(1, 0, 0, -90);
return dest * orig;
}

返回:

    QVector3D CoordinateSystemGround::fromQuatToPolar(const QQuaternion& q) const {
//convert OpenGL coord system to destination by rotation around X-axis
QQuaternion dest = QQuaternion::fromAxisAndAngle(1, 0, 0, 90);
QQuaternion out = q * dest;
QVector3D euler = out.toEulerAngles();

float hor = euler.y();
if(hor < 0.0f)
hor += 360.0f;

float ver = euler.z();
if(ver > 90.0f)
ver = 90.0f;
else if(ver < 0.0f)
ver = 0.0f;

//x changes later
return QVector3D(0, hor, ver);
}

但它不能正常工作。我想 fromPolarToQuat 转换在某处有错误,我不明白在哪里。

最佳答案

看来我找到了解决办法。因此,要从四元数中获取极角:

QVector3D CoordinateSystemGround::fromQuatToPolar(const QQuaternion& q) const {
QQuaternion coord1 = QQuaternion::fromAxisAndAngle(0, 1, 0, -180);
QQuaternion coord2 = QQuaternion::fromAxisAndAngle(1, 0, 0, -90);
QQuaternion out = orig1 * orig2 * q;
QVector3D euler = out.toEulerAngles();

float hor = euler.y();
if(hor < 0.0f)
hor += 360.0f;

float ver = euler.x();

return QVector3D(0, hor, -ver);
}

然后返回:

QQuaternion CoordinateSystemGround::fromPolarToQuat(const QVector3D& polar) const {
QQuaternion dest = QQuaternion::fromEulerAngles({-polar.z(), polar.y(), 0});
QQuaternion coord1 = QQuaternion::fromAxisAndAngle(1, 0, 0, 90);
QQuaternion coord2 = QQuaternion::fromAxisAndAngle(0, 1, 0, 180);
return coord1 * coord2 * dest;
}

尽管不确定它是否是最佳解决方案,但它可以正常工作。

已编辑

经过一些研究,我发现了一些错误并进行了优化,希望正确的转换版本:

QVector3D CoordinateSystemGround::fromQuatToPolar(const QQuaternion& q) const {
// back to OpenGL coord system: just multiplication on inverted destination coord system
QQuaternion dest = QQuaternion::fromAxes({-1, 0, 0}, {0, 0, 1}, {0, 1, 0}).inverted();
QVector3D euler = (dest * q).toEulerAngles();

float hor = euler.y();
if(hor < 0.0f)
hor += 360.0f;

float ver = euler.x();

return QVector3D(0, hor, -ver);
}

然后返回:

QQuaternion CoordinateSystemGround::fromPolarToQuat(const QVector3D& polar) const {
//just rotate if we were in OpenGL coord system
QQuaternion orig = QQuaternion::fromEulerAngles({-polar.z(), polar.y(), 0});
//and then multiply on destination coord system
QQuaternion dest = QQuaternion::fromAxes({-1, 0, 0}, {0, 0, 1}, {0, 1, 0});
return dest * orig;
}

关于c++ - 将 OpenGL 坐标系统转换为自定义并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57547524/

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