第三講 變換矩陣與齊次座標
從上一講的內容中可以知道一次完整的歐式變換(旋轉+平移)可以用式子:來表示。
假設我們現在對做了兩次歐式變換:
和
,得到的向量分別為
、
,用上式來表示就是:
,
,
於是從到
的變換就可以寫成
。
這不是一個線性關係,可以想象到,如果經過多次的歐式變換,那麼這個式子就會變的異常的複雜。
引入變換矩陣和齊次座標就是為了解決這個問題。
變換矩陣和齊次座標
我們可以將上面從到
變換的式子改寫成用矩陣表示的形式:
在上面的式子中,我們在一個三維向量的末尾添加了數字1,使得左邊變成了四維向量,稱為齊次座標。
將上面的矩陣開啟就是下面的式子:
對於這個四維向量,我們可以把旋轉和平移寫在一個矩陣裡面,通過引入矩陣
關於齊次座標,還有下面這些需要知道。
通過新增最後一維,我們用四個實數來描述了一個三維向量,這顯然多了一個自由度,但是這樣允許我們把變換寫成線性的形式。在齊次座標中,某個點的每個分量同時乘以一個非零常數
後,仍然表示同一個點。因此一個點的具體座標值不是唯一的。如
和
表示的是同一個點。
但是,當最後一項不為0時,我們總是可以把所有座標分量除以最後一項,強制最後一項為1,從而得到一個點唯一的座標表示。(也就是將非齊次座標轉換為齊次座標)。如:
通過齊次座標和變換矩陣,兩次變換(多次變換也是如此)的累加就可以有很好的形式:
實踐部分:Eigen庫使用
Eigen是一個c++開源線性代數庫。它提供了快速的有關矩陣的線性代數運算,包括解方程等功能。關於Eigen的更多資料可以在這裡找到。
1、Eigen庫的安裝
如果在ubuntu上還沒有安裝Eigen庫的話,可以先使用apt-get命令安裝Eigen:
sudo apt-get install libeigen3-dev
我已經安裝過了,執行之後提示如下:
Eigen標頭檔案的預設位置在 /usr/include/eigen3/ 中。
與其他庫相比,Eigen的特殊之處在於:它是一個純用標頭檔案搭建起來的庫。這意味著你只能找到它的標頭檔案,而沒有.so或者.a那樣的二進位制檔案。在使用的時候,也只需要引入Eigen的標頭檔案即可,不需要連結庫檔案(因為根本就沒有庫檔案)。
2、呼叫Eigen庫進行矩陣運算
首先,簡單的介紹介紹一下Matrix class:Eigen庫以矩陣為基本資料單元,它是一個模板類,定義如下:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
三個引數的含義分別為:資料型別、行數、列數。
例如,下面語句定義了一個4*4的float型別的矩陣:
Eigen::Matrix<float, 4, 4> matrix4f;
使用Eigen庫的時候,由於Eigen庫沒有庫檔案,因此不需要使用target_link_directories語句,只需要使用一個連結標頭檔案目錄的語句include_directories,如下:
include_directories("/usr/include/eigen3")
原始檔內容:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
int main() {
//定義一個2*3的int矩陣和一個3*2的int矩陣
Eigen::Matrix<int, 2, 3> matrix3i_a;
Eigen::Matrix<int, 3, 2> matrix3i_b;
//輸入矩陣matrix3i_a資料
cout<<"matrix3i_a的內容為:"<<endl;
matrix3i_a<<1, 2, 3, 4, 5, 6;
cout<<matrix3i_a<<endl;
//輸入矩陣matrix3i_b資料
for(int i=0; i<3; i++){
for(int j=0; j<2; j++){
matrix3i_b(i, j)=2*i;
}
}
cout<<"matrix3i_b的內容為:"<<endl;
cout<<matrix3i_b<<endl;
//matrix3i_a和matrix3i_b進行四則運算
cout<<"matrix3i_a*matrix3i_b的結果為:"<<endl;
cout<<matrix3i_a*matrix3i_b<<endl;
cout<<"matrix3i_a的轉置為:"<<endl;
cout<<matrix3i_a.transpose()<<endl;
cout<<"matrix3i_a的各個元素的和為:"<<endl;
cout<<matrix3i_a.sum()<<endl;
return 0;
}
CMakeLists.txt的內容:
cmake_minimum_required(VERSION 3.12)
project(use_eigen)
set(CMAKE_CXX_STANDARD 14)
#新增標頭檔案
include_directories("/usr/include/eigen3")
add_executable(use_eigen main.cpp)
上面的程式中需要注意的就是:輸入矩陣資料的時候,使用的是輸出運算子而不是輸入運算子。(這裡的運算子都是過載之後的運算子)。
這一篇暫時就先學到這裡了,明天開始學習旋轉向量、尤拉角、四元數。