我有两个对象,每个对象有两个向量:
喜欢这张图片:
向上矢量垂直于法向量。现在我想找到从一个对象到另一个对象的独特旋转,怎么做?
我有一种方法可以找到一个矢量到另一个矢量之间的旋转,并且它有效。问题是我需要注意两个向量:法向量和向量向量。如果我使用这种方法将法向量从对象1旋转到对象2的法线,则向上矢量可能指向错误的方向,并且它们需要是平行的。
以下是查找最短轮换的代码:
GE::Quat GE::Quat::fromTo(const Vector3 &v1, const Vector3 &v2)
{
Vector3 a = Vector3::cross(v1, v2);
Quat q;
float dot = Vector3::dot(v1, v2);
if ( dot >= 1 )
{
q = Quat(0,0,0,1);
}
else if ( dot < -0.999999 )
{
Vector3 axis = Vector3::cross(Vector3(1,0,0),v2);
if (axis.length() == 0) // pick another if colinear
axis = Vector3::cross(Vector3(0,1,0),v2);
axis.normalize();
q = Quat::axisToQuat(axis,180);
}
else
{
float s = sqrt( (1+dot)*2 );
float invs = 1 / s;
Vector3 c = Vector3::cross(v1, v2);
q.x = c.x * invs;
q.y = c.y * invs;
q.z = c.z * invs;
q.w = s * 0.5f;
}
q.normalize();
return q;
}
我应该更改/添加到此代码中,以找到正确的旋转?
答案 0 :(得分:3)
在我们开始之前,我将假设它们之间的UP向量和法向量都是标准化和正交(点积为零)。
让我们说你要旋转你的黄色盘子与玫瑰(红色?)盘子对齐。因此,我们的参考将是来自黄板的矢量,我们将坐标系称为XYZ,其中Z - >正常黄色矢量,Y - >黄色矢量和X - &gt; YxZ(交叉产品)。
同样地,对于玫瑰板,旋转的坐标系称为X&#39; Y&#39; Z&#39;其中Z&#39; - &GT;正常的玫瑰矢量,Y&#39; - &GT;玫瑰矢量和X&#39; - &GT; Ÿ&#39; XZ&#39; (交叉产品)。
好的找到旋转矩阵,我们只需要确保我们的正常黄色矢量将成为正常的玫瑰矢量;我们的黄色向量将在向上的玫瑰向量中变换,依此类推,即:
RyellowTOrose = |X'x Y'x Z'x|
|X'y Y'y Z'y|
|X'z Y'z Z'z|
换句话说,在将任何基元转换为黄色系统的坐标后,应用此转换,将其旋转以与玫瑰坐标系统对齐
如果向上和法线向量不正交,则可以轻松纠正其中一个向量。只需在正常和向上之间生成交叉乘积(为方便起见,生成一个名为C的向量)并再次使用C和正常之间的交叉乘积,以纠正向上向量。
答案 1 :(得分:2)
四元数代码只将一个向量旋转到另一个向量而没有“向上”向量。
在您的情况下,只需从3个正交向量构建旋转矩阵
在两种情况下,您将有R1和R2矩阵(3x3)表示对象的旋转。
要查找从R1到R2的旋转,只需执行
R1_to_R2 = R2 * R1.inversed()
矩阵R1_to_R2是从一个方向到另一个方向的变换矩阵。注意:此处的R1.inversed()可以替换为R1.transposed()
答案 2 :(得分:1)
让我再次使用你图中的矢量来解决问题。
<强>问题:强>
假设您有两个向量blue_1
和green_1
(它们是正交的),并且您正在寻找旋转以将这些向量移动到blue_2
和{{1} (他们是正交的)。此外,您希望green_2
与green_2
平行。
<强>解决方案:强>
正如我所看到的,这里的问题是这些轮换仅存在于某些情况下。您的向量green_1
应该已经与blue_2
正交。如果green_1
与blue_2
不正交,则您的轮换不存在。
<强>为什么吗
让R成为轮换,即
green_1
我们知道green_2与blue_2正交,所以
blue_2 = R*blue_1
green_2 = R*green_1
同样,green_2和green_1只有在等于不等于零的常数因子时才会是平行的,让我们说dot(blue_2,green_2) = 0
,这是一个实数。
a
把事情放在一起,你得到了
green_2 = a*green_1
因为a不是零,我们得到
0 = dot(blue_2,green_2) = a*dot(blue_2,green_1)
示例:强>
如果你的载体是
blue_1 =(1,0,0)
green_1 =(0,1,0)
并且你的新矢量蓝色是
blue_2 =(sqrt(2)/ 2,sqrt(2)/ 2,0)
然后不存在满足您的正交性的向量dot(blue_2,green_1) = 0
存在的可能性,然后您将找不到移动green_2
但不移动blue_1
的旋转。
答案 3 :(得分:1)
首先,我声称只有一个这样的变换将对齐两个对象的方向。所以我们不必担心找到最短的那个。
让将要旋转的对象称为a
,并调用保持静止的对象b
。让x
和y
分别为a
的正常和向上向量,同样让u
和v
成为b
的这些向量。我假设x
,y
,u
和v
是单位长度,x
与y
正交,{ {1}}与u
正交。如果不是这种情况,可以编写代码来纠正这个问题(通过平面投影和标准化)。
现在让我们构造矩阵,将“世界空间”定义为v
和a
的方向。 (让b
表示交叉产品)将^
构建为z
,并将x ^ y
构建为c
。将a ^ b
,x
,y
和z
,a
,b
写入每个矩阵的列会为我们提供两个矩阵,称之为{分别为{1}}和c
。 (这里的叉积给出了单位长度和相互正交的向量,因为操作数也是如此)
根据A
获取B
的坐标系变换的变化是B
(矩阵A
的倒数,其中A^-1
表示一般化在这种情况下,A
可以计算为^
,转置,因为A^-1
是构造的正交矩阵。然后,A^T
的物理转换只是矩阵A
本身。因此,通过B
转换对象,然后通过B
转换对象将得到所需的结果。但是,通过将右侧的A^-1
乘以左侧的B
,可以将这些转换连接成一个转换。
你最终得到这个矩阵(假设没有算术错误):
B