vtkMatrix4x4
vtkMatrix4x4类是一个用来表示和操作4阶矩阵的类。具体地说,它被设计用于使用4x4变换矩阵表示进行三维渲染时的齐次坐标[x y z w]。多数情况下采用列向量格式的16个double数组。
空间坐标变换是图像和图形学中的基础之一,VTK中大量与坐标和各个空间之间的转换,弄清楚变换的基本矩阵计算是很有必要的。vtkMatrix4x4和vtkMatrix3x3是VTK矩阵计算的基本操作数据结构。
接口
vtkMatrix4x4类中使用了一个public的double类型的二维数据的成员变量Element,记录了44个值;对应了一个44的齐次线性变换矩阵,第一列表示X轴方向,第二列表示Y轴方向,第三列表示Z轴方向,第四列表示(x,y,z)坐标和缩放系数;
double Element[4][4];
设置矩阵中的初始值:
Zero将每个位置的值都设置为0;
void Zero(){
vtkMatrix4x4::Zero(*this->Element);
this->Modified();
}
static void Zero(double elements[16]);
[
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
]
\begin{bmatrix} 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 \end{bmatrix}
⎣⎢⎢⎡0000000000000000⎦⎥⎥⎤
使用Identity()方法将Element值,填写为单位矩阵;
使用IsIdentity()方法判断矩阵是否为单位矩阵;
void Identity(){
vtkMatrix4x4::Identity(*this->Element);
this->Modified();
}
static void Identity(double elements[16]);
bool IsIdentity();
[
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
]
\begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}
⎣⎢⎢⎡1000010000100001⎦⎥⎥⎤
计算逆矩阵;
1.伴随矩阵A*是矩阵A元素所对应的代数余子式,所构成的矩阵,转置后得到的新矩阵。
2.求出矩阵A的行列式|A|;
3.逆矩阵A⁻¹=A*/|A|
static void Invert(const vtkMatrix4x4* in, vtkMatrix4x4* out){
vtkMatrix4x4::Invert(*in->Element, *out->Element);
out->Modified();
}
void Invert() { vtkMatrix4x4::Invert(this, this); }
static void Invert(const double inElements[16], double outElements[16]);
Invert的实现:
//----------------------------------------------------------------------------
// Matrix Inversion (adapted from Richard Carling in "Graphics Gems,"
// Academic Press, 1990).
void vtkMatrix4x4::Invert(const double inElements[16], double outElements[16]) {
// inverse( original_matrix, inverse_matrix )
// calculate the inverse of a 4x4 matrix
//
// -1
// A = ___1__ adjoint A
// det A
//
// calculate the 4x4 determinent
// if the determinent is zero,
// then the inverse matrix is not unique.
double det = vtkMatrix4x4::Determinant(inElements);
if (det == 0.0) {
return;
}
// calculate the adjoint matrix
vtkMatrix4x4::Adjoint(inElements, outElements);
// scale the adjoint matrix to get the inverse
for (int i = 0; i < 16; i++) {
outElements[i] /= det;
}
}
计算转置矩阵;
static void Transpose(const vtkMatrix4x4* in, vtkMatrix4x4* out){
vtkMatrix4x4::Transpose(*in->Element, *out->Element);
out->Modified();
}
void Transpose() { vtkMatrix4x4::Transpose(this, this); }
static void Transpose(const double inElements[16], double outElements[16]);
一维点向量通过变换矩阵的处理计算,是左乘;
void MultiplyPoint(const float in[4], float out[4]){
vtkMatrix4x4::MultiplyPoint(*this->Element, in, out);
}
void MultiplyPoint(const double in[4], double out[4]){
vtkMatrix4x4::MultiplyPoint(*this->Element, in, out);
}
static void MultiplyPoint(const double elements[16], const float in[4], float out[4]);
static void MultiplyPoint(const double elements[16], const double in[4], double out[4]);
float* MultiplyPoint(const float in[4]) VTK_SIZEHINT(4) { return this->MultiplyFloatPoint(in); }
double* MultiplyPoint(const double in[4]) VTK_SIZEHINT(4){
return this->MultiplyDoublePoint(in);
}
float* MultiplyFloatPoint(const float in[4]) VTK_SIZEHINT(4){
this->MultiplyPoint(in, this->FloatPoint);
return this->FloatPoint;
}
double* MultiplyDoublePoint(const double in[4]) VTK_SIZEHINT(4){
this->MultiplyPoint(in, this->DoublePoint);
return this->DoublePoint;
}
矩阵乘法
矩阵a右乘矩阵b,将结果放入矩阵c中;
MultiplyAndTranspose4x4()方法在乘法运算后,进行转置;
static void Multiply4x4(const vtkMatrix4x4* a, const vtkMatrix4x4* b, vtkMatrix4x4* c);
static void Multiply4x4(const double a[16], const double b[16], double c[16]);
static void Multiply4x4(const double a[16], const double b[16], float c[16]);
static void MultiplyAndTranspose4x4(const double a[16], const double b[16], float c[16]);
计算伴随矩阵,矩阵的伴随矩阵可用于矩阵的求逆运算。
void Adjoint(const vtkMatrix4x4* in, vtkMatrix4x4* out){
vtkMatrix4x4::Adjoint(*in->Element, *out->Element);
}
static void Adjoint(const double inElements[16], double outElements[16]);
计算行列式的值。
double Determinant() { return vtkMatrix4x4::Determinant(*this->Element); }
static double Determinant(const double elements[16]);
对Element的值进行读取。
void SetElement(int i, int j, double value);
double GetElement(int i, int j) const { return this->Element[i][j]; }
double* GetData() { return *this->Element; }
const double* GetData() const { return *this->Element; }
参考资料
1. File Reference