VTK_Learning_交互与拾取_点拾取
1.拾取
选择拾取是人机交互过程的一个重要功能。
一个最经典的例子就是,在玩3D游戏时,场景中可能会存在多个角色,有时需要用鼠标来选择所要控制的角色,这就要用到拾取功能。
另外,在某些三维图形的编辑软件中,经常需要编辑其中的一个点、一个面片或者一个局部区域,这也需要通过拾取功能来完成。
VTK中定义了多个拾取功能的类,具体的继承关系如下:VTK中所有的拾取类都继承自vtkAbstractPicker类,在这些类的基础之上可以实现非常复杂的功能。
2.点拾取
从上图中能够知晓,完成点拾取功能的类是vtkPointPicker。
vtk中的消息是通过vtkRenderWindowInteractor类处理的,在类vtkRenderWindowInteractor中,定义如下函数:
virtual void SetPicker(vtkAbstractPicker* );
该函数用来设置具体的VTKAbstractPicker对象,并执行相应的拾取操作。因此对于点拾取,实际就是设置VTKPointPicker的过程。
之前,曾经细致的研究过,vtkRenderWindowInteractor内部定义了一个vtkInteractorStyle对象。vtkInteractorStyle类是一个虚基类,其子类定义了多种鼠标和键盘消息的处理方法,在实现拾取操作是,需要定制相应的鼠标消息处理函数。比如拾取某个点时,应该响应鼠标的左键按下消息,并在响应该消息的函数中根据鼠标的当前窗口坐标来完成拾取操作。
点拾取的示例代码如下:#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(){//打印鼠标左键像素位置std::cout << "Picking pixel: " << this->Interactor->GetEventPosition()[0] << " " << this->Interactor->GetEventPosition()[1] << std::endl;//注册拾取点函数this->Interactor->GetPicker()->Pick(this->Interactor->GetEventPosition()[0],this->Interactor->GetEventPosition()[1], 0, // always zero.this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());//打印拾取点空间位置double picked[3];this->Interactor->GetPicker()->GetPickPosition(picked);std::cout << "Picked value: " << picked[0] << " " << picked[1] << " " << picked[2] << std::endl;//对拾取点进行标记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; }
实际操作细节分析:
- vtkInteractorStyleTrackballCemera派生类设计
PointPickerInteractorStyle类从vtkInteractorStyleTrackballCemera派生,并覆盖了该类OnLeftButtonDown()函数。在该函数中,调用了vtkRenderWindowInteractor的GetEventPosition()函数输出鼠标点击的屏幕坐标。
- 拾取函数Pick()设计
int Pick(double selectionX, double selectionY, double selectionZ, vtkRender* renderer);
该函数需要接受四个参数,前三个为(selectionX,selectionY,selectionZ),即鼠标的当前窗口坐标,其中selectionZ通常为零。最后一个是vtkRenderer对象。
- GetPackPosition()是指世界坐标系下拾取点的坐标
- mian()函数中设计拾取调用流程
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);
实例化vtkPointPicker对象以后,调用vtkRenderWindowInteractor::SetPicker()函数将其设置到渲染窗口交互器中。PointPickerInteractorStyle类与vtkInteractorStyleImage等交互器样式使用方法一致。
VTK_Learning_交互与拾取_点拾取相关推荐
- VTK_Learning_交互与拾取_单位拾取
1.单位拾取 示例代码: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL) VTK_MODULE_INIT(vtkI ...
- VTK修炼之道79:交互与拾取_单位拾取
1.单位拾取 示例代码: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL) VTK_MODULE_INIT(vtkI ...
- VTK修炼之道78:交互与拾取_点拾取
1.拾取 选择拾取是人机交互过程的一个重要功能. 一个最经典的例子就是,在玩3D游戏时,场景中可能会存在多个角色,有时需要用鼠标来选择所要控制的角色,这就要用到拾取功能. 另外,在某些三维图形的编辑软 ...
- vue3.x +Cesium Cesium 鼠标交互,鼠标点击拾取对象等(五)
cesium地图上鼠标点击事件 1.创建屏幕控制实例 var handlClick = new Cesium.ScreenSpaceEventHandler(window.viewer.canvas) ...
- 交互设计精髓_设计空间的精髓
交互设计精髓 重点 (Top highlight) 什么是空间? (What is Space?) Space is the dimension of height, depth and width ...
- 鼠标拾取(光线拾取)
作者:桑榆 QQ:934440653 有问题,评论留言,或qq联系 案例效果 鼠标拾取 主要代码 1.创建矩形 (1)6-8行限制随机产生的矩形的长.宽.纵深不超过20: (2)14-16行限制随机产 ...
- python打开交互界面设计_老司机必备——用PyQt做一个有交互界面的妹子图爬虫...
内容简介:老司机必备--用PyQt做一个有交互界面的妹子图爬虫 代码飙车,指日可待.今天的课程教大家结合PyQt和 Python 爬虫技术,做一个带有交互界面的妹子图网站爬虫程序. 一.实验简介 1. ...
- python交互界面制作_Python 如何编写交互界面?_后端开发
c语言怎么实现三个数从小到大输出?_后端开发 方法:1.使用if语句对数字x与y进行比较,若x>y则交换x和y的值:2.使用if对x与z进行比较,若x>z则交换x和z的值:3.使用if对y ...
- python图表交互控件_用djang中的交互式控件制作bokeh图表
有两个用例: 没有服务器 如果您可以在JS中执行任何更新(不需要调用实际的python代码),那么使用CustomJS callbacks添加交互非常容易.在这个链接中有很多示例,但是一个基本的简单代 ...
最新文章
- FPGA基础知识极简教程(8)详解三态缓冲器
- 解锁bios学习总结
- 给老婆普及计算机知识
- concat函数_三、P57-61 MySQL中常用函数
- 生成路径 vs 设置_Simulink代码生成之模型配置
- Tail Recursion尾递归
- C++工作笔记-WM_KEYFIRST和WM_KEYDOWN的用法
- 操作系统之内存管理:6、页面分配策略、抖动、工作集
- 基本值类型(一):序数类型与运算符
- 【LeetCode】24. Swap Nodes in Pairs
- NIPS不改名再引风波:签名抗议活动开启,大咖纷纷发声支持
- 《Python语言程序设计》——1.3 程序设计语言
- 普林斯顿大学计算机系,普林斯顿大学计算机科学系
- 论文精读:《电子政务的服务质量、感知价值与公民持续使用意愿——来自中国的实证经验》
- lopatkin俄大神精简中文系统Windows 7 Enterprise SP1 7601.23934 x86-x64 ZH-CN PIP
- Android PreferenceScreen的使用和详解(设置页面)
- 【车辆分类】基于matlab的视频中车辆跟踪监测分类算法仿真,包括背景差分与帧间差分以及形态学处理
- php 调用redis中lpush的方法
- 计算的威力,智慧的传奇——Fabrice Bellard
- c语言数组转换树存储结构,c语言, 一棵具有n个结点的完全二叉树以数组存储,试写一个非递归 算法实现对 该树的前序遍历。...