多边形+三角带=闭合多面体
除了多个多边形组成闭合多面体外,还有一种常用的方式,使用两个不同平面上的多边形加上多边形中间的三角带构成闭合多面体;应用场景是在视平面上勾画出一个闭合不自交多边形,以视平面的法线为方向向量,在一定距离计算出来平行于视平面的另外一个闭合不自交多边形;两个闭合多边形对应点逐次放入三角带中,构成三角带的数据,其目的是用于计算闭合多边形将形成的vtkImageData的掩膜数据,用于裁剪视野中的三维数据,或者是将圈选范围内(外)的数据值修改为固定值。
步骤为:
1.获取闭合曲线上的点集合point1;
2.计算另一平面上对应的闭合曲线的点集合point2;
3.交叉放入point1序号和point2序号到三角带坐标中;
4.定义vtkPolyData对象放入点坐标,两个平面信息,加上中间的三角带组成的柱面,就形成了不规则截面的柱体多边形;
构建立方体
使用8个点组成2个面+一条三角带形成闭合的立方体多边形;
const int num_points = 8;
const int num_plane = 6;
const int type_polygon = 4;
float x[num_points][3] = {
{0,0,0},{0,0,1},{1,0,0},{1,0,1},
{1,1,0},{1,1,1},{0,1,0},{0,1,1}
};
vtkIdType pts[num_plane][type_polygon] = {
{0,1,2,3},{4,5,6,7},{0,1,5,4},
{1,2,6,5},{2,3,7,6},{3,0,4,7}
};
vtkNew<vtkPolyData> geometry;
vtkNew<vtkPoints> points;
for (size_t i = 0; i < 8; i++) {
points->InsertPoint(i, x[i]);
}
vtkNew<vtkCellArray> polys;
// 前平面
polys->InsertNextCell(type_polygon);
for (int i = 0; i < type_polygon;i++) {
polys->InsertCellPoint(2*i);
}
// 后平面
polys->InsertNextCell(type_polygon);
for (int i = 0; i < type_polygon; i++) {
polys->InsertCellPoint(2*i+1);
}
// 中间的三角带
vtkNew<vtkCellArray> strips;
strips->InsertNextCell(num_points + 2);
for (int i = 0; i < 8; i++) {
strips->InsertCellPoint(i);
}
strips->InsertCellPoint(0);
strips->InsertCellPoint(1);
geometry->SetPoints(points);
geometry->SetPolys(polys);
geometry->SetStrips(strips);
vtkNew<vtkPolyDataMapper> geometryMapper;
geometryMapper->SetInputData(geometry);
vtkNew<vtkActor> geometryActor;
geometryActor->SetMapper(geometryMapper);
vtkNew<vtkRenderer> renderer;
renderer->AddActor(geometryActor);
renderer->ResetCamera();
renderer->SetBackground(0, 0, 0);
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
renWin->SetSize(300, 300);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renWin->Render();
iren->Start();
在vtkCellArray上分两部分排列单元结构,第一个组4个点,其后紧跟4个点索引,组成一个面;第二组4个点,组成另外一个面;
vtkNew<vtkCellArray> polys;
// 前平面
polys->InsertNextCell(type_polygon);
for (int i = 0; i < type_polygon;i++) {
polys->InsertCellPoint(2*i);
}
// 后平面
polys->InsertNextCell(type_polygon);
for (int i = 0; i < type_polygon; i++) {
polys->InsertCellPoint(2*i+1);
}
注意,三角带的组成点排列顺序:
// 中间的三角带
vtkNew<vtkCellArray> strips;
strips->InsertNextCell(num_points + 2);
for (int i = 0; i < 8; i++) {
strips->InsertCellPoint(i);
}
strips->InsertCellPoint(0);
strips->InsertCellPoint(1);
注释掉geometry->SetStrips(strips);后,就会只有两个面渲染出来,如下图:
未注释掉geometry->SetStrips(strips);时,效果如下: