Eigen库使用简介

Eigen是开源的C++线性代数库,常用在计算机图形学中。
有份英文的Eigen使用手册,简要整理一下

安装
$ cd ~
$ git clone https://github.com/eigenteam/eigen-git-mirror

Eigen所有的文件都是h文件,只需include即可使用,
但是要告诉编译器它在哪个位置。

$ sudo ln -s /usr/local/include ~/eigen-git-mirror/Eigen
使用
#include <Eigen/Core>

创建新矩阵的时候如下

Matrix3f A;
Matrix4d B;

这里的命名有一个便利性,比如A的类型是Matrix3f,就表示A是3x3 float型矩阵,
同理B是4x4 double型矩阵。
但并不是所有组合都work的,比如Matrix5s就会报错(虽然想的是5x5 short);也不是必须是正方形的矩阵。
那如果想用5x5 short的maxtrix呢?或者是长和宽不同的矩阵呢?

Matrix<short, 5, 5> M1;
Matrix<float, 20, 75> M2;

另外,Eigen还支持在编译的时候还不知道长和宽的矩阵,用X代替,如MatrixXf, MatrixXd。

矩阵的初始化
// Initialize A
A << 1.0 f , 0.0 f , 0.0 f ,
	0.0 f , 1.0 f , 0.0 f ,
	0.0 f , 0.0 f , 1.0 f ;
	
// Initialize B by accessing individual elements
for i = 1:4 {
	for j = 1:4 {
		B (j , i ) = 0.0;
	}
}

上面第一种方式,会一行一行地向矩阵中填入数字,所有的数字都必须提供,
如果size不match的话会报错。

第二种方式,B矩阵,可以看到是一列一列填数字的,当然也可以换成一行一行填,不过Eigen的储存方式是列主导的,一列一列填效率会更高。

指定某元素的时候不像C++那样用方括号,A[i. j], 而是圆括号A(i, j)。

也有便利的方式初始化数值

// Set each coefficient to a uniform random value in the range
[ -1 , 1]
A = Matrix3f :: Random () ;

// Set B to the identity matrix
B = Matrix4d :: Identity () ;

// Set all elements to zero
A = Matrix3f :: Zero () ;

// Set all elements to ones
A = Matrix3f :: Ones () ;

// Set all elements to a constant value
B = Matrix4d :: Constant (4.5) ;
矩阵运算

常用的矩阵运算来一波

Matrix4f M1 = Matrix4f :: Random () ;
Matrix4f M2 = Matrix4f :: Constant (2.2) ;

// Addition
// The size and the coefficient - types of the matrices must match
cout << M1 + M2 << endl ;

// Matrix multiplication
// The inner dimensions and the coefficient - types must match
cout << M1 * M2 << endl ;

// Scalar multiplication , and subtraction
// What do you expect the output to be ?
cout << M2 - Matrix4f :: Ones () * 2.2 << endl ;

等号(==)和不等号(!=)也可用在矩阵的比较上,所有对应数字都相等矩阵才相等。

cout << ( M2 - Matrix4f :: Ones () * 2.2 == Matrix4f :: Zero () )
<< endl 

矩阵的转置和逆运算

// Transposition
cout << M1 . transpose () << endl ;

// Inversion ( # include < Eigen / Dense > )
// Generates NaNs if the matrix is not invertible
cout << M1 . inverse () << endl ;

如果想进行矩阵的element-wise计算,可以把矩阵当作array来计算,通过调用array()方法

// Square each element of the matrix
cout << M1 . array () . square () << endl ;

// Multiply two matrices element - wise
cout << M1 . array () * Matrix4f :: Identity () . array () << endl ;

// All relational operators can be applied element - wise
cout << M1 . array () <= M2 . array () << endl << endl ;
cout << M1 . array () > M2 . array () << endl ;

注意上面的方法不是in place的,就是说不是在原矩阵上运算的,它会返回一个新的矩阵,比如
M1.array().sqrt()运算后会返回一个新矩阵,而M1数值不变。

Vector和矩阵用法类似,参考Eigen使用手册

平移和旋转
# include < Eigen / Core >
# include < Eigen / Geometry >
# include < iostream >
using namespace std ;
using namespace Eigen ;
int main () {
	float arrVertices [] = { -1.0 , -1.0 , -1.0 ,
							1.0 , -1.0 , -1.0 ,
							1.0 , 1.0 , -1.0 ,
							-1.0 , 1.0 , -1.0 ,
							-1.0 , -1.0 , 1.0 ,
							1.0 , -1.0 , 1.0 ,
							1.0 , 1.0 , 1.0 ,
							-1.0 , 1.0 , 1.0};
	MatrixXf mVertices = Map < Matrix < float , 3 , 8 > > ( arrVertices ) ;
	Transform < float , 3 , Affine > t = Transform < float , 3 , Affine >::
				Identity () ;
	t . scale ( 0.8 f ) ;
	t . rotate ( AngleAxisf (0.25 f * M_PI , Vector3f :: UnitX () ) ) ;
	t . translate ( Vector3f (1.5 , 10.2 , -5.1) ) ;
	cout << t * mVertices . colwise () . homogeneous () << endl ;
}

上面用C++数组初始化一个MatrixXf型的矩阵,包含了x,y,z坐标。通过Eigen的Map类来初始化矩阵。
t进行了scale, 旋转和平移变换。用矩阵表示的话,变换如下
U = TRSI,其中I表示单位矩阵。

rotation包含了旋转角度和旋转轴,旋转轴必须是归一化的单位向量;可以用AngleAxisf类把旋转角和旋转轴组合到一起。
Vector3f::UnitX(), Vector3f::UnitY, Vector3f::UnitZ() 分别表示x, y, z方向的单位向量。

更多的使用方法请参考

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值