2

我有两个向量对(旋转前后)。

旋转前:[x1,y1,z1] [x2,y2,z2]

旋转后:[x1',y1',z1'] [x2',y2',z2']

如何创建一个代表这种旋转的四元数?

4

5 回答 5

2

在大多数情况下,没有将 2 个向量转换为 2 个其他向量的旋转。以下是一种可视化原因的简单方法:旋转不会改变向量之间的角度。如果旋转前 2 个向量之间的角度与旋转后 2 个向量之间的角度不同,则没有符合您标准的旋转。

这表示可能存在一个具有可接受误差的最佳四元数,它“几乎”旋转了你的 2 个向量对。有许多算法在速度和精度上有所不同,可以找到这样的四元数。我为一个速度很关键但精度不太重要的 Arduino 应用程序编写了一个快速 C++ 算法。

http://robokitchen.tumblr.com/post/67060392720/finding-a-rotation-quaternion-from-two-pairs-of-vectors

旋转前:u0,v0。旋转后:u2,v2。

Quaternion q2 = Quaternion::fromTwoVectors(u0, u2);
Vector v1 = v2.rotate(q2.conjugate());
Vector v0_proj = v0.projectPlane(u0);
Vector v1_proj = v1.projectPlane(u0);
Quaternion q1 = Quaternion::fromTwoVectors(v0_proj, v1_proj);
return (q2 * q1).normalized();

如果这不符合您自己的应用程序的要求,请尝试 google Wabha 的问题。

于 2013-11-18T01:24:07.057 回答
2

好吧,首先你可以使用向量乘法(交叉乘法)找到旋转轴:

axis = v1 x v2;

然后你可以计算旋转角度:

sinA = |axis| / |v1|*|v2|
cosA = v1 . v2 / |v1|*|v2|

这里 | | - 是向量长度运算,并且 。- 是点乘法

最后,你的四元数是:

Q(w,x,y,z) = (cosA, axis.x * sinA, axis.y * sinA, axis.z * sinA)
于 2013-10-18T11:42:19.587 回答
1

我将 marcv81 非常有用的博文翻译成 Three.js:

const rotateVectorsSimultaneously = (u0, v0, u2, v2) => {
    const q2 = new THREE.Quaternion().setFromUnitVectors(u0, u2);

    const v1 = v2.clone().applyQuaternion(q2.clone().conjugate());

    const v0_proj = v0.projectOnPlane(u0);
    const v1_proj = v1.projectOnPlane(u0);

    let angleInPlane = v0_proj.angleTo(v1_proj);
    if (v1_proj.dot(new THREE.Vector3().crossVectors(u0, v0)) < 0) {
        angleInPlane *= -1;
    }
    const q1 = new THREE.Quaternion().setFromAxisAngle(u0, angleInPlane);

    const q = new THREE.Quaternion().multiplyQuaternions(q2, q1);
    return q;
};

因为angleTo总是返回一个正值,所以我根据u0-v0平面v1的哪一侧手动翻转角度的符号。

于 2019-03-19T19:30:42.197 回答
0

这个问题的成熟解决方案称为Triad。三元组是航天器姿态确定问题最早和最简单的解决方案之一,计算效率极高。

使用三元组,其想法是将您的两个向量的配对集合替换为三个向量的配对集合,其中额外的向量是通过叉积生成的。通过对向量进行归一化,您可以求解没有矩阵逆或 SVD 的旋转矩阵(在更一般的问题实例中需要 - 请参阅Wahba 的问题

完整算法见:https ://en.wikipedia.org/wiki/Triad_method

然后,您可以将求解的旋转矩阵从 Triad 转换为旋转四元数:

qw = √(1 + m00 + m11 + m22) /2
qx = (m21 - m12)/( 4 *qw)
qy = (m02 - m20)/( 4 *qw)
qz = (m10 - m01)/( 4 *qw)

一般来说,为了使四元数的转换稳健,您应该考虑查看此处讨论的矩阵迹线:http ://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/

最后,考虑一个替代 Triad 的方法,它直接计算称为QUEST的最佳四元数。

于 2019-05-16T05:18:24.087 回答
0

可以找到从 v1 到 v2 的四元数。

最后一个q = (cos A/2, sin A/2 * axis),其中 A 是 v1 和 v2 之间的角度,axis 是规范轴。

两边相乘2 * cos A/2

然后我们有 2 * cos A/2 *q = (1+cos A, sin A * axis)

(哪里cos A = dot(v1, v2)/|v1|/|v2|axis = cross(v1, v2).normalize() = cross(v1, v2)/|v1|/|v2|/sin A。)

然后2 * cos A/2 *q = (1+dot(v1, v2)/|v1|/|v2|, cross(v1, v2)/|v1|/|v2|)

最后q = (1+dot(v1, v2)/|v1|/|v2|, cross(v1, v2)/|v1|/|v2|).normalize()

于 2020-04-14T20:57:07.057 回答