Eigen,用四元数旋转一个vector3d?
Eigen, rotate a vector3d with a quaternion?
我有一个 3D 点数组,作为 std::vector<Eigen::Vector3d>
。
我需要用位置和四元数来转换这些点。
我的问题是:
如何用四元数旋转这些点?还有比以下更快的方法吗:
Eigen::Vector3d Trans; // position to move by
Eigen::Quaterniond quats; // quat to rotate by
for (int p = 0; p < objectPoints.size(); p++)
{
Eigen::Vector3d pnt;
//add pose
pnt.x = objectPointsTri[p].x + -Trans.x();
pnt.y = objectPointsTri[p].y + -Trans.y();
pnt.z = objectPointsTri[p].z + -Trans.z();
Eigen::Vector3d pntRot = // rotate pnt by the quaternion
}
Operator *
将完成这项工作,您当然可以简化代码:
pnt = objectPointsTri[p] - Trans;
pntRot = quat * pnt;
甚至:
pnt = quat * (objectPointsTri[p] - Trans);
或者,如果您将积分存储在 Matrix3Xd
:
Matrix3Xd in_pts;
Matrix3Xd out_pts;
Affine3d T = quats * Translation3d(-Trans);
out_pts = T * in_pts;
@ggael 的回答完全正确,我想提供一些背景知识。
在this Wikipedia article they explain quaternion-vector multiplication v’ = qvq-1. The Eigen shorthand with operator*
we're using is also apparently in Unity libraries.
在 Eigen 的当前版本中,您将选择 operator*
的 this overload,这会调用 _transformVector
template<typename RotationDerived,typename OtherVectorType>
struct rotation_base_generic_product_selector<RotationDerived,OtherVectorType,true>
{
...
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v)
{
return r._transformVector(v);
}
};
请参阅 _transformVector
上的 备注 here:
If the quaternion is used to rotate several points (>1) then it is much more efficient to first convert it to a 3x3 Matrix. Comparison of the operation cost for n transformations:
- Quaternion2: 30n
- Via a Matrix3: 24 + 15n
ggael 出于这些效率原因要求您更改解决问题的方式。
我有一个 3D 点数组,作为 std::vector<Eigen::Vector3d>
。
我需要用位置和四元数来转换这些点。
我的问题是:
如何用四元数旋转这些点?还有比以下更快的方法吗:
Eigen::Vector3d Trans; // position to move by
Eigen::Quaterniond quats; // quat to rotate by
for (int p = 0; p < objectPoints.size(); p++)
{
Eigen::Vector3d pnt;
//add pose
pnt.x = objectPointsTri[p].x + -Trans.x();
pnt.y = objectPointsTri[p].y + -Trans.y();
pnt.z = objectPointsTri[p].z + -Trans.z();
Eigen::Vector3d pntRot = // rotate pnt by the quaternion
}
Operator *
将完成这项工作,您当然可以简化代码:
pnt = objectPointsTri[p] - Trans;
pntRot = quat * pnt;
甚至:
pnt = quat * (objectPointsTri[p] - Trans);
或者,如果您将积分存储在 Matrix3Xd
:
Matrix3Xd in_pts;
Matrix3Xd out_pts;
Affine3d T = quats * Translation3d(-Trans);
out_pts = T * in_pts;
@ggael 的回答完全正确,我想提供一些背景知识。
在this Wikipedia article they explain quaternion-vector multiplication v’ = qvq-1. The Eigen shorthand with operator*
we're using is also apparently in Unity libraries.
在 Eigen 的当前版本中,您将选择 operator*
的 this overload,这会调用 _transformVector
template<typename RotationDerived,typename OtherVectorType>
struct rotation_base_generic_product_selector<RotationDerived,OtherVectorType,true>
{
...
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v)
{
return r._transformVector(v);
}
};
请参阅 _transformVector
上的 备注 here:
If the quaternion is used to rotate several points (>1) then it is much more efficient to first convert it to a 3x3 Matrix. Comparison of the operation cost for n transformations:
- Quaternion2: 30n
- Via a Matrix3: 24 + 15n
ggael 出于这些效率原因要求您更改解决问题的方式。