我做了很多研究,但实际上找不到我应该如何使用四元数来执行以下操作:
我具有源方向和目标方向,我试图找到从一个方向到另一个方向的特定角度(例如10度)的四元数。
我试图理解四元数,并且还希望避免万向节锁定,所以我需要一个不需要转换为欧拉角的答案。
我知道有Slerp函数,但它像一个“百分比”而不是一个角度。另外我不确定如何找到源和目标之间的差异。
基本上我正在尝试执行以下操作,但是使用四元数而不是矢量:
Vector3 source, target; //Lets pretend they are defined
Vector3 vect_dir = target - source;
float vect_length = Mathf.Min(10f * Time.deltaTime, vect_dir.magnitude);
Vector3 answer = vect_dir.normalized * vect_length;
有人知道如何处理四元数吗?想法是输入我选择的速度值(在示例中为10)。 它与使用Slerp函数非常相似,不同之处在于,我需要恒定的运动,而不是快速运动并逐渐变慢的运动。我也想避免因为万向节锁定而使用欧拉角。
答案 0 :(得分:1)
Quaternion.RotateTowards
Quaternion.RotateTowards
需要一个Quaternion
来自,一个Quaternion
至,以及一个float
maxDegreesDelta 。然后,它返回其中任何一个更接近 from :
从到到之间的Quaternion
与从 maxDegreesDelta 度>
至
因此,一个与您的Quaternion
相对应的示例可以写为:
Quaternion source, target; //Lets pretend they are defined
Quaternion reachedRotation = Quaternion.RotateTowards(source, target, 10f * Time.deltaTime);
如果您需要到达点和source
之间的差,可以执行一些四元数数学:
Quaternion answer = Quaternion.Inverse(source) * midpoint;
作为替代方案,您可以确定target
和source
之间的差异,并用Quaternion.ToAngleAxis
用角度(幅度)和轴(方向)形式表示出来:
Quaternion difference = Quaternion.Inverse(source) * target;
Vector3 differenceAxis;
float differenceAngle;
difference.ToAngleAxis(out differenceAngle, out differenceAxis);
然后,通过将answer
设置为上限来产生differenceAngle
:
Quaternion answer = Quaternion.AngleAxis(Mathf.Min(differenceAngle, 10f * Time.deltaTime), differenceAxis);
如果您要查找从“包含” answer
到source
上的旋转,只需将它们相乘(顺序很重要):
reachedRotation = source * answer;
作为旁注,您使用Vector3
的示例可以写为:
Vector3 source, target; //Lets pretend they are defined
Vector3 answer = Vector3.MoveTowards(source, target, 10f * Time.deltaTime) - source;