大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
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是3×3 float型矩阵,
同理B是4×4 double型矩阵。
但并不是所有组合都work的,比如Matrix5s就会报错(虽然想的是5×5 short);也不是必须是正方形的矩阵。
那如果想用5×5 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方向的单位向量。
更多的使用方法请参考
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183727.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...