vtkCellArray
是Visualization Toolkit (VTK)
中的一个核心类,用于表示和存储图形数据中的单元(cells),如线段(lines)、多边形(polygons)和多面体(polyhedra)。每个单元由一系列点(vertices)组成,这些点定义了单元的形状和位置。vtkCellArray
被广泛用于 VTK 的各种图形对象中,包括vtkPolyData
和vtkUnstructuredGrid
,允许高效地存储和访问复杂的三维图形数据。
vtkCellArray 的结构
vtkCellArray
的结构是为了高效地存储和遍历图形数据中的单元。它主要包括以下部分:
- 点索引(Point Indexes):这是指向
vtkPoint
对象中点的索引,vtkPoints
存储了图形数据中所有点的坐标。每个单元由一组点索引组成,这些索引确定了单元的形状和位置。 - 连接性(Connectivity)数据:这部分数据描述了单元是如何从点构建起来的。对于每个单元,
vtkCellArray
首先存储一个数字,指示单元中点的数量,接着是构成该单元的点的索引。
使用 vtkCellArray 画线
在使用vtkCellArray
时,遵循以下步骤:
- 创建和初始化:首先创建一个
vtkCellArray
实例,并通过添加点索引来定义单元。 - 添加单元:使用
InsertNextCell
方法添加新单元,该方法接受一个点的数量和一系列点索引。 - 绑定到图形对象:将
vtkCellArray
对象设置为某个图形对象(如 vtkPolyData)的一部分,以表示该对象的单元。
// 创建点集
var points = vtkPoints.New();
points.InsertNextPoint(0.0, 0.0, 0.0);
points.InsertNextPoint(1.0, 1.0, 0.0);
points.InsertNextPoint(2.0, 3.0, 0.0);
points.InsertNextPoint(4.0, 5.0, 0.0);
// 创建CellArray来存储线段
var lines = vtkCellArray.New();
// 添加第一条线段(点0和点1)
lines.InsertNextCell(2);
lines.InsertCellPoint(0);
lines.InsertCellPoint(1);
// 添加第二条线段(点2和点3)
lines.InsertNextCell(2);
lines.InsertCellPoint(2);
lines.InsertCellPoint(3);
// 创建PolyData对象
var polyData = vtkPolyData.New();
polyData.SetPoints(points);
polyData.SetLines(lines);
// 创建映射器和actor
var mapper = vtkPolyDataMapper.New();
mapper.SetInput(polyData);
var actor = vtkActor.New();
actor.SetMapper(mapper);
使用 vtkCellArray 生成四边形网格
创建一个10*10的四边形网格
// 定义网格大小
int gridSize = 10;
// 创建点集
var points = vtkPoints.New();
for (int i = 0; i <= gridSize; ++i)
{
for (int j = 0; j <= gridSize; ++j)
{
points.InsertNextPoint(i, j, 0);
}
}
// 创建四边形单元
var lines = vtkCellArray.New();
for (int i = 0; i <= gridSize; ++i)
{
for (int j = 0; j < gridSize; ++j)
{
// 水平线段
lines.InsertNextCell(2);
lines.InsertCellPoint(i * (gridSize + 1) + j);
lines.InsertCellPoint(i * (gridSize + 1) + (j + 1));
// 垂直线段
lines.InsertNextCell(2);
lines.InsertCellPoint(j * (gridSize + 1) + i);
lines.InsertCellPoint((j + 1) * (gridSize + 1) + i);
}
}
// 创建PolyData对象
var polyData = vtkPolyData.New();
polyData.SetPoints(points);
polyData.SetLines(lines);
var mapper = vtkPolyDataMapper.New();
mapper.SetInputData(polyData);
var actor = vtkActor.New();
actor.SetMapper(mapper);
var renderer = renderWindowControl.RenderWindow.GetRenderers().GetFirstRenderer();
renderer.AddActor(actor);
renderer.SetBackground(0.1, 0.2, 0.4);
加上高斯分布的形变场
要创建一个形变场,使得 10×10
的平面网格按照高斯分布形变,需要首先计算每个点在高斯分布下的偏移量,然后应用这些偏移量来更新网格中每个点的位置。
// 定义网格大小
int gridSize = 10;
double a = 5.0; // 高度因子
double mu_x = gridSize / 2.0;
double mu_y = gridSize / 2.0;
double sigma_x = gridSize / 4.0;
double sigma_y = gridSize / 4.0;
var points = vtkPoints.New();
for (int i = 0; i <= gridSize; ++i)
{
for (int j = 0; j <= gridSize; ++j)
{
double x = i;
double y = j;
// 应用高斯分布
double z = a * Math.Exp(-((x - mu_x) * (x - mu_x) / (2 * sigma_x * sigma_x) + (y - mu_y) * (y - mu_y) / (2 * sigma_y * sigma_y)));
points.InsertNextPoint(x, y, z);
}
}
同上...
加上颜色
// 获取颜色范围
double[] colorRange = pointColors.GetRange();
double minColorRange = colorRange[0];
double maxColorRange = colorRange[1];
// 创建映射器并应用颜色查找表
var mapper = vtkPolyDataMapper.New();
mapper.SetInputData(polyData);
mapper.SetScalarRange(minColorRange, maxColorRange); // 根据Z值的范围设置颜色映射范围
var lookupTable = vtkLookupTable.New();
lookupTable.SetRange(minColorRange, maxColorRange); // 设置查找表的标量值范围
lookupTable.SetNumberOfTableValues(512); // 设置颜色表中颜色的数量
lookupTable.Build(); // 构建默认渐变
mapper.SetLookupTable(lookupTable);
// 看看Bar
var scalarBar = vtkScalarBarActor.New();
scalarBar.SetLookupTable(mapper.GetLookupTable());
scalarBar.SetTitle("Height");
scalarBar.SetNumberOfLabels(4);
// 别忘了放actor
renderer.AddActor2D(scalarBar);
然后再往CT里放一下就假装有了一个形变场