I'd like to do exact computations on regular polygons. To do so, I wrote the code you find below. But the expression cos*cos
will not compile. Apparently multiplication is not defined for the algebraic number type I'm using. I guess I'll have to try some other approach. Currently there seem to be two candidates:
- RS apparently provides some more advanced algebraic functionality, and CGAL has support for it. But I see no multiplication operators in the related headers, so I doubt that it will do multiplication the way I'd want.
- leda::real seems to be a type for algebraic real numbers. I'll probably have to rewrite my code, but it should be possible to achieve similar results. Perhaps I could even convert the
cos
I computed in CGAL to such aleda::real
. The LEDA header at least appears to have anoperator*
. LEDA is free for my use but still closed source. Andleda_real.h
for CGAL 4.3 looks strange: it refers toleda_real
notleda::real
, so perhaps it is written for an outdated version of LEDA. And it apparently includes itself, which looks pretty pointless.
Which of these alternatives would work best for construction of an exact CGAL kernel capable of describing regular n-gons for arbitrary n? Does any of these work at all? Is there another alternative I'm missing?
Since I don't have either RS or LEDA installed on my computer, I'd prefer an educated opinion before I start building them, and perhaps even writing install instructions (“ebuilds”) for my Gentoo linux.
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
//define CGAL_USE_RS
#include <CGAL/Gmpz.h>
#include <CGAL/Algebraic_kernel_d_1.h>
#include <CGAL/Algebraic_kernel_rs_gmpz_d_1.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#define DBG(x) std::cerr << x << std::endl
typedef CGAL::Gmpz ZZ;
// typedef CGAL::Algebraic_kernel_rs_gmpz_d_1 AK;
typedef CGAL::Algebraic_kernel_d_1<ZZ> AK;
typedef AK::Polynomial_1 Polynomial;
typedef AK::Algebraic_real_1 AA;
typedef AK::Coefficient Coeff;
typedef AK::Bound Bound;
typedef AK::Multiplicity_type Multiplicity;
typedef CGAL::Homogeneous<AK> Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits;
typedef Kernel::Point_2 Point;
typedef Kernel::Segment_2 Segment;
typedef CGAL::Arrangement_2<Traits> Arrangement;
static unsigned run(unsigned short n) {
AK ak;
AK::Construct_algebraic_real_1 to_AA = ak.construct_algebraic_real_1_object();
AK::Solve_1 solve = ak.solve_1_object();
Polynomial x{CGAL::shift(Polynomial(1), 1)}, twox{2*x};
Polynomial a{1}, b{x};
for (unsigned short i = 2; i <= n; ++i) {
Polynomial c = twox*b - a;
a = b;
b = c;
}
std::vector<std::pair<AA, Multiplicity>> roots;
solve(b - 1, std::back_inserter(roots));
AA one{1}, cos{-2};
for (auto i = roots.begin(), e = roots.end(); i != e; ++i) {
AA cur = i->first;
if (cur < one && cur > cos)
cos = cur;
}
AA sin = CGAL::sqrt(to_AA(1) - cos*cos);
//DBG("sin="<<CGAL::to_double(sin)<<", cos="<<CGAL::to_double(cos));
return 0;
}
int main(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
unsigned short n;
std::istringstream(argv[i]) >> n;
std::cout << n << ": " << run(n) << std::endl;
}
return 0;
}