首页 > 解决方案 > 物体在球体的切线空间中的旋转

问题描述

给定以下两个输入:

如何获得球体上点的切线空间中物体的方位角和仰角(观察者应该看的仰角和方位角)?特别是,当物体正好在天顶时,偏航旋转(围绕垂直轴的旋转)应该考虑方位角(这样,虽然观察者是直视的,但他的肩膀会面对与物体相同的方位角)。

到目前为止我尝试过的数学是:

  1. 将卫星放入切线空间(将其世界矩阵乘以地球上切线空间矩阵的逆矩阵)。或与四元数相同。然后从得到的矩阵(或得到的四元数)推导出欧拉旋转,具有“ZXY”优先级,Z 和 X 被解释为方位角和仰角。但这给出了不正确的数字,因为旋转的一部分似乎经常被解释为我想要为零的滚动(Y 轴旋转)。
  2. 一种直观的方法也是计算观察者的矢量与物体位置之间的角度,与垂直轴,以推断高度;而方位角由切线北与物体在“切线地面”上的投影位置之间的角度给出(加上一些更多的数学来磨练这个特定的推论)。但是这种方法不适用于天顶物体的情况。

资源在线存在,但没有这些特定的输入和支持 zenith 案例的必要性。


顺便说一句,该程序是用于three.js的打字稿,因此上述第一个解决方案的代码如下:

function getRotationAtPoint(
    object: THREE.Object3D,
    point: THREE.Vector3
): { azimuth: number, elevation: number } {
    // 1. Get the matrix of the tangent space of the observer.
    const tangentSpaceMatrix = new THREE.Matrix4();
    const baseTangentSpaceAxes = getBaseTangentAxesOnSphere(point);
    tangentSpaceMatrix.makeBasis(...baseTangentSpaceAxes);

    // 2. Tranform the object's matrix in tangent space of observer.
    const inverseMatrix = new THREE.Matrix4().getInverse(tangentSpaceMatrix);
    const objectMatrix = object.matrixWorld.clone().multiply(inverseMatrix);

    // 3. Get the angles.
    const euler = new THREE.Euler().setFromRotationMatrix(objectMatrix);
    return {
        azimuth: euler.z,
        elevation: euler.x
    };
}

此外,Three.js 提供了对实例向上轴的THREE.Object3D引用,但是我处理的程序将所有内容直接计算到对象的矩阵中,并且向上轴不可信。

标签: matrixthree.jsgeometrygeospatialquaternions

解决方案


推荐阅读