将一个 3D 矢量相对于另一个 3D 矢量旋转 90 度

Rotating a 3D vector 90 degrees relative to another 3D vector

我正在制作一款玩家可以攀爬任何表面的游戏。

当玩家与表面发生碰撞时,我会得到碰撞的法线。这是玩家 "up" 向量应对齐的方向:

现在,unity 提供了一种将两个向量转换为旋转的便捷方法:

Quaternion.LookRotation(forward, up);

它需要向上向量和向前向量。正如我提到的,我已经有了向上矢量。我的问题是如何获得前向向量。

我目前的解决方案是通过在法线中翻转一些轴来计算前向向量:

normal = collision.contacts[0].normal;
Vector3 forward = Vector3.zero;
forward = new Vector3(0, -normal.z, normal.y);    
transform.rotation = Quaternion.LookRotation(forward, normal);

在大多数情况下这看起来没问题:

但是当玩家与法线只有 x 值的表面发生碰撞时,前向矢量为 0,0,0:

我知道我还必须考虑法线的 x 分量以避免这种情况,但我不确定将其插入何处。

将此问题更多地视为一个基于 Unity 的问题,涉及引擎提供的数学函数,而不是与纯数学相关的问题。但任何答案当然是值得赞赏的。

检查向量分量的大小。

然后将绝对值最小的分量置零,将最大和第二的分量交换,取最大的取反。这种方法为所有非零向量产生有效的垂直

例如,案例

Abs(n.x) >= Abs(n.z) >= Abs(n.y)
make
Perp = (n.z, 0, -n.x)