从内核中的对象
Simple_cartesian
转换为Extended_cartesian
很简单。例如,我可以做
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());
我的问题是如何向后做?看来我不能像上面那样做。 假设我知道
Extended_cartesian
核数类型表示的数是有限有理数。我查看了FT类型后,类型似乎是CGAL::Nef_polynomial<CGAL::Gmpq>
。在这种情况下,我怎样才能正确地将它转换回标准类型 CGAL::Gmpq
?我想找到一个无损的转换。换句话说,将其转换为 double
然后再转换为 CGAL::Gmpq
是次优的。
扩展内核仅用于 Nef 多边形和多面体 来表示非有限对象(如射线)。在这种情况下,所有坐标都变成了extended,并且这种扩展是使用
CGAL::Nef_polynomial
类型实现的。看起来这种类型的对象是由系数数组表示的。如果您只使用常规点(在 CGAL standard points 中称为),那么它们的坐标将由这些数组的第一个元素表示 - 因此,解决方案:
#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;
}
上述方法可能不是 CGAL 开发人员计划的。实际上,我查看了
Extended_cartesian.h
标题并找到了一个函数standard_point
,它返回了您想要的内容(但仅适用于二维点):
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]);
}
所以,上面的解决方案类似于这个功能。