以下是一个简单的示例,展示如何使用 vtkStructuredGrid
实现一个分形的树枝状几何体。我们将基于递归的分形算法生成树枝结构,并将其存储在 vtkStructuredGrid
中。
示例代码
#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkStructuredGrid.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCellArray.h>
#include <vtkTubeFilter.h>
#include <vtkLine.h>
#include <vtkLookupTable.h>
#include <vtkStructuredGridGeometryFilter.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <cmath>
#include <vector>// 递归生成树枝分形
void GenerateBranch(vtkSmartPointer<vtkPoints> points, vtkSmartPointer<vtkCellArray> lines, const double start[3], const double end[3], int level, int maxLevel)
{if (level > maxLevel) return;// 添加线段vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();vtkIdType startId = points->InsertNextPoint(start);vtkIdType endId = points->InsertNextPoint(end);line->GetPointIds()->SetId(0, startId);line->GetPointIds()->SetId(1, endId);lines->InsertNextCell(line);// 计算分支的偏移方向double dir[3] = {end[0] - start[0], end[1] - start[1], end[2] - start[2]};double length = sqrt(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]);for (int i = 0; i < 3; i++) dir[i] /= length;// 计算分支的旋转矩阵double theta = M_PI / 4.0; // 分支角度double rotX[3][3], rotY[3][3], rotZ[3][3];rotX[0][0] = 1; rotX[0][1] = 0; rotX[0][2] = 0;rotX[1][0] = 0; rotX[1][1] = cos(theta); rotX[1][2] = -sin(theta);rotX[2][0] = 0; rotX[2][1] = sin(theta); rotX[2][2] = cos(theta);rotY[0][0] = cos(theta); rotY[0][1] = 0; rotY[0][2] = sin(theta);rotY[1][0] = 0; rotY[1][1] = 1; rotY[1][2] = 0;rotY[2][0] = -sin(theta); rotY[2][1] = 0; rotY[2][2] = cos(theta);rotZ[0][0] = cos(theta); rotZ[0][1] = -sin(theta); rotZ[0][2] = 0;rotZ[1][0] = sin(theta); rotZ[1][1] = cos(theta); rotZ[1][2] = 0;rotZ[2][0] = 0; rotZ[2][1] = 0; rotZ[2][2] = 1;// 生成新的分支double newEnd[3];for (int i = 0; i < 3; i++){newEnd[i] = end[i] + 0.5 * dir[i]; // 缩短分支长度}// 生成子分支double branch1[3], branch2[3];for (int i = 0; i < 3; i++){branch1[i] = end[i] + 0.5 * (rotX[i][0] * dir[0] + rotX[i][1] * dir[1] + rotX[i][2] * dir[2]);branch2[i] = end[i] + 0.5 * (rotY[i][0] * dir[0] + rotY[i][1] * dir[1] + rotY[i][2] * dir[2]);}// 递归生成子分支GenerateBranch(points, lines, end, branch1, level + 1, maxLevel);GenerateBranch(points, lines, end, branch2, level + 1, maxLevel);
}int main()
{// 创建点集和线段vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();// 定义树的根节点double start[3] = {0, 0, 0};double end[3] = {0, 1, 0};// 生成树枝分形GenerateBranch(points, lines, start, end, 0, 6);// 创建 vtkStructuredGridvtkSmartPointer<vtkStructuredGrid> grid = vtkSmartPointer<vtkStructuredGrid>::New();grid->SetPoints(points);grid->SetDimensions(points->GetNumberOfPoints(), 1, 1);// 将 vtkStructuredGrid 转换为几何数据vtkSmartPointer<vtkStructuredGridGeometryFilter> geometryFilter = vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();geometryFilter->SetInputData(grid);geometryFilter->Update();// 创建映射器vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(geometryFilter->GetOutputPort());// 创建ActorvtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);actor->GetProperty()->SetColor(0.4, 0.2, 0.0); // 树枝颜色// 创建渲染器和渲染窗口vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();renderWindow->AddRenderer(renderer);vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();interactor->SetRenderWindow(renderWindow);// 添加Actor到渲染器renderer->AddActor(actor);// 设置背景颜色renderer->SetBackground(0.1, 0.2, 0.3);// 启动交互renderWindow->Render();interactor->Start();return 0;
}
代码说明
-
递归生成树枝:
- 使用递归函数
GenerateBranch
生成树枝的分形结构。 - 每次递归生成一个分支,并根据旋转矩阵生成新的子分支。
- 使用递归函数
-
存储数据:
- 使用
vtkPoints
存储分形树枝的点。 - 使用
vtkCellArray
存储线段。
- 使用
-
可视化处理:
- 将生成的点集和线段存储到
vtkStructuredGrid
中。 - 使用
vtkStructuredGridGeometryFilter
将vtkStructuredGrid
转换为几何数据。 - 使用
vtkPolyDataMapper
和vtkActor
进行可视化。
- 将生成的点集和线段存储到
-
运行效果:
- 窗口中会显示一个分形的树枝状几何体。
- 用户可以通过鼠标交互旋转和缩放视角。
编译和运行
- 确保已安装 VTK 库,并配置好开发环境。
- 使用 CMake 或直接编译代码:
g++ -o vtk_fractal_tree vtk_fractal_tree.cpp -lvtkCommonCore -lvtkFiltersCore -lvtkRenderingCore -lvtkInteractionStyle
- 运行生成的可执行文件:
./vtk_fractal_tree
结果
- 窗口中会显示一个分形的树枝状几何体。
- 用户可以通过鼠标交互查看分形的不同角度。