将物体与球体表面对齐,同时保持向前方向
Aligning an object to the surface of a sphere while maintaining forward direction
使用 OpenGL 作为渲染引擎,我试图生成一个旋转矩阵,该矩阵将在给定位置的球体表面放置一个网格。最初我试图通过计算给定位置的球体表面法线并将其用作我的网格 up
向量来做到这一点。
这可行,但事情变得复杂,因为我还希望能够使用绝对 yaw
、pitch
和 roll
值旋转网格 - 其中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 = n
和 f= center-eye = d
和 s = e
。请注意,您可能想要更改 f
符号,因为这不是真正的 'lookAt' 转换,它不查看,而只是定位。
现在,如果您的网格可以被视为与第一个球体同心的另一个球体,则所有旋转都必须在两个球体的共享中心上进行。旋转轴,始终保持 "heading north" 可以是 "Earth axis" (r) 和 "heading east" (e)。当使用 'e' 时,你不知何故失去了北方,向量变成了 "inside" 球体。角度可以从叉积计算,由于 if c= a x b
then |c| = |a|·|b|·sin(beta)
.
使用 OpenGL 作为渲染引擎,我试图生成一个旋转矩阵,该矩阵将在给定位置的球体表面放置一个网格。最初我试图通过计算给定位置的球体表面法线并将其用作我的网格 up
向量来做到这一点。
这可行,但事情变得复杂,因为我还希望能够使用绝对 yaw
、pitch
和 roll
值旋转网格 - 其中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 = n
和 f= center-eye = d
和 s = e
。请注意,您可能想要更改 f
符号,因为这不是真正的 'lookAt' 转换,它不查看,而只是定位。
现在,如果您的网格可以被视为与第一个球体同心的另一个球体,则所有旋转都必须在两个球体的共享中心上进行。旋转轴,始终保持 "heading north" 可以是 "Earth axis" (r) 和 "heading east" (e)。当使用 'e' 时,你不知何故失去了北方,向量变成了 "inside" 球体。角度可以从叉积计算,由于 if c= a x b
then |c| = |a|·|b|·sin(beta)
.