Search code examples
c++serializationtype-conversioncgal

Serialization of exact numbers in CGAL


I have to serialize/deserialize some exact rationals (preferably in a human readable format), computed with CGALs Exact_predicates_exact_constructions_kernel (Epeck with lazy evaluation).

My idea was to use Cartesian_converter to convert Epeck numbers to exact numbers of type Quotient and export numerator and denominator separately:

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>

using QKernel = CGAL::Simple_cartesian<CGAL::Quotient<CGAL::MP_Float>>; 
using Epeck = CGAL::Exact_predicates_exact_constructions_kernel;

// ...

CGAL::Point_2<Epeck> p(x, y);
CGAL::Cartesian_converter<Epeck, QKernel> to_qkernel;
CGAL::Point_2<QKernel> q = to_qkernel(p);

std::cout << q.x().numerator() << "/" << q.x().denominator() << " " 
          << q.y().numerator() << "/" << q.y().denominator() << std::endl;

This doesn't compile, since there ist no matching constructor. It seems that the Cartesian_converter tries to put the Epeck number as numerator, which cannot work since the Epeck number is a FieldType, whereas the numerator have to be a RingType.

/usr/local/include/CGAL/Quotient.h:97:35: error: no matching constructor for initialization of 'CGAL::Quotient<CGAL::MP_Float>::NT' (aka 'CGAL::MP_Float')
  explicit Quotient(const T& n) : num(n), den(1) {}
                                  ^   ~

Furthermore this seems not to be the smartest way of serialisation (if it would work), since neither the numerator, nor the denominator needs to be integral.

Question: Is there any way to serialize a number of type Epeck::FT to a string n + "/" + d, where n and d are integral?


Solution

  • Epeck::Exact_kernel is the exact non-filtered kernel internally used. It means that calls on any Kernel object CGAL::exact() will return an object from this type.

    For example:

    Epeck::Point_3 p;
    Epeck::Exact_kernel pp = CGAL::exact(p);
    

    Then you can serialize pp directly using operator<<(). Note however that you will loose the tree structure from Epeck.