将 OpenGL 坐标系统转换为自定义并返回
Convert OpenGL coord system to custom and back
我有一个任务,使用OpenGL在地面上绘制3D对象。我使用 OpenGL 左手坐标系统,其中 Y 轴向上。但是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);
}
但它不能正常工作。我想从 PolarToQuat 转换在某处有错误,我不明白在哪里。
似乎我找到了解决方案。因此,要从四元数获得极角:
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++映射:具有自定义类的运算符[]不起作用(总是返回0)
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 通过 NIF 从C++返回自定义数据结构
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 如何在C++中返回自定义类中的分段错误?
- 如何在C++中允许成员函数的自定义返回类型进行类型擦除?
- 如何从 cpp 中的函数返回自定义类对象?
- 将成员函数的返回类型引用到C++中的自定义类
- 自定义派生的 std::exception 类的 'what' 函数返回神秘的废话
- 从 QAbstractItemModel 返回自定义用户类型
- 将 OpenGL 坐标系统转换为自定义并返回
- 基于范围的 for 循环,用于包含C++中的指针的自定义链表,仅返回对象
- C++ grpc::experimental:interceptor 如何从自定义拦截器返回状态和消息
- 是否可以为类设置自定义返回类型
- 具有自定义返回类型和"false"返回条件的函数?
- C :不同类型的模板功能(方法)的自定义返回值
- 在派生类中定义自定义返回类型的受保护方法
- 自定义返回类型声明
- 带有自定义返回值的seresult
- 具有自定义返回类型的全局命名空间中的友元函数