将物体与球体表面对齐,同时保持向前方向

Aligning an object to the surface of a sphere while maintaining forward direction

使用 OpenGL 作为渲染引擎,我试图生成一个旋转矩阵,该矩阵将在给定位置的球体表面放置一个网格。最初我试图通过计算给定位置的球体表面法线并将其用作我的网格 up 向量来做到这一点。

这可行,但事情变得复杂,因为我还希望能够使用绝对 yawpitchroll 值旋转网格 - 其中yaw 的 0 将始终使网格指向北方 (0, 1, 0)。

我对如何实现这一点有心理障碍,希望收到任何意见。


更新Ripi2提供的解决方案:

let earthAxisOfRotation = Vector3(0, 1, 0).normalized() // south -> north pole is `up` in world space
let surfaceNormal = position.normalized() // surface normal of the given position on sphere surface

let east = earthAxisOfRotation.cross(surfaceNormal).normalized()
let north = surfaceNormal.cross(east)

let rotationMatrix = Matrix4(
    east.x, east.y, east.z, 0,
    surfaceNormal.x, surfaceNormal.y, surfaceNormal.z, 0,
    -north.x, -north.y, -north.z, 0,
    0, 0, 0, 1
)

让我们开始 "Earth"。它的旋转轴 (r) 从南极指向北极。表面的法线 (n) 为地球的 "out"。

叉积e= r x n给出了一个向东的向量。
叉积 d= n x e 给出一个向北的矢量。

使用 e, n, d 的标准化版本并转换为曲面中的点,您可以构建 lookAt 矩阵(请参阅 here)。
up = nf= center-eye = ds = e。请注意,您可能想要更改 f 符号,因为这不是真正的 'lookAt' 转换,它不查看,而只是定位。

现在,如果您的网格可以被视为与第一个球体同心的另一个球体,则所有旋转都必须在两个球体的共享中心上进行。旋转轴,始终保持 "heading north" 可以是 "Earth axis" (r) 和 "heading east" (e)。当使用 'e' 时,你不知何故失去了北方,向量变成了 "inside" 球体。角度可以从叉积计算,由于 if c= a x b then |c| = |a|·|b|·sin(beta).