Affine transformation can be decomposed to translation, rotation, and scale.
As we know, the transformation can be represented by matrix.

It can be computed by translate matrix and rotate & scale matrix.

Example: I try to do decomposition for a matrix.

The matrix comes from the three basic linear transforms, scale, rotate and translate.

#include <vtkPointData.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkPolyData.h>
#include <vtkProperty.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkCommand.h>
#include <vtkSliderWidget.h>
#include <vtkSliderRepresentation.h>
#include <vtkTransform.h>
#include <vtkSliderRepresentation3D.h>
#include <vtkWidgetEventTranslator.h>
#include <vtkWidgetEvent.h>
#include <vtkCubeSource.h>
#include <vtkTransformFilter.h>
#include <vtkAxesActor.h>
#include "./tool.h"

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

int main(int, char *[])
{
vtkSPtrNew( source, vtkCubeSource );
source->Update();

vtkSPtrNew( scaleM, vtkTransform );
scaleM->Scale( 2, 2, 1 );
scaleM->Update();

double elements[16] = { 1, -1, 0, 0,
0, 0, -1, 0,
1, 1, 0, 0,
0, 0, 0, 1 };
vtkSPtrNew( rotateM, vtkTransform );
rotateM->SetMatrix( elements );
rotateM->Update();

vtkSPtrNew( moveM, vtkTransform );
moveM->Translate( 1, 1, 0 );
moveM->Update();

vtkSPtrNew( finalM, vtkTransform );
finalM->Concatenate( moveM );
finalM->Concatenate( rotateM );
finalM->Concatenate( scaleM );
finalM->Update();
finalM->PrintSelf( std::cout, vtkIndent() );

vtkSPtrNew( axes, vtkAxesActor );
axes->SetTotalLength( 1, 1, 1 ); // change length of three axis
axes->SetUserTransform( finalM );

double *scaleFactor = finalM->GetScale();
cout << "scaleFactor: " << scaleFactor[0] << ", " << scaleFactor[1] << ", " << scaleFactor[2] << endl;

vtkSPtrNew( renderer, vtkRenderer );
renderer->SetBackground( 0, 0, 0 );

vtkSPtrNew( renderWindow, vtkRenderWindow );

vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );

renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}


Define variable M =

## eigenvalue decomposition

We have to review the eigenvalue decomposition.

If there is a constant value and non-zero column vector has the relationship , we can get the new representation .
The eigenvalues are going to fill the diagonal, and the eigenvectors are going to form .

When the eigenvalues polynomial is equal to 0, it’s called the eigenvalues equation of A.

For example, A =

Solve it, we get: .

When , we have:

Set X=1, we get Y = -0.5. So an eigenvector is (1, -0.5).
In the case , we get the eigenvector(1, -1).

So we have :

## singular value decomposition

A more popular decomposition way for matrix is singular value decomposition, SVD. It says, . It can be proved by eigenvalue decomposition. SVD does not require the matrix to be decomposed as a square matrix. Let’s say our matrix A is an m x n matrix.

We can use SVD algorithm to decomposite the example’s matrix M.

// decomposition.
double factors[3];
auto matrix = finalM->GetMatrix();
double U[3][3], VT[3][3];
for( int i = 0; i < 3; ++i )
{
U[0][i] = matrix->GetElement( 0, i );
U[1][i] = matrix->GetElement( 1, i );
U[2][i] = matrix->GetElement( 2, i );
}
vtkMath::SingularValueDecomposition3x3( U, U, factors, VT );
vtkSPtrNew( matrix_U, vtkMatrix3x3 );
matrix_U->DeepCopy( (const double *)U );
matrix_U->PrintSelf( std::cout, vtkIndent() );
/*
0.707107    -0.707107   0
0   0   -1
0.707107    0.707107    0
*/

vtkSPtrNew( matrix_W, vtkMatrix3x3 );
matrix_W->Identity();
for( int i = 0; i < 3; ++i )
matrix_W->SetElement( i, i, factors[i] );
matrix_W->PrintSelf( std::cout, vtkIndent() );
/*
2.82843 0   0
0   2.82843 0
0   0   1
*/

vtkSPtrNew( matrix_VT, vtkMatrix3x3 );
matrix_VT->DeepCopy( (const double *)VT );
matrix_VT->PrintSelf( std::cout, vtkIndent() );
/*
1   0   0
0   1   0
0   0   1
*/


So we get:

The interface finalM->GetScale(); returns singular values of original matrix.

Categories: MathVTK

Article Rating
Subscribe
Notify of