diff --git a/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_converter.h b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_converter.h new file mode 100644 index 00000000000..4f4578b8c66 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_converter.h @@ -0,0 +1,62 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion, Constantinos Tsirogiannis + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_CONVERTER_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_CONVERTER_H + +#include + + +#include + +namespace CGAL { + +// TODO : +// - FT converter ? + +template < class Al_K1, class Al_K2, + class RT_converter = NT_converter, + class Root_of_converter = NT_converter > +class Algebraic_kernel_converter { +public: + + typedef typename Al_K1::RT RT_1; + typedef typename Al_K2::RT RT_2; + typedef RT_converter RT_type_converter; + typedef Root_of_converter Root_of_type_converter; + + typename Al_K2::Polynomial_1_2 operator () (const typename Al_K1::Polynomial_1_2 &p) const + { + return typename Al_K2::Polynomial_1_2(RT_converter()(p.a()), + RT_converter()(p.b()), + RT_converter()(p.c())); + } + + typename Al_K2::Polynomial_for_circles_2_2 operator () + (const typename Al_K1::Polynomial_for_circles_2_2 &p) const + { + return typename Al_K2::Polynomial_for_circles_2_2(RT_converter()(p.a()), + RT_converter()(p.b()), + RT_converter()(p.r_sq())); + } +}; + +} //namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_CONVERTER_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/function_objects_on_roots_and_polynomials_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/function_objects_on_roots_and_polynomials_2_2.h new file mode 100644 index 00000000000..489803e770e --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/function_objects_on_roots_and_polynomials_2_2.h @@ -0,0 +1,222 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTION_OBJECTS_ON_ROOTS_AND_POLYNOMIALS_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTION_OBJECTS_ON_ROOTS_AND_POLYNOMIALS_2_H + +#include + + +#include +#include +#include + +namespace CGAL { + +namespace AlgebraicFunctors { + + template < class AK > + class Solve + { + typedef typename AK::Polynomial_for_circles_2_2 Equation_Circle; + typedef typename AK::Polynomial_1_2 Equation_Line; + + public: + typedef void result_type; + + template < class OutputIterator > + OutputIterator + operator()(const Equation_Circle & e1, + const Equation_Circle & e2, + OutputIterator res) const + { return AlgebraicFunctors::solve ( e1, e2, res); } + + template < class OutputIterator > + OutputIterator + operator()(const Equation_Line & e1, + const Equation_Circle & e2, + OutputIterator res) const + { return AlgebraicFunctors::solve ( e1, e2, res); } + + + template < class OutputIterator > + OutputIterator + operator()(const Equation_Circle & e1, + const Equation_Line & e2, + OutputIterator res) const + { return AlgebraicFunctors::solve ( e1, e2, res); } + + template < class OutputIterator > + OutputIterator + operator()(const Equation_Line & e1, + const Equation_Line & e2, + OutputIterator res) const + { return AlgebraicFunctors::solve ( e1, e2, res); } + + }; + + template < class AK > + class Construct_polynomial_for_circles_2_2 + { + typedef typename AK::RT RT; + typedef typename AK::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2; + + public: + + typedef Polynomial_for_circles_2_2 result_type; + + result_type + operator()(const RT& xc, const RT& yc, const RT& r_sq) const + { return Polynomial_for_circles_2_2(xc, yc, r_sq); } + + }; + + template < class AK > + class Construct_polynomial_1_2 + { + typedef typename AK::RT RT; + typedef typename AK::Polynomial_1_2 Polynomial_1_2; + + public: + + typedef Polynomial_1_2 result_type; + + result_type + operator()( const RT& a, const RT& b, const RT& c) const + { return Polynomial_1_2(a, b, c); } + + }; + + template < class AK > + class Sign_at + { + typedef typename AK::Polynomial_1_2 Polynomial_1_2; + typedef typename AK::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + + public: + typedef CGAL::Sign result_type; + + result_type + operator()( const Polynomial_for_circles_2_2 & equation, + const Root_for_circles_2_2 & r ) const + { return AlgebraicFunctors::sign_at(equation, r); } + + result_type + operator()( const Polynomial_1_2 & equation, + const Root_for_circles_2_2 & r ) const + { return AlgebraicFunctors::sign_at(equation, r); } + + }; + + template < class AK > + class X_critical_points + { + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typedef typename AK::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2; + + public: + typedef void result_type; + + Root_for_circles_2_2 + operator()(const Polynomial_for_circles_2_2 & c, + bool i) const + { return AlgebraicFunctors::x_critical_point(c,i); } + + template + OutputIterator + operator()(const Polynomial_for_circles_2_2 & c, + OutputIterator res) const + { return AlgebraicFunctors::x_critical_points(c,res); } + + }; + + template < class AK > + class Y_critical_points + { + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typedef typename AK::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2; + + public: + typedef void result_type; + + Root_for_circles_2_2 + operator()(const Polynomial_for_circles_2_2 & c, + bool i) const + { return AlgebraicFunctors::y_critical_point(c,i); } + + template + OutputIterator + operator()(const Polynomial_for_circles_2_2 & c, + OutputIterator res) const + { return AlgebraicFunctors::y_critical_points(c,res); } + + }; + + template < class AK > + class Compare_x + { + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typedef typename AK::RT RT; + + public: + typedef CGAL::Comparison_result result_type; + + result_type + operator()(const Root_for_circles_2_2& r1, + const Root_for_circles_2_2& r2) const + { return AlgebraicFunctors::compare_x(r1, r2); } + + }; + + template < class AK > + class Compare_y + { + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typedef typename AK::RT RT; + + public: + typedef CGAL::Comparison_result result_type; + + result_type + operator()(const Root_for_circles_2_2& r1, + const Root_for_circles_2_2& r2) const + { return AlgebraicFunctors::compare_y(r1, r2); } + + }; + + template < class AK > + class Compare_xy + { + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typedef typename AK::RT RT; + + public: + typedef CGAL::Comparison_result result_type; + + result_type + operator()(const Root_for_circles_2_2& r1, + const Root_for_circles_2_2& r2) const + { return AlgebraicFunctors::compare_xy(r1, r2); } + + }; + +} // namespace AlgebraicFunctors + +} //namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTION_OBJECTS_ON_ROOTS_AND_POLYNOMIALS_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_comparison_root_for_circles_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_comparison_root_for_circles_2_2.h new file mode 100644 index 00000000000..f33f0b3ad76 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_comparison_root_for_circles_2_2.h @@ -0,0 +1,52 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion, Julien Hazebrouck + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_COMPARISON_ROOT_FOR_CIRCLES_2_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_COMPARISON_ROOT_FOR_CIRCLES_2_2_H + +#include + + + +namespace CGAL { + namespace AlgebraicFunctors{ + + template + Comparison_result + compare_x(const CGAL::Root_for_circles_2_2& r1, const CGAL::Root_for_circles_2_2& r2){ + return compare(r1.x(), r2.x()); + } + + template + Comparison_result + compare_y(const CGAL::Root_for_circles_2_2& r1, const CGAL::Root_for_circles_2_2& r2){ + return compare(r1.y(), r2.y()); + } + + template + Comparison_result + compare_xy(const CGAL::Root_for_circles_2_2& r1, const CGAL::Root_for_circles_2_2& r2){ + Comparison_result compx = compare_x(r1, r2); + if(compx != 0) + return compx; + return compare_y(r1, r2); + } + + } // namespace AlgebraicFunctors +} // namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_COMPARISON_ROOT_FOR_CIRCLES_2_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_on_roots_and_polynomial_1_2_and_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_on_roots_and_polynomial_1_2_and_2_2.h new file mode 100644 index 00000000000..7adb4252867 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_on_roots_and_polynomial_1_2_and_2_2.h @@ -0,0 +1,184 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion, Julien Hazebrouck + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTIONS_ON_ROOTS_AND_POLYNOMIAL_1_2_AND_2_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTIONS_ON_ROOTS_AND_POLYNOMIAL_1_2_AND_2_2_H + +#include + + + +namespace CGAL { + namespace AlgebraicFunctors { + + + template < class AK, class OutputIterator > + inline + OutputIterator + solve( const typename AK::Polynomial_1_2 & e1, + const typename AK::Polynomial_for_circles_2_2 & e2, + OutputIterator res ) + { + typedef typename AK::FT FT; + typedef typename AK::Root_of_2 Root_of_2; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + if (is_zero(e1.a())){//horizontal line + + const FT hy = -e1.c()/e1.b(); + const FT hdisc = e2.r_sq() - CGAL::square(hy - e2.b()); + CGAL::Sign sign_hdisc = CGAL::sign(hdisc); + + if(sign_hdisc == NEGATIVE) return res; + if(sign_hdisc == ZERO) { + *res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(e2.a()), + Root_of_2(hy)), 2u); + return res; + } + const Root_of_2 x_res1 = make_root_of_2(e2.a(),FT(-1),hdisc); + const Root_of_2 x_res2 = make_root_of_2(e2.a(),FT(1),hdisc); + const Root_of_2 y_res = Root_of_2(hy); + *res++ = std::make_pair + ( Root_for_circles_2_2(x_res1, y_res), 1u); + *res++ = std::make_pair + ( Root_for_circles_2_2(x_res2, y_res), 1u); + return res; + } + else if(is_zero(e1.b())){//vertical line + + const FT vx = -e1.c()/e1.a(); + const FT vdisc = e2.r_sq() - CGAL::square(vx - e2.a()); + CGAL::Sign sign_vdisc = CGAL::sign(vdisc); + + if(sign_vdisc == NEGATIVE) return res; + if(sign_vdisc == ZERO) { + *res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(vx), + Root_of_2(e2.b())), 2u); + return res; + } + + const Root_of_2 x_res = Root_of_2(vx); + const Root_of_2 y_res1 = make_root_of_2(e2.b(),FT(-1),vdisc); + const Root_of_2 y_res2 = make_root_of_2(e2.b(),FT(1),vdisc); + + *res++ = std::make_pair + ( Root_for_circles_2_2(x_res, y_res1), 1u); + *res++ = std::make_pair + ( Root_for_circles_2_2(x_res, y_res2), 1u); + return res; + } + else { + + const FT line_factor = CGAL::square(e1.a()) + CGAL::square(e1.b()); + const FT disc = line_factor*e2.r_sq() - + CGAL::square(e1.a()*e2.a() + e1.b()*e2.b() + e1.c()); + CGAL::Sign sign_disc = CGAL::sign(disc); + + if (sign_disc == NEGATIVE) return res; + + const FT aux = e1.b()*e2.a() - e1.a()*e2.b(); + const FT x_base = (aux*e1.b() - e1.a()*e1.c()) / line_factor; + const FT y_base = (-aux*e1.a() - e1.b()*e1.c()) / line_factor; + + if (sign_disc == ZERO) { + *res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(x_base), + Root_of_2(y_base)), 2u); + return res; + } + + // We have two intersection points, whose coordinates are one-root numbers. + const FT x_root_coeff = e1.b() / line_factor; + const FT y_root_coeff = e1.a() / line_factor; + + if (CGAL::sign(e1.b()) == POSITIVE) { + *res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, -x_root_coeff, disc), + make_root_of_2(y_base, y_root_coeff, disc)), 1u); + *res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, x_root_coeff, disc), + make_root_of_2(y_base, -y_root_coeff, disc)), 1u); + } else { + *res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, x_root_coeff, disc), + make_root_of_2(y_base, -y_root_coeff, disc)), 1u); + *res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, -x_root_coeff, disc), + make_root_of_2(y_base, y_root_coeff, disc)), 1u); + } + return res; + } + } + + template < class AK, class OutputIterator > + inline + OutputIterator + solve( const typename AK::Polynomial_for_circles_2_2 & e1, + const typename AK::Polynomial_1_2 & e2, + OutputIterator res ) + { + return solve (e2, e1, res); + } + + template < class AK, class OutputIterator > + inline + OutputIterator + solve( const typename AK::Polynomial_1_2 & e1, + const typename AK::Polynomial_1_2 & e2, + OutputIterator res ) + { + typedef typename AK::FT FT; + typedef typename AK::Root_of_2 Root_of_2; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + //parallele case + const FT delta = e1.a()*e2.b() - e2.a()*e1.b(); + if(is_zero(delta)) return res; + //case : e2 horizontal + if(is_zero(e2.a())){ + const FT sol = -e2.c()/e2.b(); + *res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(-(e1.b()*sol + e1.c())/e1.a()), + Root_of_2(sol)), 1u); + return res; + } + //general case + const FT sol = (e2.a()*e1.c() - e2.c()*e1.a()) / delta; + *res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(-(e2.b()*sol + e2.c())/e2.a()), + Root_of_2(sol)), 1u); + return res; + } + + template < class AK > + inline + Sign sign_at( const typename AK::Polynomial_1_2 & equation, + const typename AK::Root_for_circles_2_2 & r) + { + Comparison_result c = compare(r.x()*equation.a(), + -equation.c() - r.y()*equation.b()); + if(c == EQUAL) return ZERO; + if(c == LARGER) return POSITIVE; + return NEGATIVE; + } + + + + } // namespace AlgebraicFunctors +} // namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTIONS_ON_ROOTS_AND_POLYNOMIAL_1_2_AND_2_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_on_roots_and_polynomials_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_on_roots_and_polynomials_2_2.h new file mode 100644 index 00000000000..8068dc01bb2 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles/internal_functions_on_roots_and_polynomials_2_2.h @@ -0,0 +1,227 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTIONS_ON_ROOTS_AND_POLYNOMIALS_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTIONS_ON_ROOTS_AND_POLYNOMIALS_2_H + +#include + + +#include + +namespace CGAL { + namespace AlgebraicFunctors { + + template < class AK, class OutputIterator > + inline + OutputIterator + solve( const typename AK::Polynomial_for_circles_2_2 & e1, + const typename AK::Polynomial_for_circles_2_2 & e2, + OutputIterator res ) + { + CGAL_precondition( ! (e1 == e2) ); // polynomials of this type cannot be multiple + // of one another if they are not equal + + typedef typename AK::FT FT; + typedef typename AK::Root_of_2 Root_of_2; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + const FT dx = e2.a() - e1.a(); + const FT dy = e2.b() - e1.b(); + + const FT dx2 = CGAL::square(dx); + const FT dy2 = CGAL::square(dy); + const FT dist2 = dx2 + dy2; // squared distance between centers + const FT diff_sqr_rad = e1.r_sq() - e2.r_sq(); + const FT disc = 2*dist2*(e1.r_sq() + e2.r_sq()) - + (CGAL::square(diff_sqr_rad) + CGAL::square(dist2)); + CGAL::Sign sign_disc = CGAL::sign(disc); + + if (sign_disc == NEGATIVE) return res; + + const FT x_base = ((e1.a() + e2.a()) + dx*diff_sqr_rad / dist2) / 2; + const FT y_base = ((e1.b() + e2.b()) + dy*diff_sqr_rad / dist2) / 2; + + if (sign_disc == ZERO) { + // one double root, + // no need to care about the boolean of the Root_of + *res++ = std::make_pair + ( Root_for_circles_2_2 + (Root_of_2(x_base), Root_of_2(y_base)), + static_cast(2) ); // multiplicity = 2 + return res; + } + + CGAL::Sign sign_dy = CGAL::sign (dy); + CGAL::Sign sign_dx = CGAL::sign (dx); + + // else, 2 distinct roots + if (sign_dy == ZERO) { + const FT y_root_coeff = dx / (2 * dist2); + if(sign_dx == NEGATIVE) { + * res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(x_base), + make_root_of_2(y_base, y_root_coeff, disc)), + static_cast(1) ); + + * res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(x_base), + make_root_of_2(y_base, -y_root_coeff, disc)), + static_cast(1) ); + } else { + * res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(x_base), + make_root_of_2(y_base, -y_root_coeff, disc)), + static_cast(1) ); + + * res++ = std::make_pair + ( Root_for_circles_2_2(Root_of_2(x_base), + make_root_of_2(y_base, y_root_coeff, disc)), + static_cast(1) ); + } + return res; + } + + if (sign_dx == ZERO) { + const FT x_root_coeff = dy / (2 * dist2); + if(sign_dy == POSITIVE) { + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, -x_root_coeff, disc), + Root_of_2(y_base)), + static_cast(1) ); + + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, x_root_coeff, disc), + Root_of_2(y_base)), + static_cast(1) ); + } else { + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, x_root_coeff, disc), + Root_of_2(y_base)), + static_cast(1) ); + + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, -x_root_coeff, disc), + Root_of_2(y_base)), + static_cast(1) ); + } + return res; + } + + const FT x_root_coeff = dy / (2 * dist2); + const FT y_root_coeff = dx / (2 * dist2); + + if (sign_dy == POSITIVE) { + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, -x_root_coeff, disc), + make_root_of_2(y_base, y_root_coeff, disc)), + static_cast(1) ); + + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, x_root_coeff, disc), + make_root_of_2(y_base, -y_root_coeff, disc)), + static_cast(1) ); + } else { + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, x_root_coeff, disc), + make_root_of_2(y_base, -y_root_coeff, disc)), + static_cast(1) ); + * res++ = std::make_pair + ( Root_for_circles_2_2(make_root_of_2(x_base, -x_root_coeff, disc), + make_root_of_2(y_base, y_root_coeff, disc)), + static_cast(1) ); + } + + return res; + } + + template < class AK > + inline + Sign sign_at( const typename AK::Polynomial_for_circles_2_2 & equation, + const typename AK::Root_for_circles_2_2 & r) + { + Comparison_result c = compare(square(r.x() - equation.a()), + equation.r_sq() - + square(r.y() - equation.b())); + if(c == EQUAL) return ZERO; + if(c == LARGER) return POSITIVE; + return NEGATIVE; + } + + + template + typename AK::Root_for_circles_2_2 + x_critical_point(const typename AK::Polynomial_for_circles_2_2 & c, + bool i) + { + typedef typename AK::Root_of_2 Root_of_2; + typedef typename AK::FT FT; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + + const Root_of_2 a1 = make_root_of_2(c.a(),FT(i?-1:1),c.r_sq()); + return Root_for_circles_2_2(a1, c.b()); + } + + template + OutputIterator + x_critical_points(const typename AK::Polynomial_for_circles_2_2 & c, + OutputIterator res) + { + typedef typename AK::FT FT; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + + *res++ = Root_for_circles_2_2( + make_root_of_2(c.a(),FT(-1),c.r_sq()), c.b()); + *res++ = Root_for_circles_2_2( + make_root_of_2(c.a(),FT(1),c.r_sq()), c.b()); + + return res; + } + + template + typename AK::Root_for_circles_2_2 + y_critical_point(const typename AK::Polynomial_for_circles_2_2 &c, + bool i) + { + typedef typename AK::Root_of_2 Root_of_2; + typedef typename AK::FT FT; + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + + const Root_of_2 b1 = make_root_of_2(c.b(),FT(i?-1:1),c.r_sq()); + return Root_for_circles_2_2(c.a(),b1); + } + + template + OutputIterator + y_critical_points(const typename AK::Polynomial_for_circles_2_2 & c, + OutputIterator res) + { + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + + *res++ = Root_for_circles_2_2(c.a(), + make_root_of_2(c.b(),-1,c.r_sq())); + *res++ = Root_for_circles_2_2(c.a(), + make_root_of_2(c.b(),1,c.r_sq())); + + return res; + } + + + + } // namespace AlgebraicFunctors +} // namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_FUNCTIONS_ON_ROOTS_AND_POLYNOMIALS_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles_2_2.h new file mode 100644 index 00000000000..08a55cbbed2 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Algebraic_kernel_for_circles_2_2.h @@ -0,0 +1,95 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_2_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_2_2_H + +#include + + +#include +#include +#include +#include +#include + +#include + +namespace CGAL { + + template< class RT_ > + struct Algebraic_kernel_for_circles_2_2 + { + typedef Algebraic_kernel_for_circles_2_2 Self; + + typedef RT_ RT; + typedef typename Root_of_traits< RT >::RootOf_1 FT; + + typedef CGAL::Polynomial_1_2 Polynomial_1_2; + typedef CGAL::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2; + // problem RT / FT ? + + typedef typename Root_of_traits< RT >::RootOf_2 Root_of_2; + typedef CGAL::Root_for_circles_2_2< RT > Root_for_circles_2_2; + + typedef AlgebraicFunctors::Construct_polynomial_1_2 + Construct_polynomial_1_2; + typedef AlgebraicFunctors::Construct_polynomial_for_circles_2_2 + Construct_polynomial_for_circles_2_2; + + typedef AlgebraicFunctors::Solve Solve; + typedef AlgebraicFunctors::Sign_at Sign_at; + typedef AlgebraicFunctors::X_critical_points X_critical_points; + typedef AlgebraicFunctors::Y_critical_points Y_critical_points; + typedef AlgebraicFunctors::Compare_x Compare_x; + typedef AlgebraicFunctors::Compare_y Compare_y; + typedef AlgebraicFunctors::Compare_xy Compare_xy; + + Construct_polynomial_1_2 + construct_polynomial_1_2_object() const + { return Construct_polynomial_1_2(); } + + Construct_polynomial_for_circles_2_2 + construct_polynomial_for_circles_2_2_object() const + { return Construct_polynomial_for_circles_2_2(); } + + Solve solve_object() const + { return Solve(); } + + Sign_at sign_at_object() const + { return Sign_at(); } + + X_critical_points x_critical_points_object() const + { return X_critical_points(); } + + Y_critical_points y_critical_points_object() const + { return Y_critical_points(); } + + Compare_x compare_x_object() const + { return Compare_x(); } + + Compare_y compare_y_object() const + { return Compare_y(); } + + Compare_xy compare_xy_object() const + { return Compare_xy(); } + + }; + +} //namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_2_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Polynomials_1_2.h b/Algebraic_kernel_for_circles/include/CGAL/Polynomials_1_2.h new file mode 100644 index 00000000000..5aa5884aac6 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Polynomials_1_2.h @@ -0,0 +1,68 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_POLYNOMIALS_1_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_POLYNOMIALS_1_2_H + +#include + + +#include + +namespace CGAL { + +template < typename RT_ > +class Polynomial_1_2 +{ + RT_ rep[3]; // stores a, b, c for line ax+by+c=0 + +public: + + typedef RT_ RT; + + Polynomial_1_2(){} + + Polynomial_1_2(const RT & a, const RT & b, const RT & c) + { + rep[0]=a; + rep[1]=b; + rep[2]=c; + } + + const RT & a() const + { return rep[0]; } + + const RT & b() const + { return rep[1]; } + + const RT & c() const + { return rep[2]; } +}; + +template < typename RT > +bool +operator == ( const Polynomial_1_2 & p1, + const Polynomial_1_2 & p2 ) +{ + return( (p1.a() == p2.a()) && + (p1.b() == p2.b()) && + (p1.c() == p2.c()) ); +} + +} //namespace CGAL + +#endif //CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_POLYNOMIALS_1_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Polynomials_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Polynomials_2_2.h new file mode 100644 index 00000000000..80e64656062 --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Polynomials_2_2.h @@ -0,0 +1,71 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_POLYNOMIALS_2_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_POLYNOMIALS_2_2_H + +#include + + +//////////// FIXME - pb RT (cas general Polynomial_2_2) ou FT (ici) + +#include + +namespace CGAL { + +// polynomials of the form (X-a)^2 + (Y-b)^2 - R^2 +template < typename FT_ > +class Polynomial_for_circles_2_2 +{ + FT_ rep[3]; // stores a, b, R^2 + +public: + + typedef FT_ FT; + + Polynomial_for_circles_2_2(){} + + Polynomial_for_circles_2_2(const FT & a, const FT & b, const FT & rsq) + { + rep[0]=a; + rep[1]=b; + rep[2]=rsq; + } + + const FT & a() const + { return rep[0]; } + + const FT & b() const + { return rep[1]; } + + const FT & r_sq() const + { return rep[2]; } +}; + +template < typename FT > +bool +operator == ( const Polynomial_for_circles_2_2 & p1, + const Polynomial_for_circles_2_2 & p2 ) +{ + return( (p1.a() == p2.a()) && + (p1.b() == p2.b()) && + (p1.r_sq() == p2.r_sq()) ); +} + +} //namespace CGAL + +#endif //CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_POLYNOMIALS_2_2_H diff --git a/Algebraic_kernel_for_circles/include/CGAL/Root_for_circles_2_2.h b/Algebraic_kernel_for_circles/include/CGAL/Root_for_circles_2_2.h new file mode 100644 index 00000000000..bb2b92d350d --- /dev/null +++ b/Algebraic_kernel_for_circles/include/CGAL/Root_for_circles_2_2.h @@ -0,0 +1,132 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Monique Teillaud, Sylvain Pion + +// Partially supported by the IST Programme of the EU as a Shared-cost +// RTD (FET Open) Project under Contract No IST-2000-26473 +// (ECG - Effective Computational Geometry for Curves and Surfaces) +// and a STREP (FET Open) Project under Contract No IST-006413 +// (ACS -- Algorithms for Complex Shapes) + +#ifndef CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_ROOT_FOR_CIRCLES_2_2_H +#define CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_ROOT_FOR_CIRCLES_2_2_H + +#include + + +#include +#include +#include +#include +#include + +namespace CGAL { + +template < typename RT_ > +class Root_for_circles_2_2 { + + typedef RT_ RT; + typedef typename Root_of_traits< RT >::RootOf_2 Root_of_2; + typedef typename Root_of_traits< RT >::RootOf_1 FT; + + private: + Handle_for x_; + Handle_for y_; + + public: + Root_for_circles_2_2(){} + + Root_for_circles_2_2(const Root_of_2& r1, const Root_of_2& r2) + : x_(r1), y_(r2) + { + // When it is an interval this assertion dont compile + //CGAL_assertion((r1.is_rational() || r2.is_rational()) || + // (r1.gamma() == r2.gamma())); + } + + const Root_of_2& x() const + { return get_pointee_or_identity(x_); } + + const Root_of_2& y() const + { return get_pointee_or_identity(y_); } + + CGAL::Bbox_2 bbox() const + { + CGAL::Interval_nt<> + ix=to_interval(x()), + iy=to_interval(y()); + return CGAL::Bbox_2(ix.inf(),iy.inf(), + ix.sup(),iy.sup()); + /* + const Root_of_2 &ox = x(); + const Root_of_2 &oy = y(); + + if(ox.is_rational() || oy.is_rational()) { + CGAL::Interval_nt<> + ix=to_interval(ox), + iy=to_interval(oy); + return CGAL::Bbox_2(ix.inf(),iy.inf(), + ix.sup(),iy.sup()); + } + + // delta must be the same + // WE HAVE TO TEST THE EXECUTION TIME + // IT STILL NOT POSSIBLE BECAUSE OF THE + // PROBLEM ON THE ARRANGEMENT + // (it is very likely to make it better with this changing) + const CGAL::Interval_nt alpha1 = to_interval(ox.alpha()); + const CGAL::Interval_nt beta1 = to_interval(ox.beta()); + const CGAL::Interval_nt alpha2 = to_interval(oy.alpha()); + const CGAL::Interval_nt beta2 = to_interval(oy.beta()); + const CGAL::Interval_nt g = to_interval(ox.gamma()); + const CGAL::Interval_nt sqrtg = CGAL::sqrt(g); + const CGAL::Interval_nt ix = alpha1 + beta1 * sqrtg; + const CGAL::Interval_nt iy = alpha2 + beta2 * sqrtg; + return CGAL::Bbox_2(ix.inf(),iy.inf(), + ix.sup(),iy.sup()); + */ + } + + template < typename RT > + friend bool operator == ( const Root_for_circles_2_2& r1, + const Root_for_circles_2_2& r2 ); + +}; + +template < typename RT > +bool +operator == ( const Root_for_circles_2_2& r1, + const Root_for_circles_2_2& r2 ) +{ if (CGAL::identical(r1.x_, r2.x_) && CGAL::identical(r1.y_, r2.y_)) + return true; + return (r1.x() == r2.x()) && (r1.y() == r2.y()); +} + +template < typename RT > +std::ostream & +operator<<(std::ostream & os, const Root_for_circles_2_2 &r) +{ return os << r.x() << " " << r.y() << " "; } + +template < typename RT > +std::istream & +operator>>(std::istream & is, Root_for_circles_2_2 &r) +{ + typedef typename Root_of_traits< RT >::RootOf_2 Root_of_2; + Root_of_2 x,y; + + is >> x >> y; + if(is) + r = Root_for_circles_2_2(x,y); + return is; +} + +} //namespace CGAL + +#endif // CGAL_ALGEBRAIC_KERNEL_FOR_CIRCLES_ROOT_FOR_CIRCLES_2_2_H diff --git a/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/copyright b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/copyright new file mode 100644 index 00000000000..8932b3233d2 --- /dev/null +++ b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/copyright @@ -0,0 +1,2 @@ +INRIA Sophia-Antipolis (France) + diff --git a/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies new file mode 100644 index 00000000000..8d3b893eeb2 --- /dev/null +++ b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/dependencies @@ -0,0 +1,12 @@ +Algebraic_foundations +Algebraic_kernel_for_circles +Arithmetic_kernel +Filtered_kernel +Installation +Interval_support +Kernel_23 +Modular_arithmetic +Number_types +Profiling_tools +STL_Extension +Stream_support diff --git a/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/license.txt b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/license.txt new file mode 100644 index 00000000000..8bb8efcb72b --- /dev/null +++ b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/license.txt @@ -0,0 +1 @@ +GPL (v3 or later) diff --git a/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/maintainer b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/maintainer new file mode 100644 index 00000000000..fec7225a53c --- /dev/null +++ b/Algebraic_kernel_for_circles/package_info/Algebraic_kernel_for_circles/maintainer @@ -0,0 +1 @@ +Monique Teillaud diff --git a/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/CMakeLists.txt b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/CMakeLists.txt new file mode 100644 index 00000000000..c02ce4ff14d --- /dev/null +++ b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/CMakeLists.txt @@ -0,0 +1,26 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + + +cmake_minimum_required(VERSION 3.1...3.15) +project( Algebraic_kernel_for_circles_Tests ) + + +find_package(CGAL QUIET) + +if ( CGAL_FOUND ) + + include_directories (BEFORE "include") + + # create a target per cppfile + file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + foreach(cppfile ${cppfiles}) + create_single_source_cgal_program( "${cppfile}" ) + endforeach() + +else() + + message(STATUS "This program requires the CGAL library, and will not be compiled.") + +endif() + diff --git a/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/include/CGAL/_test_constructor.h b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/include/CGAL/_test_constructor.h new file mode 100644 index 00000000000..8510d3fb696 --- /dev/null +++ b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/include/CGAL/_test_constructor.h @@ -0,0 +1,36 @@ +#include +#include + +template +void _test_constuctor(AK ak) +{ + CGAL::Random generatorOfgenerator; + int random_seed = generatorOfgenerator.get_int(0, 123456); + std::cout << "random_seed = " << random_seed << std::endl; + CGAL::Random theRandom(random_seed); + int random_max = 127; + int random_min = -127; + typename AK::Construct_polynomial_for_circles_2_2 theConstruct_2_2 = + ak.construct_polynomial_for_circles_2_2_object(); + typename AK::Construct_polynomial_1_2 theConstruct_1_2 = + ak.construct_polynomial_1_2_object(); + + for(int i = 0; i < 20 ; i++){ + int x = theRandom.get_int(random_min,random_max); + int y = theRandom.get_int(random_min,random_max); + int r_sq = theRandom.get_int(random_min,random_max); + int a = theRandom.get_int(random_min,random_max); + int b = theRandom.get_int(random_min,random_max); + int c = theRandom.get_int(random_min,random_max); + + typename AK::Polynomial_for_circles_2_2 p_2_2 = theConstruct_2_2(x, y, r_sq); + typename AK::Polynomial_1_2 p_1_2 = theConstruct_1_2(a, b, c); + assert(p_2_2.a() == x); + assert(p_2_2.b() == y); + assert(p_2_2.r_sq() == r_sq); + assert(p_1_2.a() == a); + assert(p_1_2.b() == b); + assert(p_1_2.c() == c); + } + +} diff --git a/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/include/CGAL/_test_predicates.h b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/include/CGAL/_test_predicates.h new file mode 100644 index 00000000000..211882addc9 --- /dev/null +++ b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/include/CGAL/_test_predicates.h @@ -0,0 +1,414 @@ +#include +#include + +template +void _test_solve(AK ak) +{ + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typename AK::Solve theSolve = + ak.solve_object(); + + //Polynomial_for_circles_2_2 + typename AK::Construct_polynomial_for_circles_2_2 theConstruct_2_2 = + ak.construct_polynomial_for_circles_2_2_object(); + + std::vector< std::pair > res1; + theSolve(theConstruct_2_2(5, 5, 25), + theConstruct_2_2(0, 5, 100), + std::back_inserter(res1)); + assert(res1.size() == 1); + assert(res1[0].second == 2u); + assert(res1[0].first == Root_for_circles_2_2(10, 5)); + + std::vector< std::pair > res2; + theSolve(theConstruct_2_2(-5, 5, 25), + theConstruct_2_2(0, 5, 100), + std::back_inserter(res2)); + assert(res2.size() == 1); + assert(res2[0].second == 2u); + assert(res2[0].first == Root_for_circles_2_2(-10, 5)); + + std::vector< std::pair > res3; + theSolve(theConstruct_2_2(0, 5, 25), + theConstruct_2_2(0, 0, 100), + std::back_inserter(res3)); + assert(res3.size() == 1); + assert(res3[0].second == 2u); + assert(res3[0].first == Root_for_circles_2_2(0, 10)); + + std::vector< std::pair > res4; + theSolve(theConstruct_2_2(0, -5, 25), + theConstruct_2_2(0, 0, 100), + std::back_inserter(res4)); + assert(res4.size() == 1); + assert(res4[0].second == 2u); + assert(res4[0].first == Root_for_circles_2_2(0, -10)); + + std::vector< std::pair > res5; + theSolve(theConstruct_2_2(-5, 5, 25), + theConstruct_2_2(0, 0, 25), + std::back_inserter(res5)); + assert(res5.size() == 2); + assert(res5[0].second == 1u); + assert(res5[0].first == Root_for_circles_2_2(-5, 0)); + assert(res5[1].second == 1u); + assert(res5[1].first == Root_for_circles_2_2(0, 5)); + + //Polynomial_1_2 Polynomial_for_circles_2_2 + typename AK::Construct_polynomial_1_2 theConstruct_1_2 = + ak.construct_polynomial_1_2_object(); + + //line horizontal in circle's center + std::vector< std::pair > res6; + theSolve(theConstruct_1_2(0, 1, -5), + theConstruct_2_2(0, 5, 100), + std::back_inserter(res6)); + assert(res6.size() == 2); + assert(res6[0].second == 1u); + assert(res6[0].first == Root_for_circles_2_2(-10, 5)); + assert(res6[1].second == 1u); + assert(res6[1].first == Root_for_circles_2_2(10, 5)); + + //line vertical in circle's center + std::vector< std::pair > res7; + theSolve(theConstruct_1_2(1, 0, -5), + theConstruct_2_2(5, 5, 100), + std::back_inserter(res7)); + assert(res7.size() == 2); + assert(res7[0].second == 1u); + assert(res7[0].first == Root_for_circles_2_2(5, -5)); + assert(res7[1].second == 1u); + assert(res7[1].first == Root_for_circles_2_2(5, 15)); + + //line vertical tangent left + std::vector< std::pair > res8; + theSolve(theConstruct_1_2(1, 0, 5), + theConstruct_2_2(5, 5, 100), + std::back_inserter(res8)); + assert(res8.size() == 1); + assert(res8[0].second == 2u); + assert(res8[0].first == Root_for_circles_2_2(-5, 5)); + + //line vertical tangent right + std::vector< std::pair > res9; + theSolve(theConstruct_1_2(1, 0, -15), + theConstruct_2_2(5, 5, 100), + std::back_inserter(res9)); + assert(res9.size() == 1); + assert(res9[0].second == 2u); + assert(res9[0].first == Root_for_circles_2_2(15, 5)); + + //line horizontal tangent on top + std::vector< std::pair > res10; + theSolve(theConstruct_1_2(0, 1, -15), + theConstruct_2_2(5, 5, 100), + std::back_inserter(res10)); + assert(res10.size() == 1); + assert(res10[0].second == 2u); + assert(res10[0].first == Root_for_circles_2_2(5, 15)); + + //line horizontal tangent down + std::vector< std::pair > res11; + theSolve(theConstruct_1_2(0, 1, 5), + theConstruct_2_2(5, 5, 100), + std::back_inserter(res11)); + assert(res11.size() == 1); + assert(res11[0].second == 2u); + assert(res11[0].first == Root_for_circles_2_2(5, -5)); + + + // only Polynomial_1_2 + std::vector< std::pair > res12; + theSolve(theConstruct_1_2(1, 1, -5), + theConstruct_1_2(1, -1, 5), + std::back_inserter(res12)); + assert(res12.size() == 1); + assert(res12[0].second == 1u); + assert(res12[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res13; + theSolve(theConstruct_1_2(0, 1, -5), + theConstruct_1_2(1, -1, 5), + std::back_inserter(res13)); + assert(res13.size() == 1); + assert(res13[0].second == 1u); + assert(res13[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res14; + theSolve(theConstruct_1_2(1, -1, 5), + theConstruct_1_2(0, 1, -5), + std::back_inserter(res14)); + assert(res14.size() == 1); + assert(res14[0].second == 1u); + assert(res14[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res15; + theSolve(theConstruct_1_2(1, 0, 0), + theConstruct_1_2(1, -1, 5), + std::back_inserter(res15)); + assert(res15.size() == 1); + assert(res15[0].second == 1u); + assert(res15[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res16; + theSolve(theConstruct_1_2(1, -1, 5), + theConstruct_1_2(1, 0, 0), + std::back_inserter(res16)); + assert(res16.size() == 1); + assert(res16[0].second == 1u); + assert(res16[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res17; + theSolve(theConstruct_1_2(0, 1, -5), + theConstruct_1_2(1, 0, 0), + std::back_inserter(res17)); + assert(res17.size() == 1); + assert(res17[0].second == 1u); + assert(res17[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res18; + theSolve(theConstruct_1_2(1, 0, 0), + theConstruct_1_2(0, 1, -5), + std::back_inserter(res18)); + assert(res18.size() == 1); + assert(res18[0].second == 1u); + assert(res18[0].first == Root_for_circles_2_2(0, 5)); + + std::vector< std::pair > res19; + theSolve(theConstruct_1_2(1, 0, 0), + theConstruct_1_2(1, 0, 0), + std::back_inserter(res19)); + assert(res19.size() == 0); + + std::vector< std::pair > res20; + theSolve(theConstruct_1_2(1, 0, 0), + theConstruct_1_2(1, 0, 5), + std::back_inserter(res20)); + assert(res20.size() == 0); + + + std::vector< std::pair > res21; + theSolve(theConstruct_1_2(0, 1, -5), + theConstruct_1_2(0, 1, -5), + std::back_inserter(res21)); + assert(res21.size() == 0); + + std::vector< std::pair > res22; + theSolve(theConstruct_1_2(0, 1, -5), + theConstruct_1_2(0, 1, 0), + std::back_inserter(res22)); + assert(res22.size() == 0); + + std::vector< std::pair > res23; + theSolve(theConstruct_1_2(1, -1, 5), + theConstruct_1_2(1, -1, 5), + std::back_inserter(res23)); + assert(res23.size() == 0); + + std::vector< std::pair > res24; + theSolve(theConstruct_1_2(1, -1, 5), + theConstruct_1_2(2, -2, 15), + std::back_inserter(res24)); + assert(res24.size() == 0); + + CGAL::Random generatorOfgenerator; + int random_seed = generatorOfgenerator.get_int(0, 123456); + std::cout << "random_seed = " << random_seed << std::endl; + CGAL::Random theRandom(random_seed); + int random_max = 5; + int random_min = -5; + + typename AK::Sign_at theSigh_at = + ak.sign_at_object(); + + for(std::size_t i = 0; i < 500; i++){ + int a1, b1, c1, a2, b2, c2, a3, b3, r_sq = 0; + do{ + a1 = theRandom.get_int(random_min,random_max); + b1 = theRandom.get_int(random_min,random_max); + }while((a1 == 0) && (b1 == 0)); + c1 = theRandom.get_int(random_min,random_max); + do{ + a2 = theRandom.get_int(random_min,random_max); + b2 = theRandom.get_int(random_min,random_max); + }while((a2 == 0) && (b2 == 0)); + c2 = theRandom.get_int(random_min,random_max); + a3 = theRandom.get_int(random_min,random_max); + b3 = theRandom.get_int(random_min,random_max); + r_sq = theRandom.get_int(1,random_max); + + std::vector< std::pair > res; + theSolve(theConstruct_1_2(a1, b1, c1), + theConstruct_1_2(a2, b2, c2), + std::back_inserter(res)); + std::vector< std::pair > res2; + theSolve(theConstruct_1_2(a2, b2, c2), + theConstruct_2_2(a3, b3, r_sq), + std::back_inserter(res2)); + std::vector< std::pair > res3; + theSolve(theConstruct_1_2(a1, b1, c1), + theConstruct_2_2(a3, b3, r_sq), + std::back_inserter(res3)); + for (std::size_t j = 0 ; j < res.size() ; j++){ + assert(res[j].second == 1u); + assert(theSigh_at(theConstruct_1_2(a1, b1, c1), + res[j].first) == CGAL::ZERO); + assert(theSigh_at(theConstruct_1_2(a2, b2, c2), + res[j].first) == CGAL::ZERO); + } + for (std::size_t j = 0 ; j < res2.size() ; j++){ + if(res2.size() == 1) assert(res2[j].second == 2u); + if(res2.size() == 2) assert(res2[j].second == 1u); + assert(theSigh_at(theConstruct_2_2(a3, b3, r_sq), + res2[j].first) == CGAL::ZERO); + assert(theSigh_at(theConstruct_1_2(a2, b2, c2), + res2[j].first) == CGAL::ZERO); + } + for (std::size_t j = 0 ; j < res3.size() ; j++){ + if(res3.size() == 1) assert(res3[j].second == 2u); + if(res3.size() == 2) assert(res3[j].second == 1u); + assert(theSigh_at(theConstruct_2_2(a3, b3, r_sq), + res3[j].first) == CGAL::ZERO); + assert(theSigh_at(theConstruct_1_2(a1, b1, c1), + res3[j].first) == CGAL::ZERO); + } + + } + +} + +template +void _test_sign_at(AK ak) +{ + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typename AK::Sign_at theSigh_at = + ak.sign_at_object(); + + //Polynomial_for_circles_2_2 + typename AK::Construct_polynomial_for_circles_2_2 theConstruct_2_2 = + ak.construct_polynomial_for_circles_2_2_object(); + + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(-5,5)) == CGAL::ZERO); + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(15,5)) == CGAL::ZERO); + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(5,15)) == CGAL::ZERO); + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(5,-5)) == CGAL::ZERO); + + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(5,5)) != CGAL::ZERO); + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(5,16)) != CGAL::ZERO); + assert(theSigh_at(theConstruct_2_2(5, 5, 100), + Root_for_circles_2_2(5,-6)) != CGAL::ZERO); + + //Polynomial_1_2 + typename AK::Construct_polynomial_1_2 theConstruct_1_2 = + ak.construct_polynomial_1_2_object(); + + assert(theSigh_at(theConstruct_1_2(1, 0, -5), + Root_for_circles_2_2(5,-6)) == CGAL::ZERO); + assert(theSigh_at(theConstruct_1_2(1, 0, -5), + Root_for_circles_2_2(6,-6)) != CGAL::ZERO); + assert(theSigh_at(theConstruct_1_2(0, 1, -5), + Root_for_circles_2_2(5,-6)) != CGAL::ZERO); + assert(theSigh_at(theConstruct_1_2(0, 1, -5), + Root_for_circles_2_2(5, 5)) == CGAL::ZERO); + +} + +template +void _test_critical_points(AK ak) +{ + CGAL::Random generatorOfgenerator; + int random_seed = generatorOfgenerator.get_int(0, 123456); + std::cout << "random_seed = " << random_seed << std::endl; + CGAL::Random theRandom(random_seed); + int random_max = 127; + int random_min = -127; + + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + typename AK::Construct_polynomial_for_circles_2_2 theConstruct_2_2 = + ak.construct_polynomial_for_circles_2_2_object(); + typename AK::X_critical_points theX_critical_points = + ak.x_critical_points_object(); + + typename AK::Y_critical_points theY_critical_points = + ak.y_critical_points_object(); + + for(int i = 0; i < 20; i++){ + int x = theRandom.get_int(random_min,random_max); + int y = theRandom.get_int(random_min,random_max); + int r = theRandom.get_int(1,random_max); + + assert(theX_critical_points(theConstruct_2_2(x,y,r*r),true) + == Root_for_circles_2_2(x - r, y)); + assert(theX_critical_points(theConstruct_2_2(x,y,r*r),false) + == Root_for_circles_2_2(x + r, y)); + assert(theY_critical_points(theConstruct_2_2(x,y,r*r),true) + == Root_for_circles_2_2(x, y - r)); + assert(theY_critical_points(theConstruct_2_2(x,y,r*r),false) + == Root_for_circles_2_2(x, y + r)); + } + +} + +template +void _test_compare_Root_for_circles(AK ak) +{ + CGAL::Random generatorOfgenerator; + int random_seed = generatorOfgenerator.get_int(0, 123456); + std::cout << "random_seed = " << random_seed << std::endl; + CGAL::Random theRandom(random_seed); + int random_max = 127; + int random_min = -127; + + typedef typename AK::Root_for_circles_2_2 Root_for_circles_2_2; + + typename AK::Compare_x theCompare_x = + ak.compare_x_object(); + + typename AK::Compare_y theCompare_y = + ak.compare_y_object(); + + typename AK::Compare_xy theCompare_xy = + ak.compare_xy_object(); + + for (int i = 0; i < 20; i++){ + Root_for_circles_2_2 r1(theRandom.get_int(random_min,random_max), + theRandom.get_int(random_min,random_max)); + Root_for_circles_2_2 r2(theRandom.get_int(random_min,random_max), + theRandom.get_int(random_min,random_max)); + if(r1.x() > r2.x()){ + assert(theCompare_x(r1, r2) == CGAL::LARGER); + assert(theCompare_xy(r1, r2) == CGAL::LARGER); + } + else if(r1.x() == r2.x()){ + assert(theCompare_x(r1, r2) == CGAL::EQUAL); + if(r1.y() < r2.y()){ + assert(theCompare_y(r1, r2) == CGAL::SMALLER); + assert(theCompare_xy(r1, r2) == CGAL::SMALLER); + } + else if(r1.y() > r2.y()){ + assert(theCompare_y(r1, r2) == CGAL::LARGER); + assert(theCompare_xy(r1, r2) == CGAL::LARGER); + } + else { + assert(theCompare_y(r1, r2) == CGAL::EQUAL); + assert(theCompare_xy(r1, r2) == CGAL::EQUAL); + } + } + else { + assert(theCompare_x(r1, r2) == CGAL::SMALLER); + assert(theCompare_xy(r1, r2) == CGAL::SMALLER); + } + if(r1.y() > r2.y()) + assert(theCompare_y(r1, r2) == CGAL::LARGER); + else if(r1.y() < r2.y()) + assert(theCompare_y(r1, r2) == CGAL::SMALLER); + else + assert(theCompare_y(r1, r2) == CGAL::EQUAL); + } +} diff --git a/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/test_Algebraic_kernel.cpp b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/test_Algebraic_kernel.cpp new file mode 100644 index 00000000000..f46dc0af420 --- /dev/null +++ b/Algebraic_kernel_for_circles/test/Algebraic_kernel_for_circles/test_Algebraic_kernel.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include +#include + +int main() +{ + typedef CGAL::Quotient NT1; + typedef CGAL::Algebraic_kernel_for_circles_2_2 Algebraic_k1; + Algebraic_k1 ak1; + _test_solve(ak1); + _test_sign_at(ak1); + _test_critical_points(ak1); + _test_compare_Root_for_circles(ak1); + _test_constuctor(ak1); + + return 0; +} diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt index 2bed310a6e0..21a67c6a7a7 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt @@ -19,7 +19,6 @@ find_package( Qt5 QUIET COMPONENTS Gui Widgets) if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND CGAL_Core_FOUND) include(${CGAL_USE_FILE}) - include_directories( ./ ) # Arrangement package includes add_definitions(-DQT_NO_KEYWORDS) diff --git a/BGL/examples/BGL_polyhedron_3/CMakeLists.txt b/BGL/examples/BGL_polyhedron_3/CMakeLists.txt index 01378916001..61216b99fdf 100644 --- a/BGL/examples/BGL_polyhedron_3/CMakeLists.txt +++ b/BGL/examples/BGL_polyhedron_3/CMakeLists.txt @@ -27,23 +27,6 @@ if ( NOT Boost_FOUND ) endif() -find_package( OpenMesh QUIET ) - -if ( OpenMesh_FOUND ) - include( UseOpenMesh ) - add_definitions( -DCGAL_USE_OPENMESH ) -else() - message(STATUS "Examples that use OpenMesh will not be compiled.") -endif() - -find_package( METIS ) - -if( METIS_FOUND ) - include_directories(${METIS_INCLUDE_DIRS} ) -else() - message( STATUS "Examples that use the METIS library will not be compiled." ) -endif() - # include for local directory # include for local package @@ -67,12 +50,24 @@ create_single_source_cgal_program( "transform_iterator.cpp" ) create_single_source_cgal_program( "copy_polyhedron.cpp" ) -if(OpenMesh_FOUND) +find_package( OpenMesh QUIET ) + +if ( OpenMesh_FOUND ) + include( UseOpenMesh ) + target_compile_definitions( copy_polyhedron PRIVATE -DCGAL_USE_OPENMESH ) target_link_libraries( copy_polyhedron PRIVATE ${OPENMESH_LIBRARIES} ) +else() + message(STATUS "Examples that use OpenMesh will not be compiled.") endif() +find_package( METIS ) if( METIS_FOUND ) create_single_source_cgal_program( "polyhedron_partition.cpp" ) - target_link_libraries( polyhedron_partition PRIVATE ${METIS_LIBRARIES} ) + if( METIS_FOUND ) + target_include_directories( polyhedron_partition PRIVATE ${METIS_INCLUDE_DIRS} ) + target_link_libraries( polyhedron_partition PRIVATE ${METIS_LIBRARIES} ) + else() + message( STATUS "Examples that use the METIS library will not be compiled." ) + endif() endif() diff --git a/BGL/examples/BGL_surface_mesh/CMakeLists.txt b/BGL/examples/BGL_surface_mesh/CMakeLists.txt index 13ba8575799..c545ffa17da 100644 --- a/BGL/examples/BGL_surface_mesh/CMakeLists.txt +++ b/BGL/examples/BGL_surface_mesh/CMakeLists.txt @@ -21,9 +21,9 @@ create_single_source_cgal_program( "connected_components.cpp" ) find_package( METIS ) if( METIS_FOUND ) - include_directories(${METIS_INCLUDE_DIRS} ) create_single_source_cgal_program( "surface_mesh_partition.cpp" ) + target_include_directories( surface_mesh_partition PRIVATE ${METIS_INCLUDE_DIRS} ) target_link_libraries( surface_mesh_partition PRIVATE ${METIS_LIBRARIES} ) else() message( STATUS "Examples that use the METIS library will not be compiled." ) diff --git a/CGAL_ipelets/demo/CGAL_ipelets/CMakeLists.txt b/CGAL_ipelets/demo/CGAL_ipelets/CMakeLists.txt index 6e6749d8619..fb13cb1e124 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/CMakeLists.txt +++ b/CGAL_ipelets/demo/CGAL_ipelets/CMakeLists.txt @@ -36,8 +36,6 @@ if ( CGAL_FOUND ) find_package(IPE 6) if ( IPE_FOUND ) - include_directories(BEFORE ${IPE_INCLUDE_DIR}) - if (${IPE_VERSION} EQUAL "7") set(WITH_IPE_7 ON) elseif(${IPE_VERSION} EQUAL "6") @@ -66,10 +64,6 @@ if ( CGAL_FOUND ) endif() if ( IPE_FOUND AND IPE_VERSION) - if (WITH_IPE_7) - add_definitions(-DCGAL_USE_IPE_7) - endif() - message("-- Using IPE version ${IPE_VERSION} compatibility.") #setting installation directory @@ -140,6 +134,11 @@ if ( CGAL_FOUND ) foreach(IPELET ${CGAL_IPELETS}) add_library(CGAL_${IPELET} MODULE ${IPELET}.cpp) + target_include_directories(CGAL_${IPELET} BEFORE PRIVATE ${IPE_INCLUDE_DIR}) + if (WITH_IPE_7) + target_compile_definitions(CGAL_${IPELET} PRIVATE CGAL_USE_IPE_7) + endif() + add_to_cached_list(CGAL_EXECUTABLE_TARGETS CGAL_${IPELET}) target_link_libraries(CGAL_${IPELET} PRIVATE CGAL::CGAL CGAL::Eigen_support ${IPE_LIBRARIES}) if ( IPELET_INSTALL_DIR ) @@ -152,11 +151,19 @@ if ( CGAL_FOUND ) endforeach(IPELET) if(CGAL_Core_FOUND) target_link_libraries(CGAL_cone_spanners PRIVATE CGAL::CGAL_Core CGAL::Eigen_support) + target_include_directories(CGAL_cone_spanners BEFORE PRIVATE ${IPE_INCLUDE_DIR}) + if (WITH_IPE_7) + target_compile_definitions(CGAL_cone_spanners PRIVATE CGAL_USE_IPE_7) + endif() endif() #example in doc not installed add_library(simple_triangulation MODULE simple_triangulation.cpp) add_to_cached_list(CGAL_EXECUTABLE_TARGETS simple_triangulation) target_link_libraries(simple_triangulation CGAL::Eigen_support ${IPE_LIBRARIES}) + target_include_directories(simple_triangulation BEFORE PRIVATE ${IPE_INCLUDE_DIR}) + if (WITH_IPE_7) + target_compile_definitions(simple_triangulation PRIVATE CGAL_USE_IPE_7) + endif() cgal_add_compilation_test(simple_triangulation) else() diff --git a/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt b/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt index 61dd2e41455..0f54382257e 100644 --- a/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt +++ b/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt @@ -18,7 +18,6 @@ find_package(LEDA QUIET) find_package(Qt5 QUIET COMPONENTS OpenGL Gui) if(CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND (CGAL_Core_FOUND OR LEDA_FOUND)) - include_directories( BEFORE ./ ./include ) # ui files, created with Qt Designer qt5_wrap_ui( UIS HDT2.ui ) diff --git a/Installation/cmake/modules/UseCGAL.cmake b/Installation/cmake/modules/UseCGAL.cmake index aa79191bbbd..47e8335c364 100644 --- a/Installation/cmake/modules/UseCGAL.cmake +++ b/Installation/cmake/modules/UseCGAL.cmake @@ -28,7 +28,7 @@ if(NOT USE_CGAL_FILE_INCLUDED) endforeach() - include_directories( "${CMAKE_CURRENT_BINARY_DIR}" ) + target_include_directories(CGAL INTERFACE "${CMAKE_CURRENT_BINARY_DIR}" ) if(TARGET CGAL::CGAL) add_to_list( CGAL_LIBRARIES CGAL::CGAL ) @@ -38,15 +38,7 @@ if(NOT USE_CGAL_FILE_INCLUDED) add_to_list( CGAL_LIBRARIES ${CGAL_LIBRARY} ) endif() - #message (STATUS "LIB: ${CGAL_LIBRARY}") - #message (STATUS "LIBS: ${CGAL_LIBRARIES}") - - include_directories ( ${CGAL_INCLUDE_DIRS}) - include_directories ( SYSTEM ${CGAL_3RD_PARTY_INCLUDE_DIRS} ) - add_definitions ( ${CGAL_3RD_PARTY_DEFINITIONS} ${CGAL_DEFINITIONS} ) - - if(NOT CGAL_NO_BLANKET_LINKING) - link_directories ( ${CGAL_3RD_PARTY_LIBRARIES_DIRS} ) - link_libraries ( ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) - endif() + target_include_directories (CGAL INTERFACE ${CGAL_INCLUDE_DIRS}) + target_include_directories (CGAL SYSTEM INTERFACE ${CGAL_3RD_PARTY_INCLUDE_DIRS} ) + target_compile_definitions (CGAL INTERFACE ${CGAL_3RD_PARTY_DEFINITIONS} ${CGAL_DEFINITIONS} ) endif()