Understand vtk pre-multiplication and post-multiplication

·

1 min read

Let's look at matrix multiplication first

vtkNew<vtkTransform> transformA;
transformA->Translate(10, 0, 0);
std::cout<<"matrixA="<<std::endl<<*transformA->GetMatrix()<<std::endl;

vtkNew<vtkTransform> transformB;
transformB->RotateZ(90);
std::cout<<"matrixB="<<std::endl<<*transformB->GetMatrix()<<std::endl;

vtkNew<vtkMatrix4x4> matrixC;
vtkNew<vtkMatrix4x4> matrixD;

vtkMatrix4x4::Multiply4x4(transformA->GetMatrix(), transformB->GetMatrix(), matrixC);
vtkMatrix4x4::Multiply4x4(transformB->GetMatrix(), transformA->GetMatrix(), matrixD);

std::cout<<"C = A x B"<<std::endl<<*matrixC<<std::endl;
std::cout<<"D = B x A"<<std::endl<<*matrixD<<std::endl;

Output

Pre Multiple

// Default operation is premultiple
vtkNew<vtkTransform> transformE;
transformE->Translate(10, 0, 0);
transformE->RotateZ(90);
std::cout<<"transformE="<<std::endl<<*transformE->GetMatrix()<<std::endl;

Output

Post multiple

vtkNew<vtkTransform> transformF;
transformF->PostMultiply();
transformF->Translate(10, 0, 0);
transformF->RotateZ(90);
std::cout<<"transformF="<<std::endl<<*transformF->GetMatrix()<<std::endl;

Output

If we combine an object, it will be clearer

Default

Pre Multiple

rotateZ(90) --> translate(10, 0, 0)

Post Multiple

translate(10, 0, 0) --> rotateZ(90)

In conclusion

  • The order of pre-multiplication is the same as the order of matrix multiplication, but contrary to the actual reading order. In other words, the operation of the earlier transformation should be placed at the end.

  • The order of post-multiplication is opposite to the order of matrix multiplication, but it is the same as the actual reading order, and the operation of the earlier transformation should be placed in front