当前位置: 首页 > news >正文

利用vtkTransform类对模型位置变换、缩放、镜面成像等

        vtk的vtkTransform类可以对三维模型进行位置变换、缩放、镜面成像,如下代码绘制了一个球体和一个三棱锥,通过vtkTransform类对球体、三棱锥位置变换、缩放、镜面成像:

#include <vtkConeSource.h>
#include <vtkLogger.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
int main(int argc, char* argv[])
{
    vtkLogger::Init(argc, argv);

    // Colors
    vtkNew<vtkNamedColors> colors;
    vtkColor3d coneColor = colors->GetColor3d("Tomato");
    vtkColor3d sphereColor = colors->GetColor3d("Banana");
    vtkColor3d backgroundColor = colors->GetColor3d("Peacock");

    // Create the graphics structure. The renderer renders into the
    // render window.
    vtkNew<vtkRenderWindowInteractor> iren;
    vtkNew<vtkRenderer> ren1;
    ren1->SetBackground(backgroundColor.GetData());

    vtkNew<vtkRenderWindow> renWin;
    iren->SetRenderWindow(renWin);
    renWin->AddRenderer(ren1);

    // Generate a sphere
    vtkNew<vtkSphereSource> sphereSource;
    sphereSource->SetPhiResolution(31);
    sphereSource->SetThetaResolution(31);
    //sphereSource->SetStartTheta(135);
    //sphereSource->SetStartPhi(135);

    vtkNew<vtkPolyDataMapper> sphereMapper;
    sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
    vtkNew<vtkActor> sphere;
    sphere->SetMapper(sphereMapper);
    sphere->GetProperty()->SetDiffuseColor(sphereColor.GetData());
    sphere->GetProperty()->SetDiffuse(.7);
    sphere->GetProperty()->SetSpecular(.3);
    sphere->GetProperty()->SetSpecularPower(30.0);

    vtkNew<vtkTransform> sphereTrans;
    sphereTrans->Scale(5, 5, 5);
    sphere->SetUserTransform(sphereTrans);

    ren1->AddActor(sphere);

    // Generate a cone
    vtkNew<vtkConeSource> coneSource;
    coneSource->SetResolution(31);

    vtkNew<vtkPolyDataMapper> coneMapper;
    coneMapper->SetInputConnection(coneSource->GetOutputPort());
    // auto cone = vtkSmartPointer<vtkActor>::New();
    vtkNew<vtkActor> cone;
    cone->SetMapper(coneMapper);
    cone->GetProperty()->SetDiffuseColor(coneColor.GetData());

    vtkNew<vtkTransform> coneTrans;
    coneTrans->Translate(6.0, 0.0, 0.0);
    //coneTrans->Scale(-1, 1, 1);
    cone->SetUserTransform(coneTrans);

    ren1->AddActor(cone);
    renWin->SetWindowName("AnimateActors");

    renWin->Render();
    ren1->ResetCamera();
    ren1->ResetCameraClippingRange();

    vtkNew<vtkInteractorStyleTrackballCamera> style;
    iren->SetInteractorStyle(style);

    iren->Initialize();
    iren->Start();

    return EXIT_SUCCESS;
}

其中53~55行将球分别沿X、Y、Z轴方向放大5倍;70~73行将三菱锥沿X轴正方向移动6个单位,效果如下:

将72行注释取消,则效果如下:

 

可以看到圆锥体在X轴反向了,即以Y轴所在平面(VTK默认的Y轴正方向为从屏幕底部指向屏幕顶部)且垂直于屏幕的平面为镜子成镜面成像,可以理解为对X坐标取相反数了,即如果X坐标原来是1,镜面成像后变为-1。

 将53~55行、70~73行都注释,即不加任何变换的原始效果如下图:

以上是场景中的模型个数大于1,对场景中模型个数为1时,如果不另外处理,则vtkTransform类无效果,如下代码,整个场景中只绘制了一个三棱锥:

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkConeSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include<vtkTransform.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
int main(int, char* [])
{
	vtkNew<vtkNamedColors> colors;

	//
	// Next we create an instance of vtkConeSource and set some of its
	// properties. The instance of vtkConeSource "cone" is part of a
	// visualization pipeline (it is a source process object); it produces data
	// (output type is vtkPolyData) which other filters may process.
	//
	vtkNew<vtkConeSource> cone;
	cone->SetHeight(3.0);
	cone->SetRadius(1.0);
	cone->SetResolution(10);

	//
	// In this example we terminate the pipeline with a mapper process object.
	// (Intermediate filters such as vtkShrinkPolyData could be inserted in
	// between the source and the mapper.)  We create an instance of
	// vtkPolyDataMapper to map the polygonal data into graphics primitives. We
	// connect the output of the cone source to the input of this mapper.
	//
	vtkNew<vtkPolyDataMapper> coneMapper;
	coneMapper->SetInputConnection(cone->GetOutputPort());

	//
	// Create an actor to represent the cone. The actor orchestrates rendering
	// of the mapper's graphics primitives. An actor also refers to properties
	// via a vtkProperty instance, and includes an internal transformation
	// matrix. We set this actor's mapper to be coneMapper which we created
	// above.
	//
	vtkNew<vtkActor> coneActor;
	coneActor->SetMapper(coneMapper);
	coneActor->GetProperty()->SetColor(colors->GetColor3d("Bisque").GetData());

	vtkNew<vtkTransform> trans;
	trans->Translate(1.0, 0.0, 0.0);
	trans->Scale(3, 3, 3);
	coneActor->SetUserTransform(trans);
	//
	// Create the Renderer and assign actors to it. A renderer is like a
	// viewport. It is part or all of a window on the screen and it is
	// responsible for drawing the actors it has.  We also set the background
	// color here.
	//
	vtkNew<vtkRenderer> ren1;
	ren1->AddActor(coneActor);
	ren1->SetBackground(colors->GetColor3d("MidnightBlue").GetData());

	//ren1->GetActiveCamera()->Dolly(0.15);
	//ren1->GetActiveCamera()->SetFocalPoint(0.15, 0, 0);
	//
	// Finally we create the render window which will show up on the screen.
	// We put our renderer into the render window using AddRenderer. We also
	// set the size to be 300 pixels by 300.
	//
	vtkNew<vtkRenderWindow> renWin;
	renWin->AddRenderer(ren1);
	renWin->SetSize(800, 600);
	renWin->SetWindowName("vtkTransform");

	//
	// The vtkRenderWindowInteractor class watches for events (e.g., keypress,
	// mouse) in the vtkRenderWindow. These events are translated into
	// event invocations that VTK understands (see VTK/Common/vtkCommand.h
	// for all events that VTK processes). Then observers of these VTK
	// events can process them as appropriate.
	vtkNew<vtkRenderWindowInteractor> iren;
	iren->SetRenderWindow(renWin);

	//
	// By default the vtkRenderWindowInteractor instantiates an instance
	// of vtkInteractorStyle. vtkInteractorStyle translates a set of events
	// it observes into operations on the camera, actors, and/or properties
	// in the vtkRenderWindow associated with the vtkRenderWinodwInteractor.
	// Here we specify a particular interactor style.
	vtkNew<vtkInteractorStyleTrackballCamera> style;
	iren->SetInteractorStyle(style);

	//
	// Unlike the previous scripts where we performed some operations and then
	// exited, here we leave an event loop running. The user can use the mouse
	// and keyboard to perform the operations on the scene according to the
	// current interaction style. When the user presses the "e" key, by default
	// an ExitEvent is invoked by the vtkRenderWindowInteractor which is caught
	// and drops out of the event loop (triggered by the Start() method that
	// follows.
	//
	iren->Initialize();
	iren->Start();

	//
	// Final note: recall that observers can watch for particular events and
	// take appropriate action. Pressing "u" in the render window causes the
	// vtkRenderWindowInteractor to invoke a UserEvent. This can be caught to
	// popup a GUI, etc. See the Tcl Cone5.tcl example for an idea of how this
	// works.

	return EXIT_SUCCESS;
}

上述代码的53~56行设置了平移和放大变换,但并未按预想的那样平移和放大模型,模型依然和没加53~56行代码时的效果一样,为使平移和放大变换起作用,必须取消67或68行中的任意一行才行。关于Dolly函数的作用,请参考:vtkCamera类的Dolly函数作用及相机拉近拉远

相关文章:

  • 医疗报销系统的设计与实现(代码+数据库+LW)
  • 深入HBase——核心组件
  • 球队训练信息管理系统设计与实现(代码+数据库+LW)
  • 分布式事务三阶段协议
  • 【算法与数据结构】单调队列
  • 在PHP Web开发中,实现异步处理有几种常见方式的优缺点,以及最佳实践推荐方法
  • 嵌入式之条件编译
  • 基于数据可视化+SpringBoot+安卓端的数字化施工项目计划与管理平台设计和实现
  • 纠错检索增广生成论文
  • C++ 项目:Unsplash 爬虫与瀑布流实战
  • 运维Ansible面试题及参考答案
  • 分布式事务-本地消息表学习与落地方案
  • 蓝桥杯——按键
  • 神经形态视觉的实时动态避障系统:突破传统SLAM的响应延迟瓶颈
  • (一)趣学设计模式 之 单例模式!
  • 13th Labour of Heracles CodeForces - 1466D
  • 2025高维多目标优化:基于导航变量的多目标粒子群优化算法(NMOPSO)的无人机三维路径规划,MATLAB代码
  • CSS `transform` 属性详解:打造视觉效果与动画的利器
  • 51单片机学习之旅——定时器
  • go 日志框架
  • 中东睿评|胡塞武装已成为楔入中东各方力量之间的钉子户
  • 特朗普:对所有在国外制作进入美国的电影征收100%关税
  • 黎巴嫩9年来首次举行地方选举
  • 上千游客深夜滞留张家界大喊退票?当地通报情况并致歉
  • 海港通报颜骏凌伤停两至三周,国足面临门将伤病危机
  • 解放日报头版:上海张江模力社区托举“年轻的事业”