VTK可视化工具包之旅06-坐标系统以及空间变换

265 阅读2分钟

计算机图形学中的坐标系统主要有4种,分别是Model系统,World坐标系统,View坐标系统和Display坐标系统,此外还有两种不同的表示坐标点的方式:以屏幕像素为单位和归一化坐标值。

  • Model坐标是采用定义模型时候采用的坐标系统,通常是局部的笛卡尔坐标系,
  • World坐标系统是放置Actor的三维坐标系,Actor(vtkActor类)其中的一个功能就是负责将模型从Model坐标系变换到World坐标系统。每一个模型可以定义自己的Model坐标系统,但是World坐标系统只能有一个。每一个Actor必须通过缩放、平移、旋转等操作将Model坐标系变换到World坐标系。World坐标系同时也是相机和灯光所在的坐标系。
  • View坐标系表示的是相机看见的坐标系统。X、Y、Z轴取值为[-1,1]表示平面上的距离,Z表示到相机的距离。相机负责将World坐标系变成View坐标系
  • Display坐标系与View坐标系类似,但是各坐标轴的取值不是[-1,1],而是使用屏幕像素值。所以可以吧不同的渲染场景放到一个窗口中进行演示。

实现效果

image.png

步骤拆分

  1. 定义Cube、Cone、cylinder、sphere 四个要放在对应场景中的物体(source)
  2. 分别构造他们的mappersphereMapper->SetInputConnection(sphere->GetOutputPort());
  3. 通过vtkActor来具象化这些物体(SetMapper)
  4. 定义renderer1、renderer2、renderer3、renderer4四个不同的场景渲染器。然后将他们分别规定渲染窗口的哪些位置。
  5. 将这些渲染器都加入到窗口当中去:AddRenderer

关键代码

	vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
	renderer1->AddActor(coneActor);
	renderer1->SetBackground(1.0, 0.0, 0.0);
	renderer1->SetViewport(0.0, 0.0, 0.5, 0.5);
	vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
	renderer2->AddActor(cubeActor);
	renderer2->SetBackground(0.0, 1.0, 0.0);
	renderer2->SetViewport(0.5, 0.0, 1.0, 0.5);
	vtkSmartPointer<vtkRenderer> renderer3 = vtkSmartPointer<vtkRenderer>::New();
	renderer3->AddActor(cylinderActor);
	renderer3->SetBackground(0.0, 0.0, 1.0);
	renderer3->SetViewport(0.0, 0.5, 0.5, 1.0);
	vtkSmartPointer<vtkRenderer> renderer4 = vtkSmartPointer<vtkRenderer>::New();
	renderer4->AddActor(sphereActor);
	renderer4->SetBackground(1.0, 1.0, 0.0);
	renderer4->SetViewport(0.5, 0.5, 1.0, 1.0);

代码实现


#include <vtkConeSource.h>
#include <vtkCubeSource.h>
#include <vtkCylinderSource.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>

#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);

int main()
{
	vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
	vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
	vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
	vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();

	vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	coneMapper->SetInputConnection(cone->GetOutputPort());
	vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	cubeMapper->SetInputConnection(cube->GetOutputPort());
	vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
	vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	sphereMapper->SetInputConnection(sphere->GetOutputPort());

	vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
	coneActor->SetMapper(coneMapper);
	vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();
	cubeActor->SetMapper(cubeMapper);
	vtkSmartPointer<vtkActor> cylinderActor = vtkSmartPointer<vtkActor>::New();
	cylinderActor->SetMapper(cylinderMapper);
	vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
	sphereActor->SetMapper(sphereMapper);


	vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
	renderer1->AddActor(coneActor);
	renderer1->SetBackground(1.0, 0.0, 0.0);
	renderer1->SetViewport(0.0, 0.0, 0.5, 0.5);
	vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
	renderer2->AddActor(cubeActor);
	renderer2->SetBackground(0.0, 1.0, 0.0);
	renderer2->SetViewport(0.5, 0.0, 1.0, 0.5);
	vtkSmartPointer<vtkRenderer> renderer3 = vtkSmartPointer<vtkRenderer>::New();
	renderer3->AddActor(cylinderActor);
	renderer3->SetBackground(0.0, 0.0, 1.0);
	renderer3->SetViewport(0.0, 0.5, 0.5, 1.0);
	vtkSmartPointer<vtkRenderer> renderer4 = vtkSmartPointer<vtkRenderer>::New();
	renderer4->AddActor(sphereActor);
	renderer4->SetBackground(1.0, 1.0, 0.0);
	renderer4->SetViewport(0.5, 0.5, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
	renWin->AddRenderer(renderer1);
	renWin->AddRenderer(renderer2);
	renWin->AddRenderer(renderer3);
	renWin->AddRenderer(renderer4);
	renWin->SetSize(640, 480);
	renWin->Render();
	renWin->SetWindowName("Viewport");

	vtkSmartPointer<vtkRenderWindowInteractor> interactor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	interactor->SetRenderWindow(renWin);

	renWin->Render();
	interactor->Initialize();
	interactor->Start();

	return EXIT_SUCCESS;
}