寻找四元数之间的最短旋转

时间:2020-01-10 13:31:40

标签: c# unity3d difference quaternions

我的问题:

我正在尝试将Gameobject A与GameObject B的旋转对齐,尽管重要的细节是GoA可以与GoB的旋转进行1:1对齐,或者与GoB的旋转进行逆向对齐(即,用笔尖捡起铅笔)一面朝上,或者相反,一面朝下)。

我想做的是找到哪个选项(1:1或反向)是最接近的旋转,所以这是旋转到的最短路径。

示例:

Scenario A and B where the red line represents GoA, and the black line represents GoB

在上面的示例中,方案A的红线(GoA)应该找到与黑线(GoB)最接近的旋转1:1,而在方案B中,红线应该找到与该线最近的旋转作为逆向旋转。黑色线。

此解决方案需要在3D空间中工作,并避免万向锁定。

非常感谢您的帮助,如果需要更多信息,我将其编辑到原始帖子上!

谢谢

蒂姆

1 个答案:

答案 0 :(得分:0)

取决于“更紧密”的含义。

假设目标在一个有门和窗户的房间里。

目标是直立的,看着门,相反的目标是在看着窗户,但是颠倒了。

对象正在门和窗户之间看,只是离窗户稍远一点,并且是直立的。

哪个候选人更符合您的需求?


如果由于被摄体已经直立而认为此处的目标“更近”,并且您关心被摄体与目标之间的整个旋转差异,则可以使用Quaternion.Angle来确定哪个具有较小的差异从身份轮换中:

Transform target;
Transform subject;

Quaternion subjectRot = subject.rotation;
Quaternion targetRot = target.rotation;

// however you define "inverse" here
Qutaternion invTargetRot = targetRot * Quaternion.Euler(180f,0f,0f);

float angleToTarget = Quaternion.Angle(subjectRot, targetRot);
float angleToInvTarget = Quaternion.Angle(subjectRot, invTargetRot);

if (angleToTarget <= angleToInvTarget) 
{
    // alignment with target is closer
}
else 
{
    // alignment with inverse of target is closer
}

如果您认为此处的反向目标“更近”,因为您只关心主体/目标的一个局部方向(例如,向前),而不关心其他目标(例如,上/右),那么您可以只使用Vector3.Angle来比较方向,如果角度小于90度,则对齐的方向更接近:

Transform target;
Transform subject;

// or *.up, or *.right depending on your needs
float angleToTarget = Vector3.Angle(subject.forward, target.forward);

if (angleToTarget <= 90f) 
{
    // alignment with target is closer
}
else 
{
    // alignment with inverse of target is closer
}
相关问题