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

CGAL如何在顶点与两条贝塞尔曲线交点间构建边及报错解决方案

解决方案说明

供所有搜索到该问题、需要解决方案的用户参考:

  • 经CGAL邮件列表讨论确认:两条贝塞尔(Bezier)曲线的交点对应的顶点无法用于构建边,Arr_Bezier_curve_traits_2.h不支持该操作
  • 官方建议改用Arr_algebraic_segment_traits.h,该头文件虽不明确支持贝塞尔曲线,但支持通用多项式运算

原问题描述

使用CGAL Arrangement模块,尝试在两条贝塞尔曲线交点对应的顶点与一个普通点之间构建边,运行示例代码时出现段错误。如果边是退化贝塞尔曲线(即#if块对应的else分支代码)则运行正常,示例代码如下:

#include <iomanip>
#include <ios>
#include <iostream>
#include <list>

#include <CGAL/basic.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arrangement_with_history_2.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Arr_vertical_decomposition_2.h>
#include <CGAL/Sweep_line_2_algorithms.h>


typedef CGAL::CORE_algebraic_number_traits              Nt_traits;
typedef Nt_traits::Rational                             Rational;
typedef Nt_traits::Algebraic                            Algebraic;

typedef CGAL::Cartesian<Rational>                       Rat_kernel;
typedef CGAL::Cartesian<Algebraic>                      Alg_kernel;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
                                                        Traits_2;
  
typedef Traits_2::Curve_2                               Bezier_curve_2;
typedef Traits_2::X_monotone_curve_2                    X_monotone_curve_2;

typedef Alg_kernel::Point_2                             Bezier_alg_point;
typedef Rat_kernel::Point_2                             Bezier_rat_point;
typedef Traits_2::Point_2                               Bezier_point;
typedef Traits_2::X_monotone_curve_2                    Bezier_X_monotone_curve;

typedef Traits_2::Point_2                               Point_2;

typedef CGAL::Arrangement_with_history_2<Traits_2>    Arrangement;

typedef typename Arrangement::Geometry_traits_2 Bezier_traits;
typedef typename Bezier_traits::Curve_2 Curve_2;
typedef typename Bezier_traits::X_monotone_curve_2 X_monotone_curve_2;

typedef typename Arrangement::Vertex_const_handle       Vertex_const_handle;
typedef typename Arrangement::Vertex_handle             Vertex_handle;

typedef typename Arrangement::Halfedge_const_handle     Halfedge_const_handle;
typedef typename Arrangement::Halfedge_handle           Halfedge_handle;

typedef typename Arrangement::Face_const_handle         Face_const_handle;
typedef typename Arrangement::Face_handle               Face_handle;

Bezier_curve_2 constructEdge( Bezier_point p1, Bezier_point p2) {
    std::list<Bezier_point> pts;
    pts.push_back(p1);
    pts.push_back(p2);
    return Bezier_curve_2(pts.begin(), pts.end());
}

Bezier_curve_2 constructEdge( Bezier_point p1, Bezier_point p2, Bezier_point p3) {
    std::list<Bezier_point> pts;
    pts.push_back(p1);
    pts.push_back(p2);
    pts.push_back(p3);
    return Bezier_curve_2(pts.begin(), pts.end());
}

/*
 * 使用CGAL Arrangement模块,尝试在两条贝塞尔曲线交点对应的顶点与一个普通点之间构建边
 *
 * 本示例中,尝试构建边时会触发段错误
 * 
 * 如果边是退化贝塞尔曲线(即#if块的else分支代码)则运行正常
 * 
 */


int main(int argc, char* argv[])
{
    Arrangement arr;

    std::list<Bezier_curve_2> curves;
#if 1   
    curves.push_back( constructEdge( Point_2( -100,0 ), Point_2( 0, 10 ), Point_2( 100, 0 ))); 
    curves.push_back( constructEdge( Point_2( 0,-100 ), Point_2( 10, 0 ), Point_2( 0, 100)));
#else   
    curves.push_back( constructEdge( Point_2( -100,0 ), Point_2( 100, 0 ))); 
    curves.push_back( constructEdge( Point_2( 0,-100 ), Point_2( 0, 100)));
#endif  

    insert(arr, curves.begin(), curves.end());

    typedef std::list<std::pair<Vertex_const_handle,
            std::pair<CGAL::Object, CGAL::Object> > >   Ray_shoot_list;

    Ray_shoot_list                     vrs_list;
    typename Ray_shoot_list::iterator  vrs_iter;
    
    CGAL::decompose (arr, std::back_inserter (vrs_list));

    std::list<Bezier_curve_2> moreCurves;
    
    for (typename Ray_shoot_list::iterator vv = vrs_list.begin(); vv != vrs_list.end(); vv++) {
        Vertex_handle vertex = arr.non_const_handle( vv->first );
        std::cerr << "Vertex " << vertex->point() << " degree " << vertex->degree() << std::endl;

        if (vertex->degree()>1) {
            Point_2 p(1,1);
            std::cerr << "Inserting new edge from " << p << " to " << vertex->point() << std::endl;
            moreCurves.push_back( constructEdge( p, vertex->point() ) );
            insert(arr, moreCurves.begin(), moreCurves.end());
        }
    }

  return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:36:08