https://blog.csdn.net/minmindianzi/article/details/84279434
VTK相关的类有:
vtkTransform, vtkTransformFilter, vtkMatrix4x4等
相关的方法有:
• RotateX(angle)、RotateY(angle)、RotateZ(angle)
• RotateWXYZ(angle,x,y,z)
• Scale(x,y,z)
• Translate(x,y,z)
• SetMatrix(m)、GetMatrix(m)
• PostMultiply()、PreMultiply()
• SetPosition(x,y,z)、GetPosition(x,y,z)
• SetOrientation(x,y,z)、 GetOrientation(x,y,z)
• SetScale(sx,sy,sz)
• SetOrigin(x,y,z)、GetOrigin
空间变换类
vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
在VTK中,矩阵乘法默认是左乘(PreMultiply),在齐次矩阵符号中,M = M*A,其中M为当前变换矩阵,A为要应用矩阵(比如旋转矩阵或者平移矩阵)。
trans->PreMultiply();//M=M*A
源码中是这样解释的: vtkTransform.h的156行
* Sets the internal state of the transform to PreMultiply. All subsequent
* operations will occur before those already represented in the
* current transformation. In homogeneous matrix notation, M = M*A where
* M is the current transformation matrix and A is the applied matrix.
* The default is PreMultiply.
A就是指“All subsequent operations”,M就是指“those already represented in the current transformation”
我对before的理解就是A左乘M(A的左边乘上M)
当然,也可以设置矩阵乘法为右乘(PostMultiply),在齐次矩阵符号中,M = A*M,其中M为当前变换矩阵,A为要应用矩阵(比如旋转矩阵或者平移矩阵)。
trans->PostMultiply();//M=A*M
源码中是这样写的:
* Sets the internal state of the transform to PostMultiply. All subsequent
* operations will occur after those already represented in the
* current transformation. In homogeneous matrix notation, M = A*M where
* M is the current transformation matrix and A is the applied matrix.
* The default is PreMultiply.
我对after的理解就是A右乘M(A的右边乘上M)
实例分析:
三维物体的初始齐次矩阵为:
矩阵右乘(post后置),先旋转再平移
trans->PostMultiply();//M=A*M
trans->RotateZ(30);
trans->Translate(1, 0, 0);
矩阵右乘(post后置),先平移再旋转
trans->PostMultiply();//M=A*M
trans->Translate(1, 0, 0);
trans->RotateZ(30);
矩阵左乘(pre前置),先旋转再平移
trans->PreMultiply();//M=M*A
trans->RotateZ(30);
trans->Translate(1, 0, 0);
矩阵左乘(pre前置),先平移再旋转
trans->PreMultiply();//M=M*A
trans->Translate(1, 0, 0);
trans->RotateZ(30);
#include <vtkLineSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkAxesActor.h>
#include <vtkConeSource.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkTransform.h>
#include <vtkSphereSource.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType)
int main(int, char *[])
{
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(0.1);//设置半径
sphereSource->Update();
vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
vtkSmartPointer<vtkActor> sphereActor =
vtkSmartPointer<vtkActor>::New();
sphereActor->SetPosition(0, 0, 0);//设置演员的位置
sphereActor->SetMapper(sphereMapper);//设置演员的映射器
sphereActor->GetProperty()->SetColor(1, 0, 0);//设置演员的颜色
vtkSmartPointer<vtkConeSource> coneSource =
vtkSmartPointer<vtkConeSource>::New();
coneSource->SetRadius(.2);
coneSource->SetHeight(.5);
coneSource->SetCenter(0, 0, 0);
vtkSmartPointer<vtkPolyDataMapper> coneMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
coneMapper->SetInputConnection(coneSource->GetOutputPort());
vtkSmartPointer<vtkActor> coneActor =
vtkSmartPointer<vtkActor>::New();
coneActor->SetMapper(coneMapper);
vtkSmartPointer<vtkActor> oriConeActor =
vtkSmartPointer<vtkActor>::New();
oriConeActor->SetMapper(coneMapper);
#define AXIS_LEN 1.
vtkSmartPointer<vtkAxesActor> oriAxesActor =
vtkSmartPointer<vtkAxesActor>::New();
oriAxesActor->SetPosition(0, 0, 0);
oriAxesActor->SetTotalLength(AXIS_LEN, AXIS_LEN, AXIS_LEN);
oriAxesActor->SetShaftType(0);
oriAxesActor->SetAxisLabels(0);
oriAxesActor->SetCylinderRadius(0.02);
vtkSmartPointer<vtkAxesActor> axesActor =
vtkSmartPointer<vtkAxesActor>::New();
axesActor->SetPosition(0, 0, 0);
axesActor->SetTotalLength(AXIS_LEN, AXIS_LEN, AXIS_LEN);
axesActor->SetShaftType(0);
axesActor->SetAxisLabels(0);
axesActor->SetCylinderRadius(0.02);
vtkSmartPointer<vtkTextActor> textActor =
vtkSmartPointer<vtkTextActor>::New();
textActor->SetPosition2(100, 40);
textActor->GetTextProperty()->SetFontSize(24);
textActor->GetTextProperty()->SetColor(1, 0, 0);
vtkSmartPointer<vtkTransform> trans =
vtkSmartPointer<vtkTransform>::New();
//trans->PostMultiply();//M=A*M
trans->PreMultiply();//M=M*A
trans->RotateZ(30);
//coneActor->SetPosition(1, 0, 0);永远M=M*A
trans->Translate(1, 0, 0);
//trans->RotateZ(30);
//trans->Translate(1, 0, 0);
//trans->RotateZ(30);
coneActor->SetUserTransform(trans);
textActor->SetInput("PostMultiply()\nTranslate(1, 0, 0)\nRotateZ(30)");
cout << "GetMatrix:" << endl;
if (coneActor->GetMatrix() != NULL)
{
coneActor->GetMatrix()->Print(cout);
}
else
{
cout << "NULL" << endl;
}
cout << "GetUserMatrix:" << endl;
if (coneActor->GetUserMatrix() != NULL)
{
coneActor->GetUserMatrix()->Print(cout);
}
else
{
cout << "NULL" << endl;
}
vtkSmartPointer<vtkRenderer> renderer1 =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderer> renderer2 =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(800, 400);
renderWindow->AddRenderer(renderer1);
renderWindow->AddRenderer(renderer2);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
double leftViewport[] = { 0.0, 0.0, 0.5, 1.0 };
double rightViewport[] = { 0.5, 0.0, 1.0, 1.0 };
renderer1->AddActor(oriAxesActor);
renderer1->AddActor(sphereActor);
renderer1->AddActor(oriConeActor);
renderer2->AddActor(axesActor);
renderer2->AddActor(sphereActor);
renderer2->AddActor(coneActor);
renderer2->AddActor2D(textActor);
renderer1->SetBackground(.3, .3, .5);
renderer2->SetBackground(.2, .4, .5);
renderer1->SetViewport(leftViewport);
renderer2->SetViewport(rightViewport);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}