一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

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绘制网格的接口中没有实现绘制次刻度网格。若想绘制次刻度网格线,必须自己修改源码实现绘制次网格线的代码,修改源码显示次网格线的效果如下:

posted on 2020-11-26 14:36  一杯清酒邀明月  阅读(4278)  评论(0编辑  收藏  举报