C# Vector3 四元数从一个方向旋转到下方表面的法线方向但仅按百分比

C# Vector3 Quaternion rotating from a direction to the normal direction of surface below but only by a percentage

我正在为此项目使用 Unity3D 引擎。

我的目标是将对象的向上方向旋转大约一半,使其与其所在表面的方向相同,地面正常。

通常您可以使用以下代码轻松实现此目的:

  fencer.transform.rotation = Quaternion.FromToRotation(fencer.transform.up, hit.normal) * fencer.transform.rotation;

fencer.transform.up是物体的向上方向,也是一个Vector3,我们将其设置为撞击表面的法线。 hit.normal 是一个Vector3,下方曲面的法线。 这非常有效。

现在我只尝试 'half' 将对象旋转到地面:

var halfNormal = (fencer.transform.up - hit.normal);
                        if (halfNormal.y < 0)
                            halfNormal *= -1;
                        fencer.transform.rotation = Quaternion.FromToRotation(fencer.transform.up, halfNormal) * fencer.transform.rotation;

所以上面的代码试图计算法线向量和击剑手向上向量之间的差异,基本上是试图计算 'half of the normal'。因此,当我将 FromToRotation() 与新的 halfNormal 一起用作“ToRotation”时。 它应该只将物体旋转到正常地面的一半,基本上只旋转了 50%,而不是之前我们旋转了 100%。

问题是它不起作用,我用这种方法得到的结果很奇怪。

如何解决这个问题并找到正常的一半?还是有更好的方法可以找到正常值的 10%、75% 或我选择的任何百分比?

非常感谢您的帮助。谢谢

一种方法是只使用 Quaternion.Slerp 在开始和 100% 旋转之间插入 50%。

Quaternion goal =  Quaternion.FromToRotation(fencer.transform.up, hit.normal) 
        * fencer.transform.rotation;
fencer.transform.rotation = Quaternion.Slerp(fencer.transform.rotation, goal, 0.5f);

另一种方法是执行您之前的方法,但将增量转换为 angle/axis,然后在应用前将角度减半。如果您出于其他目的需要知道角度 and/or 轴,这可能会更有用:

Quaternion delta = Quaternion.FromToRotation(fencer.transform.up, hit.normal);
delta.ToAngleAxis(out float angle, out Vector3 axis);
Quaternion halfDelta = Quaternion.AngleAxis(0.5f * angle, axis);
fencer.transform.rotation = halfDelta * fencer.transform.rotation;