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

                
            
        
浙公网安备 33010602011771号