You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CGAL Arrangements:如何获取孔洞内部的面列表?

CGAL Arrangement 获取孔洞内部面列表的简便方法

针对你提到的场景(比如CGAL手册中图34.2里的面f1,其孔洞包含f3和f4),目前CGAL的Arrangement_on_surface_2框架并没有直接提供“通过孔洞直接获取内部面列表”的API,但可以用更高效的方式替代你当前的去重遍历方案:

  • 利用面的包含关系做广度/深度优先搜索:每个孔洞的循环(Ccb_halfedge_circulator)对应着内侧的初始面,从这个初始面出发,遍历它所有内孔洞对应的子面,同时记录已访问的面避免重复,就能一次性获取所有被当前孔洞包含的面。这种方式比遍历所有半边再去重效率更高,逻辑也更清晰。

举个简化的代码片段示例:

#include <CGAL/Arrangement_on_surface_2.h>
#include <queue>
#include <unordered_set>

typedef CGAL::Arrangement_on_surface_2<...> Arrangement;
typedef Arrangement::Face_handle Face_handle;
typedef Arrangement::Ccb_halfedge_circulator Ccb_circulator;

std::vector<Face_handle> get_hole_inner_faces(Face_handle f, Ccb_circulator hole_ccb) {
    std::vector<Face_handle> inner_faces;
    std::queue<Face_handle> face_queue;
    std::unordered_set<Face_handle> visited;

    // 初始面:孔洞循环对应的第一个内侧面
    Face_handle start_face = hole_ccb->twin()->face();
    if (visited.find(start_face) == visited.end()) {
        visited.insert(start_face);
        face_queue.push(start_face);
    }

    // BFS遍历所有被包含的面
    while (!face_queue.empty()) {
        Face_handle current_face = face_queue.front();
        face_queue.pop();
        inner_faces.push_back(current_face);

        // 遍历当前面的所有内孔洞,处理其包含的子面
        for (auto inner_ccb = current_face->inner_ccbs_begin(); inner_ccb != current_face->inner_ccbs_end(); ++inner_ccb) {
            Face_handle sub_face = (*inner_ccb)->twin()->face();
            if (visited.find(sub_face) == visited.end()) {
                visited.insert(sub_face);
                face_queue.push(sub_face);
            }
        }
    }

    return inner_faces;
}

内容的提问来源于stack exchange,提问作者Clement

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:03:10