球体切线空间中物体的旋转

时间:2019-10-07 10:03:00

标签: matrix three.js geometry geospatial quaternions

给出以下两个输入:

  • 球体上的一个点(就像地球上的观察者);
  • 空间中物体的世界矩阵(卫星的位置和姿态)

如何获取球体上该点的切线空间中对象的方位角和高度(观察者应该观察的高度和方位角)?特别是,当对象正好位于天顶时,偏航旋转(绕垂直轴旋转)应说明方位角(这样,即使观察者直视上方,他的肩膀也将面对与对象相同的方位角)。

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

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

资源在线存在,但没有这些具体输入,也没有支持天顶案例的必要性。


顺便说一下,该程序是用于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实例的上轴的引用,但是我处理的程序将所有内容直接计算到对象的矩阵中,并且上轴不可信任。

0 个答案:

没有答案