旋轉向量
#include <Eigen/Geometry>
#include <Eigen/Core>
AngleAxisd
類有幾種構造函數,其中最常用的是:
Eigen::AngleAxisd(const Scalar& angle, const Axis& axis);
angle
是旋轉的角度,通常以弧度表示。axis
是旋轉的軸,通常是一個單位向量,表示旋轉的方向。
例如,要創建一個圍繞 Z 軸順時針旋轉 π/4 弧度(45度)的 AngleAxisd
對象,可以這樣寫:
Eigen::AngleAxisd rotation_angle_axis(M_PI / 4.0, Eigen::Vector3d::UnitZ());
或者是
Eigen::AngleAxisd rotation_angle_axis(M_PI / 4.0, Eigen::Vector3d(::UnitZ(0,0,1));
使用
使用 AngleAxisd
對象可以執行以下操作:
-
將其應用于向量或點進行旋轉:
// 通過將 rotation_angle_axis 應用到 point 上得到的旋轉后的新點 Eigen::Vector3d point(1.0, 0.0, 0.0); Eigen::Vector3d rotated_point = rotation_angle_axis * point;
-
轉換為旋轉矩陣或四元數:
// 通過 toRotationMatrix() 方法從 rotation_angle_axis 轉換而來,用于表示相同旋轉的旋轉矩陣 Eigen::Matrix3d rotation_matrix = rotation_angle_axis.toRotationMatrix(); // 通過直接將 rotation_angle_axis 賦值給 Eigen::Quaterniond 類型得到,也表示了同樣旋轉的四元數 Eigen::Quaterniond quaternion = rotation_angle_axis;
-
進行組合和插值操作:
// rotation_angle_axis 和 another_rotation 相乘(組合)得到的新的 Eigen::AngleAxisd 對象,它代表了先進行 rotation_angle_axis 的旋轉,然后進行 another_rotation 的旋轉。 Eigen::AngleAxisd another_rotation(M_PI / 3.0, Eigen::Vector3d::UnitY()); Eigen::AngleAxisd combined_rotation = rotation_angle_axis * another_rotation; // interpolated_rotation 是通過 slerp() 方法進行球面線性插值(Slerp)得到的 Eigen::AngleAxisd 對象。這種方法可以在兩個旋轉之間進行平滑的過渡,第一個參數是插值參數,通常是一個介于0到1之間的值,表示兩個旋轉的相對比例。 Eigen::AngleAxisd interpolated_rotation = rotation_angle_axis.slerp(0.5, another_rotation);
歐氏變換
Eigen::Isometry3d
是 Eigen 庫中用于表示三維歐氏空間中的等距變換(Isometry)的類。它繼承自 Eigen::Transform
,具體表示了包括平移和旋轉在內的等距變換。
主要特點和用途:
- Identity Isometry(單位等距變換):單位等距變換表示沒有任何旋轉或平移,即一個點經過單位等距變換后位置不變。在三維空間中,單位等距變換的旋轉部分是單位矩陣,平移部分是零向量。
- 靜態成員函數
Identity()
:這個函數是通過Isometry3d
類訪問的靜態函數,它返回一個默認的單位等距變換對象。通過調用Eigen::Isometry3d::Identity()
,可以獲得一個已經初始化為單位變換的Isometry3d
對象,通常用于開始定義其他具體的變換。
- 等距變換(Isometry):
Isometry3d
能夠表示旋轉和平移的組合,保持點之間的距離不變。在計算機圖形學、機器人學和幾何計算等領域中,等距變換非常重要。 - 旋轉和平移的組合:通過
Isometry3d
,可以方便地表示和操作三維空間中的物體的姿態和位置。 - Eigen 庫支持:Eigen 是一個開源的線性代數庫,專注于高性能的矩陣和向量運算。
Isometry3d
類充分利用了 Eigen 的矩陣和向量運算優勢,提供了高效的數學運算。
示例:
以下是一個簡單的示例,展示如何使用 Isometry3d
類創建和操作等距變換:
#include <Eigen/Geometry>int main() {// 創建一個 Isometry3d 對象Eigen::Isometry3d T = Eigen::Isometry3d::Identity();// 設置旋轉部分(繞Z軸旋轉90度)T.rotate(Eigen::AngleAxisd(M_PI/2, Eigen::Vector3d::UnitZ()));// 設置平移部分(平移向量)T.pretranslate(Eigen::Vector3d(1, 2, 3));// 使用 Isometry3d 進行點變換Eigen::Vector3d point(1, 0, 0);Eigen::Vector3d transformed_point = T * point;// 輸出變換后的點std::cout << "Transformed point: " << transformed_point.transpose() << std::endl;return 0;
}
#include <Eigen/Dense>
#include <iostream>int main() {// 假設我們有一個4x4的仿射變換矩陣Eigen::Affine3d T;T.matrix() << 1, 0, 0, 1, // 旋轉矩陣部分0, 1, 0, 0, // 旋轉矩陣部分0, 0, 1, 0, // 旋轉矩陣部分1, 2, 3, 1; // 平移向量// 提取旋轉矩陣Eigen::Matrix3d R = T.linear();// 提取平移向量Eigen::Vector3d t = T.translation();// 打印旋轉矩陣和平移向量std::cout << "Rotation matrix:\n" << R << std::endl;std::cout << "Translation vector:\n" << t.transpose() << std::endl;return 0;}
T.linear()
這個成員函數返回仿射變換中的線性部分,即旋轉矩陣。它返回的是一個Eigen::Matrix3d
類型的引用,代表3x3的旋轉矩陣。
T.translation()
這個成員函數返回仿射變換中的平移向量。它返回的是一個Eigen::Vector3d
類型的引用,代表3D空間中的平移。
T.rotate()
這個成員函數是用來設置仿射變換的旋轉部分的。你可以傳遞一個3x3的旋轉矩陣給這個函數,它會更新T
的線性部分。
旋轉矩陣
Eigen::Matrix3d 在實際應用中有許多用途,以下是幾個常見的例子:
1. 旋轉矩陣表示旋轉操作
#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個旋轉矩陣,將向量繞Z軸旋轉45度Eigen::Matrix3d rotation_matrix;double angle = M_PI / 4.0; // 45度rotation_matrix << cos(angle), -sin(angle), 0,sin(angle), cos(angle), 0,0, 0, 1;// 定義一個向量Eigen::Vector3d vector(1.0, 0.0, 0.0);// 將向量應用旋轉Eigen::Vector3d rotated_vector = rotation_matrix * vector;// 輸出結果std::cout << "Original vector: " << vector.transpose() << std::endl;std::cout << "Rotated vector: " << rotated_vector.transpose() << std::endl;return 0;
}
這個例子中,我們定義了一個 Eigen::Matrix3d
類型的 rotation_matrix
,表示繞Z軸旋轉45度的旋轉矩陣。然后,我們定義了一個 Eigen::Vector3d
類型的向量 vector
,并將其通過 rotation_matrix
進行旋轉操作,得到 rotated_vector
。最后輸出了旋轉前后的向量。
2. 坐標變換
#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個坐標變換矩陣,將點從局部坐標系變換到全局坐標系Eigen::Matrix3d coordinate_transform;coordinate_transform << 1, 0, 0,0, -1, 0,0, 0, 1;// 定義一個局部坐標系下的點Eigen::Vector3d local_point(2.0, 3.0, 1.0);// 應用坐標變換Eigen::Vector3d global_point = coordinate_transform * local_point;// 輸出結果std::cout << "Local point: " << local_point.transpose() << std::endl;std::cout << "Global point: " << global_point.transpose() << std::endl;return 0;
}
在這個例子中,我們定義了一個 Eigen::Matrix3d
類型的 coordinate_transform
,表示一個坐標系的變換矩陣,用來將局部坐標系下的點 local_point
轉換到全局坐標系下的 global_point
。這種方式在計算機圖形學和仿真中經常使用,用于物體的位置和姿態變換。
3. 矩陣運算
#include <Eigen/Dense>
#include <iostream>int main() {// 定義兩個矩陣Eigen::Matrix3d A, B;A << 1, 2, 3,4, 5, 6,7, 8, 9;B << 9, 8, 7,6, 5, 4,3, 2, 1;// 計算矩陣乘法Eigen::Matrix3d result = A * B;// 輸出結果std::cout << "Matrix A:\n" << A << std::endl;std::cout << "Matrix B:\n" << B << std::endl;std::cout << "Result of A * B:\n" << result << std::endl;return 0;
}
當使用Eigen庫進行旋轉表示的轉換時,可以如下操作:
1. 旋轉矩陣轉換為旋轉向量
#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個旋轉矩陣,例如繞Y軸旋轉30度Eigen::Matrix3d rotation_matrix;double angle = M_PI / 6.0; // 30度rotation_matrix << cos(angle), 0, sin(angle),0, 1, 0,-sin(angle), 0, cos(angle);// 將旋轉矩陣轉換為旋轉向量Eigen::AngleAxisd rotation_vector(rotation_matrix);// 輸出結果std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;std::cout << "Equivalent rotation vector:\n" << rotation_vector.axis().transpose()<< " " << rotation_vector.angle() << " radians" << std::endl;return 0;
}
在這個例子中,我們定義了一個旋轉矩陣 rotation_matrix
,表示繞Y軸旋轉30度。然后,使用 Eigen::AngleAxisd
類型的構造函數將旋轉矩陣轉換為對應的旋轉向量 rotation_vector
。通過 rotation_vector.axis()
獲取旋轉向量的軸向量,通過 rotation_vector.angle()
獲取旋轉角度。
2. 旋轉矩陣轉換為四元數
Eigen::Matrix3d rotation_matrix;
// 填充旋轉矩陣Eigen::Quaterniond quaternion(rotation_matrix);
這段代碼示例已經在前面提供過,展示了如何將旋轉矩陣 rotation_matrix
轉換為對應的四元數 quaternion
。
3. 旋轉矩陣轉換為歐拉角
Eigen庫中沒有直接提供將旋轉矩陣轉換為歐拉角的函數,但可以通過以下步驟手動實現歐拉角的計算:
#include <Eigen/Dense>
#include <iostream>int main() {// 定義一個旋轉矩陣,例如繞Z軸旋轉60度Eigen::Matrix3d rotation_matrix;double angle = M_PI / 3.0; // 60度rotation_matrix << cos(angle), -sin(angle), 0,sin(angle), cos(angle), 0,0, 0, 1;// 計算歐拉角(ZYX順序)double phi = atan2(rotation_matrix(1, 0), rotation_matrix(0, 0));double theta = atan2(-rotation_matrix(2, 0), sqrt(rotation_matrix(2, 1) * rotation_matrix(2, 1) + rotation_matrix(2, 2) * rotation_matrix(2, 2)));double psi = atan2(rotation_matrix(2, 1), rotation_matrix(2, 2));// 輸出結果std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;std::cout << "Equivalent Euler angles (ZYX order):\n"<< "Phi (roll): " << phi << " radians\n"<< "Theta (pitch): " << theta << " radians\n"<< "Psi (yaw): " << psi << " radians" << std::endl;return 0;
}
在這個例子中,我們定義了一個旋轉矩陣 rotation_matrix
,表示繞Z軸旋轉60度。然后,通過手動計算歐拉角(ZYX順序),即 roll (phi
), pitch (theta
), yaw (psi
),從旋轉矩陣中提取這些角度信息。
這些例子展示了如何使用 Eigen 庫進行旋轉表示的各種轉換,從而在不同的場景中方便地處理旋轉操作。
四元數
Eigen::Quateriond
Eigen::Quaterniond
是 Eigen 庫中用于表示雙精度(double
)的四元數的類。四元數在計算機圖形學和機器人學等領域中廣泛用于表示旋轉。讓我展示如何使用 Eigen::Quaterniond
類來創建和操作四元數:
創建一個四元數
#include <Eigen/Dense>
#include <iostream>int main() {// 創建一個四元數,表示繞Z軸旋轉45度Eigen::Quaterniond quaternion;double angle = M_PI / 4.0; // 45度quaternion = Eigen::Quaterniond(cos(angle / 2), 0, 0, sin(angle / 2));// 輸出四元數的信息std::cout << "Quaternion:\n" << quaternion.coeffs().transpose() << std::endl;return 0;
}
在這個例子中,我們創建了一個四元數 quaternion
,它表示繞Z軸旋轉45度。四元數的構造方法 Eigen::Quaterniond
接受四個參數 (w, x, y, z)
,分別表示四元數的實部和虛部(三個虛部分量)。在這里,我們使用角度 angle
計算實部 w
和虛部 z
。
操作四元數
#include <Eigen/Dense>
#include <iostream>int main() {// 創建一個四元數,表示繞Z軸旋轉45度Eigen::Quaterniond quaternion(cos(M_PI / 8), 0, 0, sin(M_PI / 8));// 獲取旋轉矩陣Eigen::Matrix3d rotation_matrix = quaternion.toRotationMatrix();// 輸出旋轉矩陣std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;return 0;
}
#include <Eigen/Dense>
#include <iostream>int main() {// 創建一個四元數,表示繞Z軸旋轉45度Eigen::Quaterniond quaternion(cos(M_PI / 8), 0, 0, sin(M_PI / 8));// 獲取旋轉矩陣Eigen::Matrix3d rotation_matrix = quaternion.toRotationMatrix();// 輸出旋轉矩陣std::cout << "Rotation matrix:\n" << rotation_matrix << std::endl;return 0;
}