Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 寻找四元数之间的最短旋转_C#_Unity3d_Difference_Quaternions - Fatal编程技术网

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

C# 寻找四元数之间的最短旋转,c#,unity3d,difference,quaternions,C#,Unity3d,Difference,Quaternions,我的问题是: 我正在尝试将游戏对象A与游戏对象B的旋转对齐,尽管重要的细节是GoA可以与GoB的旋转对齐1:1,或者与GoB的旋转相反(即,一只手拿起铅笔,笔尖朝上,或者笔尖朝下) 我想做的是找出哪一个选项(1:1或相反)是最接近的旋转,所以这是旋转到的最短路径 例如: 在上述示例中,场景A中红线(GoA)应与黑线(GoB)以1:1的比例找到最近的旋转,而场景B中红线应找到与黑线相反的最近旋转 此解决方案需要在3D空间中工作,并避免万向锁 非常感谢您的帮助,如果需要更多信息,我会将其编辑到这篇

我的问题是:

我正在尝试将游戏对象A与游戏对象B的旋转对齐,尽管重要的细节是GoA可以与GoB的旋转对齐1:1,或者与GoB的旋转相反(即,一只手拿起铅笔,笔尖朝上,或者笔尖朝下)

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

例如:

在上述示例中,场景A中红线(GoA)应与黑线(GoB)以1:1的比例找到最近的旋转,而场景B中红线应找到与黑线相反的最近旋转

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

非常感谢您的帮助,如果需要更多信息,我会将其编辑到这篇原创文章中

谢谢


Tim取决于你所说的“更近”是什么意思

假设目标在一个房间里,房间对面有门和窗

目标是直立的,看着门,相反的目标是看着窗户,但却是倒置的

受试者从门和窗之间看去,只是稍微靠近窗户,并且是直立的

哪位候选人更符合你的需求


如果你认为这里的目标是“更接近”的,因为主体已经竖直,并且你关心主体和目标之间的整体旋转差异,你可以使用<代码>四元数。角度< /代码>来确定哪一个与身份旋转有较小的差异:

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
}

对每个电势旋转进行四元数点积。最小的结果更接近。然后,旋转到更近的旋转的方法是使用四元数slerp。你找到这个问题的解决方案了吗?
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
}