從上一講的內容中可以知道一次完整的歐式變換(旋轉+平移)可以用式子:來表示。
假設我們現在對做了兩次歐式變換:和,得到的向量分別爲、,用上式來表示就是:
,,
於是從到的變換就可以寫成。
這不是一個線性關係,可以想象到,如果經過多次的歐式變換,那麼這個式子就會變的異常的複雜。
引入變換矩陣和齊次座標就是爲了解決這個問題。
變換矩陣和齊次座標
我們可以將上面從到變換的式子改寫成用矩陣表示的形式:
在上面的式子中,我們在一個三維向量的末尾添加了數字1,使得左邊變成了四維向量,稱爲齊次座標。
將上面的矩陣打開就是下面的式子:
對於這個四維向量,我們可以把旋轉和平移寫在一個矩陣裏面,通過引入矩陣使得整個關係變成線性關係。矩陣T稱爲變換矩陣。
關於齊次座標,還有下面這些需要知道。
通過添加最後一維,我們用四個實數來描述了一個三維向量,這顯然多了一個自由度,但是這樣允許我們把變換寫成線性的形式。在齊次座標中,某個點的每個分量同時乘以一個非零常數後,仍然表示同一個點。因此一個點的具體座標值不是唯一的。如和表示的是同一個點。
但是,當最後一項不爲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)
上面的程序中需要注意的就是:輸入矩陣數據的時候,使用的是輸出運算符而不是輸入運算符。(這裏的運算符都是重載之後的運算符)。
這一篇暫時就先學到這裏了,明天開始學習旋轉向量、歐拉角、四元數。