To convert from the object in the kernel Simple_cartesian
to Extended_cartesian
is simple. For example, I can do
CGAL::Simple_cartesian<CGAL::Gmpq>::Point_3 p_s(1, 2, 3);
CGAL::Extended_cartesian<CGAL::Gmpq>::Point_3 p_e(p_s.x(), p_s.y(), p_s.z());
My question is how to do it backwards? It seems that I cannot do it in the same way as above.
Assume I know that the number represented by the Extended_cartesian
kernel number type is a finite rational number. After I check the FT type, it appears that the type is CGAL::Nef_polynomial<CGAL::Gmpq>
. How can I properly convert it back to the standard type which is CGAL::Gmpq
in this case? I would like to find a conversion that is lossless. In other words, converting it to double
and then converting to CGAL::Gmpq
is suboptimal.
Extended kernels are used only for Nef polygons and polyhedra to represent non-finite objects (like rays). In this case all the coordinates become extended, and this extension is achieved using the CGAL::Nef_polynomial
type. It looks like objects of this type are represented by arrays of coefficients. If you work with regular points (which are called in CGAL standard points) only, then their coordinates will be represented by first elements of these arrays - so, the solution:
#include <iostream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Extended_cartesian.h>
#include <CGAL/Gmpq.h>
using KernelE = CGAL::Extended_cartesian<CGAL::Gmpq>;
using PointE = KernelE::Point_3;
using KernelS = CGAL::Simple_cartesian<CGAL::Gmpq>;
using PointS = KernelS::Point_3;
int main()
{
PointE const pe{1, 2, 3};
std::cout << pe << std::endl;
PointS const ps(pe.x()[0], pe.y()[0], pe.z()[0]);
std::cout << ps << std::endl;
}
The approach above might be not what CGAL developers planned. Actually I looked at the Extended_cartesian.h
header and found a function standard_point
, which returned what you wanted (but only for points in 2D):
Standard_point_2 standard_point(const Point_2& p) const
/*{\Xop returns the standard point represented by |p|.
\precond |\Mvar.is_standard(p)|.}*/
{ CGAL_assertion( type(p)==STANDARD );
return Standard_point_2(p.x()[0],p.y()[0]);
}
So, the solution above is similar to this function.