一.需求

实现一个可移动,可旋转的三位坐标轴。

二,步骤

1.继承 vtkAbstractWidget。将鼠标事件传递给 vtkWidgetRepresentation。

2.继承 vtkWidgetRepresentation 。实现控件长什么样子,三个轴,三个圈。怎么交互,操纵轴,操纵圈该怎么动。

三,实现

1,绘制轴和圈

vtkMovableAxesRepresentation::vtkMovableAxesRepresentation()
{// The initial statethis->InteractionState = vtkMovableAxesRepresentation::Outside;// Handle size is in pixels for this widgetthis->HandleSize = 5.0;// Control orientation of normalsthis->InsideOut = 0;// Set up the initial propertiesthis->CreateDefaultProperties();// Define the point coordinatesdouble bounds[6];bounds[0] = -0.5;bounds[1] = 0.5;bounds[2] = -0.5;bounds[3] = 0.5;bounds[4] = -0.5;bounds[5] = 0.5;// Points 8-14 are down by PositionHandles();this->BoundingBox = vtkBox::New();this->PlaceWidget(bounds);//画 圆this->AxisCircel = new vtkActor* [3];this->AxisPolygonSource = new vtkRegularPolygonSource* [3];this->AxisCircleMapper = new vtkPolyDataMapper*[3];for(auto i=0;i<3;i++){this->AxisCircel[i]=vtkActor::New();this->AxisPolygonSource[i] = vtkRegularPolygonSource::New();this->AxisCircleMapper[i] = vtkPolyDataMapper::New();this->AxisPolygonSource[i]->SetNumberOfSides(100);    //多边形边数this->AxisPolygonSource[i]->SetRadius(g_circleRadius);       //半径this->AxisPolygonSource[i]->SetCenter(0, 0, 0);      //圆心this->AxisCircleMapper[i]->SetInputConnection(this->AxisPolygonSource[i]->GetOutputPort());this->AxisCircel[i]->SetMapper(this->AxisCircleMapper[i]);this->AxisCircel[i]->GetProperty()->SetOpacity(1);    //透明度this->AxisCircel[i]->GetProperty()->SetLineWidth(g_circleLineWidth);this->AxisCircel[i]->GetProperty()->SetRepresentationToWireframe();//图形不填充,只要边框this->AxisCircel[i]->GetProperty()->SetColor(g_normalColor[i][0],g_normalColor[i][1],g_normalColor[i][2]);    //颜色vtkNew<vtkMatrix4x4> initMatrix;this->AxisCircel[i]->SetUserMatrix(initMatrix);}//圆形拾取this->CircelPicker = vtkCellPicker::New();this->CircelPicker->SetTolerance(0.001);for(int i=0;i<3;i++){this->CircelPicker->AddPickList(this->AxisCircel[i]);}this->CircelPicker->PickFromListOn();this->CurrentCircel=nullptr;//轴this->HandleAxis = new vtkAssembly* [3];for (int i=0; i<3; i++){vtkNew<vtkLineSource> lineSource;vtkNew<vtkPolyDataMapper> lineMapper;vtkNew<vtkActor> lineActor;lineMapper->SetInputConnection(lineSource->GetOutputPort());lineActor->SetMapper(lineMapper);double point1[3];double point2[3];if(i==0){//x轴point1[0]=-g_axisLength;point1[1]=0;point1[2]=0;point2[0]=g_axisLength;point2[1]=0;point2[2]=0;}else if(i==1){//y轴point1[0]=0;point1[1]=-g_axisLength;point1[2]=0;point2[0]=0;point2[1]=g_axisLength;point2[2]=0;}else if(i==2){//z轴point1[0]=0;point1[1]=0;point1[2]=-g_axisLength;point2[0]=0;point2[1]=0;point2[2]=g_axisLength;}lineSource->SetPoint1(point1);lineSource->SetPoint2(point2);lineActor->GetProperty()->SetColor(g_normalColor[i][0],g_normalColor[i][1],g_normalColor[i][2]);lineActor->GetProperty()->SetLineWidth(g_axisLineWidth);//箭头vtkNew<vtkConeSource> coneSource1;vtkNew<vtkPolyDataMapper> coneMapper1;vtkNew<vtkActor> coneActor1;coneSource1->SetHeight( 0.2 );coneSource1->SetRadius( 0.04 );coneSource1->SetResolution( 10 );coneMapper1->SetInputConnection(coneSource1->GetOutputPort());coneActor1->SetMapper(coneMapper1);coneActor1->GetProperty()->SetColor(g_normalColor[i][0],g_normalColor[i][1],g_normalColor[i][2]);coneSource1->SetCenter(point2);if(i==0){//x轴}else if(i==1){//y轴coneActor1->SetOrigin(point2);coneActor1->RotateZ(90);}else if(i==2){//z轴coneActor1->SetOrigin(point2);coneActor1->RotateY(-90);}//vtkNew<vtkConeSource> coneSource2;vtkNew<vtkPolyDataMapper> coneMapper2;vtkNew<vtkActor> coneActor2;coneSource2->SetHeight( 0.2 );coneSource2->SetRadius( 0.04 );coneSource2->SetResolution( 30 );coneMapper2->SetInputConnection(coneSource2->GetOutputPort());coneActor2->SetMapper(coneMapper2);coneActor2->GetProperty()->SetColor(g_normalColor[i][0],g_normalColor[i][1],g_normalColor[i][2]);coneSource2->SetCenter(point1);if(i==0){//x轴coneActor2->SetOrigin(point1);coneActor2->RotateY(180);this->AxisPolygonSource[i]->SetNormal(1,0,0);}else if(i==1){//y轴coneActor2->SetOrigin(point1);coneActor2->RotateZ(-90);this->AxisPolygonSource[i]->SetNormal(0,1,0);}else if(i==2){//z轴coneActor2->SetOrigin(point1);coneActor2->RotateY(90);this->AxisPolygonSource[i]->SetNormal(0,0,1);}this->HandleAxis[i] = vtkAssembly::New();this->HandleAxis[i]->AddPart(lineActor);this->HandleAxis[i]->AddPart(coneActor1);this->HandleAxis[i]->AddPart(coneActor2);vtkNew<vtkMatrix4x4> initMatrix;this->HandleAxis[i]->SetUserMatrix(initMatrix);}//坐标轴拾取this->AxisPicker = vtkCellPicker::New();this->AxisPicker->SetTolerance(0.001);for (int i=0; i<3; i++){this->AxisPicker->AddPickList(this->HandleAxis[i]);}this->AxisPicker->PickFromListOn();//// Internal data members for performancethis->Transform = vtkTransform::New();this->PlanePoints = vtkPoints::New(VTK_DOUBLE);this->PlanePoints->SetNumberOfPoints(6);this->PlaneNormals = vtkDoubleArray::New();this->PlaneNormals->SetNumberOfComponents(3);this->PlaneNormals->SetNumberOfTuples(6);this->Matrix = vtkMatrix4x4::New();}

2,实现轴和圈的交互。以旋转为例。(感谢 此网友的分享 【VTK】可拖动的坐标轴MovableAxesWidget_Beyond欣的博客-CSDN博客)

void vtkMovableAxesRepresentation::Rotate(int X, int Y, double *p1, double *p2, double *vpn, int singleAxis)
{for(int i=0;i<3;i++){vtkMatrix4x4 *origin_matrixCircle = this->AxisCircel[i]->GetUserMatrix();vtkNew<vtkMatrix4x4> result_matrixCircle;RotateByMatrix(origin_matrixCircle,p1,p2,singleAxis,result_matrixCircle);this->AxisCircel[i]->SetUserMatrix(result_matrixCircle);vtkMatrix4x4 *origin_matrixAxis = this->HandleAxis[i]->GetUserMatrix();vtkNew<vtkMatrix4x4> result_matrixAxis;RotateByMatrix(origin_matrixAxis,p1,p2,singleAxis,result_matrixAxis);this->HandleAxis[i]->SetUserMatrix(result_matrixAxis);}this->Modified();this->BuildRepresentation();
}
void vtkMovableAxesRepresentation::RotateByMatrix(vtkMatrix4x4 *origin_matrix, double *p1, double *p2,int direction,vtkMatrix4x4* result_matrix)
{// 将鼠标位置移动到自身坐标系下,求两次鼠标位置向量在投影平面的夹角vtkNew<vtkTransform> trans;trans->SetMatrix(origin_matrix);double pos_t1[4] { p1[0], p1[1], p1[2], 1 };double pos_t2[4] { p2[0], p2[1], p2[2], 1 };vtkNew<vtkMatrix4x4> posture_inv;vtkMatrix4x4::Invert(origin_matrix, posture_inv);auto pos_t = posture_inv->MultiplyDoublePoint(pos_t1);double v1[3] = { pos_t[0], pos_t[1], pos_t[2] };pos_t = posture_inv->MultiplyDoublePoint(pos_t2);double v2[3] = { pos_t[0], pos_t[1], pos_t[2] };double normal[3];if(direction==0){normal[0] = 1;normal[1] = 0;normal[2] = 0;}else if(direction==1){normal[0] = 0;normal[1] = 1;normal[2] = 0;}else if(direction==2){normal[0] = 0;normal[1] = 0;normal[2] = 1;}double projection1[3], projection2[3];GetPlaneProjection(normal, v1, projection1);GetPlaneProjection(normal, v2, projection2);vtkMath::Normalize(projection1);vtkMath::Normalize(projection2);double axis[3];vtkMath::Cross(projection1, projection2, axis);double radians = acos(vtkMath::Dot(projection1, projection2));double degrees = vtkMath::DegreesFromRadians(radians);trans->RotateWXYZ(degrees, axis);result_matrix->DeepCopy(trans->GetMatrix());
}

VTK可移动三维坐标轴 vtkMovableAxesWidget相关推荐

  1. VTK可交互三维坐标轴

    因为实习工作需要制作一个如下图所示的可交互的三维坐标轴,制作这个坐标轴,首先需要创建一些三维图形,接着需要熟悉交互模块和鼠标进行交互,最后将它们封装成一个vtkWidget类 VTK中一些基础类介绍 ...

  2. 用几何画板怎么画三维坐标轴

    通过课本上的介绍,想必大家都知道了,三维笛卡儿坐标系是在二维笛卡儿坐标系的基础上根据右手定则增加第三维坐标(即Z轴)而形成的.那么要怎么画出三维坐标轴呢? 几何画板作为专业的绘图软件,可以用来画各种数 ...

  3. Matlab中如何创建空的三维坐标轴

    想必很多小伙伴经常会使用axes函数来创建二维的空坐标轴吧,可是对三维的空坐标轴却一筹莫展.创建二维的空坐标轴的代码如下所示: % Matlabfigure ax = axes('Position', ...

  4. python的三维坐标轴设置_使用PyOpenGL绘制三维坐标系实例

    我就废话不多说了,直接上代码吧! def drawCoordinate(): ''' 绘制三维的坐标系,并绘制由坐标轴构成的平面的网格,各个坐标轴的颜色以及由坐标轴所引出的网格线的颜色为: x: (1 ...

  5. 三维坐标轴html实现,CSS3三维变形,其实很简单!

    原标题:CSS3三维变形,其实很简单! 本文主要内容一.前言二.坐标轴系统三.透视与变形风格四.3D变形函数五.实例展示六.总结一.前言 所谓的三维变形,无外乎就是在二维平面的基础上进而实现三维立体空 ...

  6. python三维图形渲染-基于VTK/numpy的三维图像渲染与可视化

    我试图用numpy/vtk显示CT扫描获得的图像.为此,我遵循了这个sample code和{a2}的答案,但是我没有得到好的结果,也不知道原因.在 我检查了一下,我加载的数据是正确的,所以看起来我在 ...

  7. matlab的空间坐标轴,空间三维坐标轴旋转

    根据在网上找的公式编的程序,不知道对不对 %设在OXY坐标系中,原点不动,坐标轴旋转而得到一新坐标系OX'Y'Z': %OX'轴与OX,OY,OZ轴的正向夹角分别成:α1,  β1,  γ1角: %O ...

  8. python三维坐标轴单位长度_Matplotlib中三维散点图的z轴缩放和限制

    我对三个参数进行了蒙特卡罗反演,现在我试图用Matplotlib将它们绘制成三维图形.其中一个参数(Mo)的值在大约10^15到10^20之间变化,我对绘制从10^17到10^19变化的好解(蓝点)感 ...

  9. VTK For python 三维文件obj 体积计算

    1.安装python3 到官网下载 Download Python | Python.org 或者 http://链接:https://pan.baidu.com/s/1xGpH53Ia8MyZ3g7 ...

最新文章

  1. 边界填充算法讲解_边界填充算法
  2. 自定义MyHttpServletRequest解决过滤器拦截@RequestBody整体JSON请求问题
  3. ucos操作系统的内核有哪些调度方法
  4. go 怎么等待所有的协程完成_GO语言基础进阶教程:Go语言的协程——Goroutine
  5. 初始化mysql的数据库失败_初始化mysql的数据库失败怎么办
  6. Java连续获取两个输入,java 获取控制台的输入的两个方法
  7. 阿里云刘伟光:金融核心系统将步入分布式智能化的时代
  8. PCIE标准共享,以及其机械尺寸图
  9. 如何理解 Java 中的继承?
  10. 简单的Wifi网络概念
  11. HTML播放器快进不显示进度条,MediaSource播放视频,快进(直接点击进度条)的时候怎么知道range范围呢...
  12. 学生php实训个人总结300字,实训总结300字通用版5篇
  13. 怎么制作公司网页教程【网站制作】
  14. 多激光雷达外参标定算法与源码解析(一):基于BLAM的建图模块
  15. 三合一剪弦器怎么用_吉他换弦时多余的弦用什么工具剪掉?
  16. 信息安全竞赛解决方案
  17. android 序列化存储对象,android中对象序列化存储
  18. NLP进阶,Bert+BiLSTM情感分析实战
  19. 【Benewake(北醒) 】中距 TF02-Pro 40m介绍以及资料整理
  20. 【MySQL】-增删查改

热门文章

  1. centos7没有netstat命令的解决方法
  2. 微星小飞机没有osd显示怎么办?
  3. 【生信】使用QIIME进行 进化树,Alpha,Beta多样性 分析
  4. 计算机组成原理与体系结构——层次化存储结构
  5. ECharts Map 属性详解
  6. 鼎普计算机保密检查系统,敏感电子信息集中管控平台系统
  7. IPad GoodReader阅读文档实现即点即译取词在线翻译
  8. 找人接电话的常用套语
  9. C语言CRC校验码计算与校验
  10. SQL Server 2012 安装包