C# 欧拉角旋转矢量的归一化
我需要显示对象特定轴的欧拉角旋转。C# 欧拉角旋转矢量的归一化,c#,unity3d,C#,Unity3d,我需要显示对象特定轴的欧拉角旋转。 我知道,以欧拉角检索对象的旋转会产生不一致的结果,其中一些结果可以通过简单地对结果使用模360来解决。然而,unity在为一个向量赋值为“transform.localRotation.eulerAngles”时,有时会做一个置换,它不是检索向量3“V”,而是检索“(180,180,180)-V”。 根据我的理解,“(180,180,180)-V”不会产生与V相同的真实世界旋转,不同于“(180,180,180)+V”,后者不会影响实际旋转。 对这种现象的解释
我知道,以欧拉角检索对象的旋转会产生不一致的结果,其中一些结果可以通过简单地对结果使用模360来解决。然而,unity在为一个向量赋值为“transform.localRotation.eulerAngles”时,有时会做一个置换,它不是检索向量3“V”,而是检索“(180,180,180)-V”。 根据我的理解,“(180,180,180)-V”不会产生与V相同的真实世界旋转,不同于“(180,180,180)+V”,后者不会影响实际旋转。
对这种现象的解释是什么?假设我知道欧拉角旋转矢量的一个轴的期望值和可行值,那么规范化欧拉角旋转矢量的最佳方法是什么?(例如,将其规格化,使其所有值均为mod 360,且假设其具有Z=0的表示形式,则其Z轴等于0)我不太确定我是否正确理解您的问题,但euler角仅表示围绕3轴以特定顺序应用的3次旋转的角度,对吗?那么,为什么要通过在每一处添加180来规范化它呢?通过对每个角度进行模化,应将每个角度分别置于0-360范围内 你的问题似乎暗示你只需绕两个轴而不是三个轴旋转就可以获得任何方向。。。这就是你想要达到的目标吗?
使用四元数可能会对您有所帮助,事实上,一个方向可以用4个标量值定义:一个轴和一个角度。我不知道问题的第一部分(在我看来,它的不同程度足以成为它自己的问题),但我可以回答您的第二个问题 因此,您有以下输入:
Quaternion desiredRotation;
float knownZ;
您试图找到Vector3 Euler
,其中Euler.z
大约是knownZ
和Quaternion.Euler(Euler)==desiredRotation
以下是我将使用的程序:
首先,确定由
desiredRotation
旋转的向上方向和由一卷knownZ
旋转的向上和向右方向:
Vector3 upDirEnd = desiredRotation * Vector3.up;
Quaternion rollRotation = Quaternion.Euler(0,0,knownZ);
Vector3 upDirAfterRoll = rollRotation * Vector3.up;
Vector3 rightDirAfterRoll = rollRotation * Vector3.right;
我们知道应用desiredRotation
后的局部向上方向,并且在应用rollknownZ
后,唯一可以调整向上方向的是euler俯仰组件进行的旋转。因此,如果我们可以计算从upDirAfterRoll
到upDirEnd
的角度,作为围绕rightDirAfterRoll
轴测量的角度
float determinedX = Vector3.SignedAngle(upDirAfterRoll, upDirEnd, rightDirAfterRoll);
// Normalizing determinedX
determinedX = (determinedX + 360f) % 360f;
…我们可以确定EULER的x分量
然后,我们对eulers
的偏航组件执行相同操作,以使新的前进方向与末端前进方向对齐:
Vector3 forwardDirEnd = desiredRotation * Vector3.forward;
Quaternion rollAndPitchRotation = Quaternion.Euler(determinedX, 0, knownZ);
Vector3 forwardDirAfterRollAndPitch = rollAndPitchRotation * Vector3.forward;
Vector3 upDirAfterRollAndPitch = upDirEnd; // unnecessary but here for clarity
float determinedY = Vector3.SignedAngle(forwardDirAfterRollAndPitch, forwardDirEnd, upDirAfterRollAndPitch );
// Normalizing determinedY
determinedY = (determinedY + 360f) % 360f;
Vector3 eulers = new Vector3(determinedX, determinedY, knownZ);
为了确保给定的四元数可以使用给定的组件生成,您可以检查给定给SignedAngle
的轴是否确实可以将输入向量旋转到目标向量,或者您可以只比较计算的EULER和给定的四元数:
Quaternion fromEuler = Quaternion.Euler(eulerAngles);
if (fromEuler==desiredRotation)
{
// use eulerAngles here
}
else
{
// component and quaternion incompatible
}
希望这能有所帮助。“unity有时会做一个排列,当……”你能引述来源吗?不是我在所有地方都添加180。由于从四元数到Euler角的映射不是内射的,Unity可能会为同一个四元数提供不同的Euler角向量,我正在寻找一种方法来克服这一点。这可能有帮助吗?