在CGAL中转换坐标值

问题描述 投票:0回答:1

从CGAL,我目前正在使用以下软件包:Boolean operations on polygons

我对多边形感兴趣,因为多边形除了线段外,边线也可以是圆弧段,因此我在基本的typedef中使用了以下内容:

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2                                   Point_2;
typedef Kernel::Circle_2                                  Circle_2;
typedef Kernel::Line_2                                    Line_2;
typedef CGAL::Gps_circle_segment_traits_2<Kernel>         Traits_2;

typedef CGAL::General_polygon_set_2<Traits_2>             Polygon_set_2;
typedef Traits_2::General_polygon_2                       Polygon_2;
typedef Traits_2::General_polygon_with_holes_2            Polygon_with_holes_2;
typedef Traits_2::Curve_2                                 Curve_2;
typedef Traits_2::X_monotone_curve_2                      X_monotone_curve_2;
typedef Traits_2::Point_2                                 Point_2t;
typedef Traits_2::CoordNT                                 coordnt;
typedef CGAL::Arrangement_2<Traits_2>                     Arrangement_2;
typedef Arrangement_2::Face_handle                        Face_handle;

如上面的类型所示,我有两个Point-type,即Point_2(即Kernel :: Point_2)和我称为Point_2t(即Traits_2 :: Point_2)。

[它们之间的区别是Point_2具有有理坐标x(),y(),而Point_2t具有Q(alpha)坐标,其中Q表示有理数域,而alpha是有理数的平方根。

或者,换句话说,Point_2的坐标在Kernel :: FT中,而Point_2t的坐标在Traits_2 :: CoordNT中。

因此,从Point_2转换为Point_2t没问题,但我也必须从Point_2t转换为Point_2t,希望可以通过这种方式来控制丢失的精度。

阅读文档并使用eclipse的自动完成功能,我组成了以下例程:

const int use_precision = 100;

CGAL::Gmpfr convert(CGAL::Gmpq z)
{
    CGAL::Gmpz num = z.numerator();
    CGAL::Gmpz den = z.denominator();

    CGAL::Gmpfr num_f(num);
    CGAL::Gmpfr den_f(den);

    return num_f/den_f;
}


CGAL::Gmpfr convert(Traits_2::CoordNT z)
{
    Kernel::FT a0_val = z.a0();
    Kernel::FT a1_val = z.a1();
    Kernel::FT root_val = z.root();

    CGAL::Gmpq a0_q = a0_val.exact();
    CGAL::Gmpq a1_q = a1_val.exact();
    CGAL::Gmpq root_q = root_val.exact();

    CGAL::Gmpfr a0_f = convert(a0_q);
    CGAL::Gmpfr a1_f = convert(a1_q);
    CGAL::Gmpfr root_f = convert(root_q);

    CGAL::Gmpfr res = a0_f + a1_f * root_f.sqrt(use_precision);

    return res;
}

Point_2 convert(Point_2t p)
{
    CGAL::Gmpfr xx = convert(p.x());
    CGAL::Gmpfr yy = convert(p.y());

    CGAL::Gmpq xx1 = xx;
    CGAL::Gmpq yy1 = yy;

    Kernel::FT xx2 = xx1;
    Kernel::FT yy2 = yy1;

    Point_2 pp(xx2, yy2);
    return pp;
}

基本上是将Traits_2 :: CoordNT的坐标转换为形式

(*)a0 + a1 * sqrt(root)

with a0,a1,root from Kernel :: FT(= rational field),然后将a0,a1,root转换为Gmpq有理数,将它们转换为Gmpfr,精度为100位小数,然后计算表达式(*)并转换回Gmpq然后是Kernel :: FT。所有转换(或多或少)仅由分配完成,并由CGAL自动转换。

在我的测试中,这看似正确,但我仍然不确定100%是否根据CGAL定义(*)中的sqrt(root)表达式始终表示正平方根。

我浏览了定义:

description of sqrt-extended Number type in CGAL

但是即使那样,我还是不能完全相信,仅采用sqrt(root)的正值。

因此,我向那些完全了解CGAL系统的人提出的问题:

上面的转换例程在始终假设要取根的正值的情况下正确吗?

computational-geometry numeric cgal
1个回答
0
投票

是的,你是对的。在CGAL Sqrt_extension中,在表达式Sqrt_extension中,平方根始终为正或为null。

© www.soinside.com 2019 - 2024. All rights reserved.