5.1 3D坐标轴(vtkCubeAxesActor)
5.1.1 对象接口说明
SetXAxisLabelVisibility(vtkTypeBool) | 设置x、y、z轴刻度标签是否显示 |
SetXAxisTickVisibility(vtkTypeBool) | 设置x、y、z轴刻度是否显示 |
SetXAxisMinorTickVisibility(vtkTypeBool) | 设置x、y、z轴次刻度是否显示 |
SetDrawXGridlines(vtkTypeBool) | 设置是否绘制x、y、z轴的网格线 |
SetDrawXInnerGridlines(vtkTypeBool) | 设置是否绘制x、y、z轴的网格线的内部网格线 |
SetDrawXGridpolys(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 |
设置相机,以执行缩放。一般是将当前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//两侧 }; |
设置惯性因子,该惯性因子控制轴切换位置的频率(从一个轴跳到另一个轴),范围为1到VTK_INT_MAX。默认值是1 | |
指定一个偏移量值,以便从轴连接的角“拉回”轴,以避免轴标签重叠。默认值是0 | |
SetXAxisVisibility(vtkTypeBool) | 设置x、y、z轴的显示状态。 |
指定网格线呈现的样式 enum GridVisibility { VTK_GRID_LINES_ALL = 0,//呈现所有网格线 VTK_GRID_LINES_CLOSEST = 1,//呈现最近的三个轴的网格线 VTK_GRID_LINES_FURTHEST = 2//呈现最远的三个轴的网格线 }; |
5.1.2 代码实现
void ESAxes::create()
{
m_cubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
m_cubeAxesActor->SetCamera(m_pRender->GetActiveCamera());
//
//轴的设置
//设置x、y、z轴的起始和终止值
m_cubeAxesActor->SetXAxisRange(0, 200000);
m_cubeAxesActor->SetYAxisRange(0, 200000);
m_cubeAxesActor->SetZAxisRange(0, 200000);
//设置坐标轴线的宽度
m_cubeAxesActor->GetXAxesLinesProperty()->SetLineWidth(0.5);
m_cubeAxesActor->GetYAxesLinesProperty()->SetLineWidth(0.5);
m_cubeAxesActor->GetZAxesLinesProperty()->SetLineWidth(0.5);
//设置标题和标签文本的屏幕大小。默认值为10.0。
m_cubeAxesActor->SetScreenSize(6);
//指定标签与轴之间的距离。默认值为20.0。
m_cubeAxesActor->SetLabelOffset(5);
//显示坐标轴
m_cubeAxesActor->SetVisibility(true);
//指定一种模式来控制轴的绘制方式
m_cubeAxesActor->SetFlyMode(0);
//设置惯性因子,该惯性因子控制轴切换位置的频率(从一个轴跳到另一个轴)
//m_cubeAxesActor->SetInertia(1);
//
//网格设置
//开启x、y、z轴的网格线绘制
m_cubeAxesActor->DrawXGridlinesOn();
m_cubeAxesActor->DrawYGridlinesOn();
m_cubeAxesActor->DrawZGridlinesOn();
//设置x、y、z轴的内部网格线不绘制
m_cubeAxesActor->SetDrawXInnerGridlines(false);
m_cubeAxesActor->SetDrawYInnerGridlines(false);
m_cubeAxesActor->SetDrawZInnerGridlines(false);
//设置x、y、z轴网格线的颜色
m_cubeAxesActor->GetXAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
m_cubeAxesActor->GetYAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
m_cubeAxesActor->GetZAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
//指定网格线呈现的样式
m_cubeAxesActor->SetGridLineLocation(2);
//
//刻度的设置
//不显示x、y、z轴的次刻度
m_cubeAxesActor->XAxisMinorTickVisibilityOff();
m_cubeAxesActor->YAxisMinorTickVisibilityOff();
m_cubeAxesActor->ZAxisMinorTickVisibilityOff();
//设置刻度标签的显示方式(参数1为false,刻度标签按0-200000显示;为true时,按0-200显示)
m_cubeAxesActor->SetLabelScaling(false, 0, 0, 0);
//设置刻度线显示的位置(内部、外部、两侧)
m_cubeAxesActor->SetTickLocation(1);
//
m_pRender->AddActor(m_cubeAxesActor);
m_pRender->ResetCamera();
m_pRender->ResetCameraClippingRange();
m_pRenderWnd->Render();
}
5.1.3 扩展
5.1.3.1 显示问题-刻度与网格线分离
如下图:
较好的显示效果应该为:1处有网格线,2和3处有刻度标注。
出现该问题的原因:
(1)首先,vtkCubeAxesActor对象的构造函数中是分别为x、y、z三个方向都创建了4个vtkAxisActor对象,代码如下:
vtkCubeAxesActor::vtkCubeAxesActor() : vtkActor()
{
。。。
for (int i = 0; i < NUMBER_OF_ALIGNED_AXIS; i++)
{
this->XAxes[i] = vtkAxisActor::New();
this->XAxes[i]->SetTickVisibility(1);
this->XAxes[i]->SetMinorTicksVisible(1);
this->XAxes[i]->SetLabelVisibility(1);
this->XAxes[i]->SetTitleVisibility(1);
this->XAxes[i]->SetAxisTypeToX();
。。。
this->YAxes[i] = vtkAxisActor::New();
this->YAxes[i]->SetTickVisibility(1);
this->YAxes[i]->SetMinorTicksVisible(1);
this->YAxes[i]->SetLabelVisibility(1);
this->YAxes[i]->SetTitleVisibility(1);
this->YAxes[i]->SetAxisTypeToY();
this->YAxes[i]->SetAxisPosition(i);
this->YAxes[i]->SetAxisLinesProperty(this->YAxesLinesProperty);
this->YAxes[i]->SetGridlinesProperty(this->YAxesGridlinesProperty);
this->YAxes[i]->SetInnerGridlinesProperty(this->YAxesInnerGridlinesProperty);
。。。
this->ZAxes[i] = vtkAxisActor::New();
this->ZAxes[i]->SetTickVisibility(1);
this->ZAxes[i]->SetMinorTicksVisible(1);
this->ZAxes[i]->SetLabelVisibility(1);
this->ZAxes[i]->SetTitleVisibility(1);
this->ZAxes[i]->SetAxisTypeToZ();
。。。
。。。
。。。
}
NUMBER_OF_ALIGNED_AXIS = 4。
而针对指定网格线呈现的样式为VTK_GRID_LINES_FURTHEST时,x、y、z方向的都各只有一个vtkAxisActor会画网格线且不呈现刻度标注,代码如下:
void vtkCubeAxesActor::UpdateGridLineVisibility(int idx)
{
if( this->GridLineLocation != VTK_GRID_LINES_ALL &&
(this->DrawXGridlines || this->DrawYGridlines || this->DrawZGridlines) )
{
for(int i=0; i < NUMBER_OF_ALIGNED_AXIS; ++i)
{
this->XAxes[i]->SetDrawGridlines(0);
this->YAxes[i]->SetDrawGridlines(0);
this->ZAxes[i]->SetDrawGridlines(0);
this->XAxes[i]->SetDrawGridlinesOnly(0);
this->YAxes[i]->SetDrawGridlinesOnly(0);
this->ZAxes[i]->SetDrawGridlinesOnly(0);
}
int xId = vtkCubeAxesActorTriads[idx][0];
int yId = vtkCubeAxesActorTriads[idx][1];
int zId = vtkCubeAxesActorTriads[idx][2];
this->XAxes[xId]->SetDrawGridlines(this->DrawXGridlines);
this->YAxes[yId]->SetDrawGridlines(this->DrawYGridlines);
this->ZAxes[zId]->SetDrawGridlines(this->DrawZGridlines);
// Update axis render list
int id = 0;
if(this->NumberOfAxesX == 1)
{
id = this->RenderAxesX[this->NumberOfAxesX] = vtkCubeAxesActorTriads[idx][0];
this->XAxes[id]->SetDrawGridlinesOnly((this->RenderAxesX[0] != id) ? 1 : 0);
this->NumberOfAxesX += (this->RenderAxesX[0] != id) ? 1 : 0;
}
if(this->NumberOfAxesY == 1)
{
id = this->RenderAxesY[this->NumberOfAxesY] = vtkCubeAxesActorTriads[idx][1];
this->YAxes[id]->SetDrawGridlinesOnly((this->RenderAxesY[0] != id) ? 1 : 0);
this->NumberOfAxesY += (this->RenderAxesY[0] != id) ? 1 : 0;
}
if(this->NumberOfAxesZ == 1)
{
id = this->RenderAxesZ[this->NumberOfAxesZ] = vtkCubeAxesActorTriads[idx][2];
this->ZAxes[id]->SetDrawGridlinesOnly((this->RenderAxesZ[0] != id) ? 1 : 0);
this->NumberOfAxesZ += (this->RenderAxesZ[0] != id) ? 1 : 0;
}
}
}
网格线是由图中箭头所指的vtkAxisActor对象绘制出来的,我们可以从vtkAxisActor绘制网格线的代码中看到:
void vtkAxisActor::BuildAxisGridLines(
double p1[3], double p2[3], double localCoordSys[3][3])
{
。。。
// - Insert Gridlines points along the axis using the DeltaMajor vector
double nbIterationAsDouble = (axisLength - axisShift) / vtkMath::Norm(deltaVector);
int nbIteration = vtkMath::Floor(nbIterationAsDouble + 2 * FLT_EPSILON) + 1;
nbIteration = (nbIteration < VTK_MAX_TICKS) ? nbIteration : VTK_MAX_TICKS;
for (int nbTicks = 0; nbTicks < nbIteration; nbTicks++)
{
// Closest U
this->GridlinePts->InsertNextPoint(gridPointClosest);
this->GridlinePts->InsertNextPoint(gridPointU);
// Farest U
this->GridlinePts->InsertNextPoint(gridPointFarest);
this->GridlinePts->InsertNextPoint(gridPointU);
// Closest V
this->GridlinePts->InsertNextPoint(gridPointClosest);
this->GridlinePts->InsertNextPoint(gridPointV);
// Farest V
this->GridlinePts->InsertNextPoint(gridPointFarest);
this->GridlinePts->InsertNextPoint(gridPointV);
// PolyPoints
this->GridpolyPts->InsertNextPoint(gridPointClosest);
this->GridpolyPts->InsertNextPoint(gridPointU);
this->GridpolyPts->InsertNextPoint(gridPointFarest);
this->GridpolyPts->InsertNextPoint(gridPointV);
。。。
}
。。。
}
5.1.3.2 显示问题-次刻度的网格没有绘制
次刻度的网格之所以没有绘制,是因为在vtkAxisActor绘制网格的接口中没有实现绘制次刻度网格。若想绘制次刻度网格线,必须自己修改源码实现绘制次网格线的代码,修改源码显示次网格线的效果如下: