• VTK 对象绘制 3D坐标轴(vtkCubeAxesActor)


    5.1 3D坐标轴(vtkCubeAxesActor)

    5.1.1 对象接口说明

    SetXAxisLabelVisibility(vtkTypeBool)

    SetYAxisLabelVisibility(vtkTypeBool)

    SetZAxisLabelVisibility(vtkTypeBool)

    设置x、y、z轴刻度标签是否显示

    SetXAxisTickVisibility(vtkTypeBool)

    SetYAxisTickVisibility(vtkTypeBool)

    SetZAxisTickVisibility(vtkTypeBool)

    设置x、y、z轴刻度是否显示

    SetXAxisMinorTickVisibility(vtkTypeBool)

    SetYAxisMinorTickVisibility(vtkTypeBool)

    SetZAxisMinorTickVisibility(vtkTypeBool)

    设置x、y、z轴次刻度是否显示

    SetDrawXGridlines(vtkTypeBool)

    SetDrawYGridlines(vtkTypeBool)

    SetDrawZGridlines(vtkTypeBool)

    设置是否绘制x、y、z轴的网格线

    SetDrawXInnerGridlines(vtkTypeBool)

    SetDrawYInnerGridlines(vtkTypeBool)

    SetDrawZInnerGridlines(vtkTypeBool)

    设置是否绘制x、y、z轴的网格线的内部网格线

    SetDrawXGridpolys(vtkTypeBool)

    SetDrawYGridpolys(vtkTypeBool)

    SetDrawZGridpolys(vtkTypeBool)

    设置是否绘制x、y、z轴的网格线的内部网格面

    SetLabelScaling(bool,int,int,int)

    设置刻度标签的显示样式,假设坐标轴的值范围为0-200000,当参数1为false时,刻度标签按0-200000显示;参数1为true时,按0-200显示

    SetXAxisRange(double,double)

    SetYAxisRange(double,double)

    SetZAxisRange(double,double)

    设置x、y、z轴值的范围

    SetScreenSize (double screenSize)

    设置标题和标签文本的屏幕大小。默认值为10.0。

    SetLabelOffset (double offset)

    指定标签与轴之间的距离。默认值为20.0。

    SetTitleOffset(double)

    设置标题和刻度标签之间的距离。默认为20.0

    SetCamera(vtkCamera *)

    设置相机,以执行缩放。一般是将当前render的相机设置给坐标轴。

    SetFlyMode(int)

    指定一种模式来控制轴的绘制方式

    enum FlyMode

    {

    VTK_FLY_OUTER_EDGES = 0,//外边缘

    VTK_FLY_CLOSEST_TRIAD = 1,//最近位置

    VTK_FLY_FURTHEST_TRIAD = 2,//最远位置

    VTK_FLY_STATIC_TRIAD = 3,//静态最近位置,不随摄像头动而跳变位置。

    VTK_FLY_STATIC_EDGES = 4 //静态所有外边缘位置,不随摄像头动而跳变位置。

    };

    SetXTitle (const char *)

    SetYTitle (const char *)

    SetZTitle (const char *)

    设置x、y、z轴的标题

    SetTickLocation

    设置刻度线显示的位置

    enum TickLocation

    {

    VTK_TICKS_INSIDE = 0,//内部

    VTK_TICKS_OUTSIDE = 1,//外部

    VTK_TICKS_BOTH = 2//两侧

    };

    SetInertia (int)

    设置惯性因子,该惯性因子控制轴切换位置的频率(从一个轴跳到另一个轴),范围为1到VTK_INT_MAX。默认值是1

    SetCornerOffset (double)

    指定一个偏移量值,以便从轴连接的角“拉回”轴,以避免轴标签重叠。默认值是0

    SetXAxisVisibility(vtkTypeBool)

    SetYAxisVisibility(vtkTypeBool)

    SetZAxisVisibility(vtkTypeBool)

    设置x、y、z轴的显示状态。

    SetGridLineLocation

    指定网格线呈现的样式

    enum GridVisibility

    {

    VTK_GRID_LINES_ALL = 0,//呈现所有网格线

    VTK_GRID_LINES_CLOSEST = 1,//呈现最近的三个轴的网格线

    VTK_GRID_LINES_FURTHEST =  2//呈现最远的三个轴的网格线

    };

    5.1.2 代码实现

     1 void ESAxes::create()
     2 {
     3     m_cubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
     4     m_cubeAxesActor->SetCamera(m_pRender->GetActiveCamera());
     5     //
     6     //轴的设置
     7     //设置x、y、z轴的起始和终止值
     8     m_cubeAxesActor->SetXAxisRange(0, 200000);
     9     m_cubeAxesActor->SetYAxisRange(0, 200000);
    10     m_cubeAxesActor->SetZAxisRange(0, 200000);
    11     //设置坐标轴线的宽度
    12     m_cubeAxesActor->GetXAxesLinesProperty()->SetLineWidth(0.5);
    13     m_cubeAxesActor->GetYAxesLinesProperty()->SetLineWidth(0.5);
    14     m_cubeAxesActor->GetZAxesLinesProperty()->SetLineWidth(0.5);
    15     //设置标题和标签文本的屏幕大小。默认值为10.0。
    16     m_cubeAxesActor->SetScreenSize(6);
    17     //指定标签与轴之间的距离。默认值为20.0。
    18     m_cubeAxesActor->SetLabelOffset(5);
    19     //显示坐标轴
    20     m_cubeAxesActor->SetVisibility(true);
    21     //指定一种模式来控制轴的绘制方式
    22     m_cubeAxesActor->SetFlyMode(0);
    23     //设置惯性因子,该惯性因子控制轴切换位置的频率(从一个轴跳到另一个轴)
    24     //m_cubeAxesActor->SetInertia(1);
    25     //
    26     //网格设置
    27     //开启x、y、z轴的网格线绘制
    28     m_cubeAxesActor->DrawXGridlinesOn();
    29     m_cubeAxesActor->DrawYGridlinesOn();
    30     m_cubeAxesActor->DrawZGridlinesOn();
    31     //设置x、y、z轴的内部网格线不绘制
    32     m_cubeAxesActor->SetDrawXInnerGridlines(false);
    33     m_cubeAxesActor->SetDrawYInnerGridlines(false);
    34     m_cubeAxesActor->SetDrawZInnerGridlines(false);
    35     //设置x、y、z轴网格线的颜色
    36     m_cubeAxesActor->GetXAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
    37     m_cubeAxesActor->GetYAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
    38     m_cubeAxesActor->GetZAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
    39     //指定网格线呈现的样式
    40     m_cubeAxesActor->SetGridLineLocation(2);
    41     //
    42     //刻度的设置
    43     //不显示x、y、z轴的次刻度
    44     m_cubeAxesActor->XAxisMinorTickVisibilityOff();
    45     m_cubeAxesActor->YAxisMinorTickVisibilityOff();
    46     m_cubeAxesActor->ZAxisMinorTickVisibilityOff();
    47     //设置刻度标签的显示方式(参数1为false,刻度标签按0-200000显示;为true时,按0-200显示)
    48     m_cubeAxesActor->SetLabelScaling(false, 0, 0, 0);
    49     //设置刻度线显示的位置(内部、外部、两侧)
    50     m_cubeAxesActor->SetTickLocation(1);
    51     //
    52     m_pRender->AddActor(m_cubeAxesActor);
    53     m_pRender->ResetCamera();
    54     m_pRender->ResetCameraClippingRange();
    55     m_pRenderWnd->Render();
    56 }

    5.1.3 扩展

    5.1.3.1 显示问题-刻度与网格线分离

    如下图:

    较好的显示效果应该为:1处有网格线,2和3处有刻度标注。

    出现该问题的原因:

    (1)首先,vtkCubeAxesActor对象的构造函数中是分别为x、y、z三个方向都创建了4个vtkAxisActor对象,代码如下:

     1 vtkCubeAxesActor::vtkCubeAxesActor() : vtkActor()
     2 {
     3 。。。
     4   for (int i = 0; i < NUMBER_OF_ALIGNED_AXIS; i++)
     5   {
     6     this->XAxes[i] = vtkAxisActor::New();
     7     this->XAxes[i]->SetTickVisibility(1);
     8     this->XAxes[i]->SetMinorTicksVisible(1);
     9     this->XAxes[i]->SetLabelVisibility(1);
    10     this->XAxes[i]->SetTitleVisibility(1);
    11     this->XAxes[i]->SetAxisTypeToX();
    12 。。。
    13  
    14     this->YAxes[i] = vtkAxisActor::New();
    15     this->YAxes[i]->SetTickVisibility(1);
    16     this->YAxes[i]->SetMinorTicksVisible(1);
    17     this->YAxes[i]->SetLabelVisibility(1);
    18     this->YAxes[i]->SetTitleVisibility(1);
    19     this->YAxes[i]->SetAxisTypeToY();
    20     this->YAxes[i]->SetAxisPosition(i);
    21     this->YAxes[i]->SetAxisLinesProperty(this->YAxesLinesProperty);
    22     this->YAxes[i]->SetGridlinesProperty(this->YAxesGridlinesProperty);
    23     this->YAxes[i]->SetInnerGridlinesProperty(this->YAxesInnerGridlinesProperty);
    24 。。。
    25  
    26     this->ZAxes[i] = vtkAxisActor::New();
    27     this->ZAxes[i]->SetTickVisibility(1);
    28     this->ZAxes[i]->SetMinorTicksVisible(1);
    29     this->ZAxes[i]->SetLabelVisibility(1);
    30     this->ZAxes[i]->SetTitleVisibility(1);
    31     this->ZAxes[i]->SetAxisTypeToZ();
    32        。。。
    33 。。。
    34 。。。
    35 }

    NUMBER_OF_ALIGNED_AXIS = 4。

    而针对指定网格线呈现的样式为VTK_GRID_LINES_FURTHEST时,x、y、z方向的都各只有一个vtkAxisActor会画网格线且不呈现刻度标注,代码如下:

     1 void vtkCubeAxesActor::UpdateGridLineVisibility(int idx)
     2 {
     3   if( this->GridLineLocation != VTK_GRID_LINES_ALL &&
     4       (this->DrawXGridlines || this->DrawYGridlines || this->DrawZGridlines) )
     5   {
     6     for(int i=0; i < NUMBER_OF_ALIGNED_AXIS; ++i)
     7     {
     8       this->XAxes[i]->SetDrawGridlines(0);
     9       this->YAxes[i]->SetDrawGridlines(0);
    10       this->ZAxes[i]->SetDrawGridlines(0);
    11       this->XAxes[i]->SetDrawGridlinesOnly(0);
    12       this->YAxes[i]->SetDrawGridlinesOnly(0);
    13       this->ZAxes[i]->SetDrawGridlinesOnly(0);
    14     }
    15     int xId = vtkCubeAxesActorTriads[idx][0];
    16     int yId = vtkCubeAxesActorTriads[idx][1];
    17     int zId = vtkCubeAxesActorTriads[idx][2];
    18     this->XAxes[xId]->SetDrawGridlines(this->DrawXGridlines);
    19     this->YAxes[yId]->SetDrawGridlines(this->DrawYGridlines);
    20     this->ZAxes[zId]->SetDrawGridlines(this->DrawZGridlines);
    21     // Update axis render list
    22     int id = 0;
    23     if(this->NumberOfAxesX == 1)
    24     {
    25       id = this->RenderAxesX[this->NumberOfAxesX] = vtkCubeAxesActorTriads[idx][0];
    26       this->XAxes[id]->SetDrawGridlinesOnly((this->RenderAxesX[0] != id) ? 1 : 0);
    27       this->NumberOfAxesX += (this->RenderAxesX[0] != id) ? 1 : 0;
    28     }
    29     if(this->NumberOfAxesY == 1)
    30     {
    31       id = this->RenderAxesY[this->NumberOfAxesY] = vtkCubeAxesActorTriads[idx][1];
    32       this->YAxes[id]->SetDrawGridlinesOnly((this->RenderAxesY[0] != id) ? 1 : 0);
    33       this->NumberOfAxesY += (this->RenderAxesY[0] != id) ? 1 : 0;
    34     }
    35     if(this->NumberOfAxesZ == 1)
    36     {
    37       id = this->RenderAxesZ[this->NumberOfAxesZ] = vtkCubeAxesActorTriads[idx][2];
    38       this->ZAxes[id]->SetDrawGridlinesOnly((this->RenderAxesZ[0] != id) ? 1 : 0);
    39       this->NumberOfAxesZ += (this->RenderAxesZ[0] != id) ? 1 : 0;
    40     }
    41   }
    42 }

    网格线是由图中箭头所指的vtkAxisActor对象绘制出来的,我们可以从vtkAxisActor绘制网格线的代码中看到:

     1 void vtkAxisActor::BuildAxisGridLines(
     2 double p1[3], double p2[3], double localCoordSys[3][3])
     3 {
     4 。。。
     5   // - Insert Gridlines points along the axis using the DeltaMajor vector
     6   double nbIterationAsDouble = (axisLength - axisShift) / vtkMath::Norm(deltaVector);
     7   int nbIteration = vtkMath::Floor(nbIterationAsDouble + 2 * FLT_EPSILON) + 1;
     8   nbIteration = (nbIteration < VTK_MAX_TICKS) ? nbIteration : VTK_MAX_TICKS;
     9   for (int nbTicks = 0; nbTicks < nbIteration; nbTicks++)
    10   {
    11     // Closest U
    12     this->GridlinePts->InsertNextPoint(gridPointClosest);
    13     this->GridlinePts->InsertNextPoint(gridPointU);
    14     // Farest U
    15     this->GridlinePts->InsertNextPoint(gridPointFarest);
    16     this->GridlinePts->InsertNextPoint(gridPointU);
    17     // Closest V
    18     this->GridlinePts->InsertNextPoint(gridPointClosest);
    19     this->GridlinePts->InsertNextPoint(gridPointV);
    20     // Farest V
    21     this->GridlinePts->InsertNextPoint(gridPointFarest);
    22     this->GridlinePts->InsertNextPoint(gridPointV);
    23     // PolyPoints
    24     this->GridpolyPts->InsertNextPoint(gridPointClosest);
    25     this->GridpolyPts->InsertNextPoint(gridPointU);
    26     this->GridpolyPts->InsertNextPoint(gridPointFarest);
    27 this->GridpolyPts->InsertNextPoint(gridPointV);
    28 。。。
    29 }
    30 。。。
    31 }

    5.1.3.2 显示问题-次刻度的网格没有绘制

    次刻度的网格之所以没有绘制,是因为在vtkAxisActor绘制网格的接口中没有实现绘制次刻度网格。若想绘制次刻度网格线,必须自己修改源码实现绘制次网格线的代码,修改源码显示次网格线的效果如下:

  • 相关阅读:
    Eclipse中Outline里各种图标的含义
    synchronized
    instanceof
    java代码实现rabbitMQ请求
    ftp服务的搭建及调用
    WebService学习总结(三)——使用JDK开发WebService
    Java Web Service 学习
    通俗理解阻塞、非阻塞,同步、异步。
    mongo VUE 操作
    【清华集训2014】主旋律
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14042172.html
Copyright © 2020-2023  润新知