日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

VTK修炼之道78:交互与拾取_点拾取

發(fā)布時(shí)間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VTK修炼之道78:交互与拾取_点拾取 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.拾取

選擇拾取是人機(jī)交互過(guò)程的一個(gè)重要功能。 一個(gè)最經(jīng)典的例子就是,在玩3D游戲時(shí),場(chǎng)景中可能會(huì)存在多個(gè)角色,有時(shí)需要用鼠標(biāo)來(lái)選擇所要控制的角色,這就要用到拾取功能。 另外,在某些三維圖形的編輯軟件中,經(jīng)常需要編輯其中的一個(gè)點(diǎn)、一個(gè)面片或者一個(gè)局部區(qū)域,這也需要通過(guò)拾取功能來(lái)完成。 VTK中定義了多個(gè)拾取功能的類,具體的繼承關(guān)系如下:
VTK中所有的拾取類都繼承自vtkAbstractPicker類,在這些類的基礎(chǔ)之上可以實(shí)現(xiàn)非常復(fù)雜的功能。

2.點(diǎn)拾取

從上圖中能夠知曉,完成點(diǎn)拾取功能的類是vtkPointPicker。 vtk中的消息是通過(guò)vtkRenderWindowInteractor類處理的,在類vtkRenderWindowInteractor中,定義如下函數(shù): virtual void SetPicker(vtkAbstractPicker* ?); 該函數(shù)用來(lái)設(shè)置具體的VTKAbstractPicker對(duì)象,并執(zhí)行相應(yīng)的拾取操作。因此對(duì)于點(diǎn)拾取,實(shí)際就是設(shè)置VTKPointPicker的過(guò)程。 之前,曾經(jīng)細(xì)致的研究過(guò),vtkRenderWindowInteractor內(nèi)部定義了一個(gè)vtkInteractorStyle對(duì)象。vtkInteractorStyle類是一個(gè)虛基類,其子類定義了多種鼠標(biāo)和鍵盤消息的處理方法,在實(shí)現(xiàn)拾取操作是,需要定制相應(yīng)的鼠標(biāo)消息處理函數(shù)。比如拾取某個(gè)點(diǎn)時(shí),應(yīng)該響應(yīng)鼠標(biāo)的左鍵按下消息,并在響應(yīng)該消息的函數(shù)中根據(jù)鼠標(biāo)的當(dāng)前窗口坐標(biāo)來(lái)完成拾取操作。 點(diǎn)拾取的示例代碼如下: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL) VTK_MODULE_INIT(vtkRenderingFreeType) VTK_MODULE_INIT(vtkInteractionStyle)#include <vtkSmartPointer.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h>#include <vtkPointPicker.h> //this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer() #include <vtkRendererCollection.h> #include <vtkInteractorStyleTrackballCamera.h> #include <vtkObjectFactory.h> //vtkStandardNewMacro(); #include <vtkProperty.h>#include <vtkAxesActor.h> #include <vtkOrientationMarkerWidget.h> /**************************************************************************************************/ class PointPickerInteractorStyle : public vtkInteractorStyleTrackballCamera { public:static PointPickerInteractorStyle* New();vtkTypeMacro(PointPickerInteractorStyle, vtkInteractorStyleTrackballCamera);virtual void OnLeftButtonDown(){//打印鼠標(biāo)左鍵像素位置std::cout << "Picking pixel: " << this->Interactor->GetEventPosition()[0] << " " << this->Interactor->GetEventPosition()[1] << std::endl;//注冊(cè)拾取點(diǎn)函數(shù)this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],this->Interactor->GetEventPosition()[1], 0, // always zero.this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());//打印拾取點(diǎn)空間位置double picked[3];this->Interactor->GetPicker()->GetPickPosition(picked);std::cout << "Picked value: " << picked[0] << " " << picked[1] << " " << picked[2] << std::endl;//對(duì)拾取點(diǎn)進(jìn)行標(biāo)記vtkSmartPointer<vtkSphereSource> sphereSource =vtkSmartPointer<vtkSphereSource>::New();sphereSource->Update();vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(sphereSource->GetOutputPort());vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);actor->SetPosition(picked);actor->SetScale(0.05);actor->GetProperty()->SetColor(1.0, 0.0, 0.0);this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);vtkInteractorStyleTrackballCamera::OnLeftButtonDown();} }; /**************************************************************************************************/vtkStandardNewMacro(PointPickerInteractorStyle);int main() {vtkSmartPointer<vtkSphereSource> sphereSource =vtkSmartPointer<vtkSphereSource>::New();sphereSource->Update();vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(sphereSource->GetOutputPort());vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(actor);renderer->SetBackground(1, 1, 1);vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();renderWindow->Render();renderWindow->SetWindowName("PointPicker");renderWindow->AddRenderer(renderer);vtkSmartPointer<vtkPointPicker> pointPicker =vtkSmartPointer<vtkPointPicker>::New();vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();renderWindowInteractor->SetPicker(pointPicker);renderWindowInteractor->SetRenderWindow(renderWindow);vtkSmartPointer<PointPickerInteractorStyle> style =vtkSmartPointer<PointPickerInteractorStyle>::New();renderWindowInteractor->SetInteractorStyle(style);/vtkSmartPointer<vtkAxesActor> Axes = vtkSmartPointer<vtkAxesActor>::New();vtkSmartPointer<vtkOrientationMarkerWidget> widget =vtkSmartPointer<vtkOrientationMarkerWidget>::New();widget->SetInteractor(renderWindowInteractor);widget->SetOrientationMarker(Axes);widget->SetOutlineColor(1, 1, 1);widget->SetViewport(0, 0, 0.2, 0.2);widget->SetEnabled(1);widget->InteractiveOn();renderWindow->Render();renderWindowInteractor->Start();return 0; } 實(shí)際操作細(xì)節(jié)分析:
  • vtkInteractorStyleTrackballCemera派生類設(shè)計(jì)
PointPickerInteractorStyle類從vtkInteractorStyleTrackballCemera派生,并覆蓋了該類OnLeftButtonDown()函數(shù)。在該函數(shù)中,調(diào)用了vtkRenderWindowInteractor的GetEventPosition()函數(shù)輸出鼠標(biāo)點(diǎn)擊的屏幕坐標(biāo)。
  • 拾取函數(shù)Pick()設(shè)計(jì)
int Pick(double selectionX, double selectionY, double selectionZ, vtkRender* renderer); 該函數(shù)需要接受四個(gè)參數(shù),前三個(gè)為(selectionX,selectionY,selectionZ),即鼠標(biāo)的當(dāng)前窗口坐標(biāo),其中selectionZ通常為零。最后一個(gè)是vtkRenderer對(duì)象。
  • GetPackPosition()是指世界坐標(biāo)系下拾取點(diǎn)的坐標(biāo)
  • mian()函數(shù)中設(shè)計(jì)拾取調(diào)用流程
vtkSmartPointer<vtkPointPicker> pointPicker =vtkSmartPointer<vtkPointPicker>::New();vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetPicker(pointPicker); renderWindowInteractor->SetRenderWindow(renderWindow);vtkSmartPointer<PointPickerInteractorStyle> style =vtkSmartPointer<PointPickerInteractorStyle>::New(); renderWindowInteractor->SetInteractorStyle(style);實(shí)例化vtkPointPicker對(duì)象以后,調(diào)用vtkRenderWindowInteractor::SetPicker()函數(shù)將其設(shè)置到渲染窗口交互器中。PointPickerInteractorStyle類與vtkInteractorStyleImage等交互器樣式使用方法一致。

2.參看資料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開(kāi)發(fā)進(jìn)階[M]. 機(jī)械工業(yè)出版社, 2015.

總結(jié)

以上是生活随笔為你收集整理的VTK修炼之道78:交互与拾取_点拾取的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。