Преобразование значений координат в CGAL - PullRequest
0 голосов
/ 21 марта 2020

Из CGAL В настоящее время я использую следующий пакет: Булевы операции над полигонами

Поскольку меня интересуют полигоны, которые могут иметь, кроме отрезков линии, в качестве ребер и окружностей сегменты, я используйте следующую сборку для моих базовых c typedefs:

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, а именно Point_2, который является Kernel :: Point_2 и который я назвал Point_2t, который это Черты_2 :: Точка_2.

Разница между ними состоит в том, что Point_2 имеет рациональные координаты x (), y (), тогда как Point_2t имеет координаты в Q (альфа), где Q обозначает рациональное поле, а альфа представляет собой квадрат- root рациональное число.

Или, иначе говоря, координаты Point_2 находятся в Kernel :: FT, тогда как координаты Point_2t находятся в Traits_2 :: CoordNT.

Таким образом, преобразование из Point_2 в Point_2t это не проблема, но я должен также преобразовать из Point_2t в Point_2, надеюсь, таким способом, который дает контроль над потерянной точностью.

Читая документацию и используя функцию автозаполнения 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)

с a0, a1, root из Kernel :: FT (= рациональное поле), затем преобразовать a0, a1, root в рациональные числа Gmpq, в Gmpfr с точностью до 100 десятичных дробей, затем вычислить e xpression (*) и преобразовать обратно в Gmpq, а затем Kernel :: FT. Все преобразования (более или менее) просто выполняются с помощью заданий и автоматического c преобразования с помощью CGAL. ​​

В моих тестах это работало, казалось бы, правильно, но я все еще не уверен на 100%, если, согласно В определениях CGAL выражение sqrt (root) в (*) всегда означает положительный квадрат- root.

Я просматривал определение:

описание sqrt- расширенный тип числа в CGAL

, но даже тогда я не полностью убежден, что принимается только положительное значение sqrt (root).

Так что мой вопрос к тем, кто полностью понимает систему CGAL в этом пункте:

Правильны ли мои приведенные выше процедуры преобразования при условии, что всегда принимается положительное значение root?

1 Ответ

1 голос
/ 22 марта 2020

Да, вы правы. В CGAL Sqrt_extension, в выражении a0+a1√(root) квадрат root всегда положительный или нулевой.

...