第04章 17 实现一个逐步收缩球体的视觉效果
结合vtkSphereSource
、vtkShrinkFilter
和vtkElevationFilter
,我们可以实现一个逐步收缩球体的视觉效果,并在球体表面应用高程映射(Elevation Mapping)。vtkElevationFilter
用于根据球体的某个方向(如Z轴)生成颜色或标量值,使球体表面呈现出从低到高的渐变效果。
下面是一个示例代码,展示了如何逐次缩小球体并应用高程映射。
示例代码
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkShrinkFilter.h>
#include <vtkElevationFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char *[])
{
// 创建球体源
vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetRadius(1.0); // 球体半径
sphereSource->SetThetaResolution(30); // 经度方向的细分
sphereSource->SetPhiResolution(30); // 纬度方向的细分
sphereSource->Update();
// 创建收缩滤波器
vtkSmartPointer<vtkShrinkFilter> shrinkFilter = vtkSmartPointer<vtkShrinkFilter>::New();
shrinkFilter->SetInputConnection(sphereSource->GetOutputPort());
shrinkFilter->SetShrinkFactor(0.7); // 设置收缩因子为0.7
shrinkFilter->Update();
// 创建高程滤波器
vtkSmartPointer<vtkElevationFilter> elevationFilter = vtkSmartPointer<vtkElevationFilter>::New();
elevationFilter->SetInputConnection(shrinkFilter->GetOutputPort());
elevationFilter->SetLowPoint(0.0, 0.0, -1.0); // 低点的坐标
elevationFilter->SetHighPoint(0.0, 0.0, 1.0); // 高点的坐标
elevationFilter->SetScalarRange(-1.0, 1.0); // 标量范围
elevationFilter->Update();
// 创建Mapper和Actor
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(elevationFilter->GetOutputPort());
mapper->ScalarVisibilityOn(); // 开启标量可视化
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 设置Renderer和RenderWindow
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(1.0, 1.0, 1.0); // 背景颜色为白色
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(800, 600);
// 设置RenderWindowInteractor
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
// 初始化并启动交互
renderWindow->Render();
interactor->Initialize();
interactor->Start();
return 0;
}
代码说明
-
创建球体源 (
vtkSphereSource
):vtkSphereSource
用于生成一个球体。通过SetRadius
、SetThetaResolution
和SetPhiResolution
可以控制球体的半径和细分程度。
-
收缩球体 (
vtkShrinkFilter
):vtkShrinkFilter
将球体表面进行收缩。通过SetShrinkFactor
设置收缩因子(例如0.7表示收缩到原始大小的70%)。收缩的原理是将每个单元的点向其质心移动。
-
应用高程映射 (
vtkElevationFilter
):vtkElevationFilter
根据球体的Z轴坐标生成标量值。通过SetLowPoint
和SetHighPoint
指定低点和高点的坐标,标量值会根据点的Z坐标在低值和高值之间插值。SetScalarRange
设置标量值的范围(例如-1.0
到1.0
)。
-
创建Mapper和Actor:
vtkPolyDataMapper
将几何数据和标量数据映射到Actor上。ScalarVisibilityOn
启用标量可视化,使颜色根据标量值变化。
-
设置Renderer和RenderWindow:
- 将Actor添加到Renderer中,并设置背景颜色。
-
启动交互:
- 初始化RenderWindowInteractor并启动交互循环,用户可以通过鼠标操作视图。
作用原理
-
vtkShrinkFilter
的作用原理:vtkShrinkFilter
计算每个单元的质心,然后将单元内的每个点向质心移动一定的比例。收缩因子shrinkFactor
决定了移动的比例。例如,shrinkFactor = 0.7
表示点向质心移动70%的距离。
-
vtkElevationFilter
的作用原理:vtkElevationFilter
根据几何体的坐标生成标量值。它通过设置低点和高点(LowPoint
和HighPoint
),计算每个点的标量值。标量值在低点和高点之间线性插值。- 标量值可以用来映射颜色、透明度或其他属性。
-
逐次缩小球体的实现:
- 通过不断调整
SetShrinkFactor
的值,可以实现逐次缩小球体的效果。每次缩小后,球体的表面会向质心移动,同时保留原始的拓扑结构。
- 通过不断调整
运行效果
运行此代码后,你将看到一个红色的球体,其表面被收缩到原始大小的70%。球体的表面颜色根据Z轴方向的高低变化,呈现从低点到高点的渐变效果。通过调整SetShrinkFactor
的值,可以进一步控制收缩程度。
总结
vtkShrinkFilter
用于收缩几何体的表面,保留拓扑结构。vtkElevationFilter
根据几何体的坐标生成标量值,实现高程映射。- 结合这两个滤波器,可以创建动态的几何变换效果,如逐次缩小球体并应用渐变颜色映射。
这种方法适用于需要动态调整几何形状并添加视觉效果的应用场景。