基于VTK从点集生成复杂凹多边形曲面的方法求助
解决方案:约束Delaunay三角剖分(VTK)
针对vtkDelaunay2D无法正确还原凹多边形形状的问题,核心是给三角剖分添加边界约束,让算法严格在凹多边形内部生成三角面。以下是具体实现步骤和注意事项:
1. 整理点集顺序
确保凹多边形的边界点按顺时针或逆时针的连续顺序排列(形成闭合环),内部点可任意顺序添加。若点集乱序,需先通过质心极角排序等方法整理边界点顺序。
2. 构建带约束边界的PolyData
将边界点和内部点整合到同一个vtkPolyData中,明确标记凹多边形的闭合边界环:
// 假设已有的点集合:boundaryPoints(边界点,有序)、innerPoints(内部点) vtkSmartPointer<vtkPoints> allPoints = vtkSmartPointer<vtkPoints>::New(); // 添加边界点 for (int i = 0; i < boundaryPoints->GetNumberOfPoints(); i++) { double p[3]; boundaryPoints->GetPoint(i, p); allPoints->InsertNextPoint(p); } // 添加内部点 for (int i = 0; i < innerPoints->GetNumberOfPoints(); i++) { double p[3]; innerPoints->GetPoint(i, p); allPoints->InsertNextPoint(p); } // 创建闭合边界环 vtkSmartPointer<vtkPolygon> boundaryLoop = vtkSmartPointer<vtkPolygon>::New(); boundaryLoop->GetPointIds()->SetNumberOfIds(boundaryPoints->GetNumberOfPoints()); for (int i = 0; i < boundaryPoints->GetNumberOfPoints(); i++) { boundaryLoop->GetPointIds()->SetId(i, i); // 边界点索引为0到n-1 } vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New(); polygons->InsertNextCell(boundaryLoop); // 组装PolyData vtkSmartPointer<vtkPolyData> inputPolyData = vtkSmartPointer<vtkPolyData>::New(); inputPolyData->SetPoints(allPoints); inputPolyData->SetPolygons(polygons);
3. 启用约束三角剖分
配置vtkDelaunay2D开启约束模式,确保算法遵守边界约束:
vtkSmartPointer<vtkDelaunay2D> delaunay = vtkSmartPointer<vtkDelaunay2D>::New(); delaunay->SetInputData(inputPolyData); delaunay->SetConstrainedTriangulation(true); // 关键:开启约束 delaunay->SetTolerance(1e-6); // 根据点集精度调整,避免浮点误差导致约束失效 delaunay->Update(); // 获取最终的三角化曲面 vtkPolyData* concaveSurface = delaunay->GetOutput();
4. 复杂场景处理(带孔洞的凹多边形)
若凹多边形包含内部孔洞,需添加多个约束环:
- 外边界环按顺时针顺序排列
- 内部孔洞环按逆时针顺序排列(与外边界方向相反)
- 将所有环添加到vtkCellArray中,再设置给PolyData的Polygons属性
备选方案:vtkAlphaShape2D
若无法整理边界点顺序,可尝试vtkAlphaShape2D:
- 通过调整
SetAlpha()参数控制曲面形状:Alpha值越大越接近凸包,越小越贴合凹部 - 缺点是Alpha值需根据点集密度手动调整,精度不如约束Delaunay
内容的提问来源于stack exchange,提问作者Jish
相关产品推荐
相关产品推荐

