物流网个人网站建设保定网站建设方案优化
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);// ColorsvtkNew<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 spherevtkNew<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 conevtkNew<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函数作用及相机拉近拉远