// Copyright (c) 1999 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Homogeneous_kernel/include/CGAL/Homogeneous/CircleH2.h $ // $Id: CircleH2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Sven Schoenherr // Stefan Schirra #ifndef CGAL_CIRCLEH2_H #define CGAL_CIRCLEH2_H #include #include namespace CGAL { template class CircleH2 { typedef typename R_::FT FT; typedef typename R_::RT RT; typedef typename R_::Point_2 Point_2; typedef boost::tuple Rep; typedef typename R_::template Handle::type Base; Base base; public: typedef R_ R; CircleH2() {} CircleH2(const Point_2& p, const Point_2& q, const Point_2& r) { Orientation o = CGAL::orientation( p, q, r); CGAL_kernel_precondition( o != COLLINEAR); Point_2 cp = circumcenter( p, q, r); FT sq_r = squared_distance( p, cp); base = Rep(cp, sq_r, o); } CircleH2(const Point_2& p, const Point_2& q, const Orientation& o) { CGAL_kernel_precondition( o != COLLINEAR); if ( p != q) { Point_2 cp = midpoint( p, q); FT sq_r = squared_distance( cp, p); base = Rep(cp, sq_r, o); } else base = Rep(p, FT( 0), o); } CircleH2(const Point_2& cp, const FT& squared_radius, const Orientation& o) { CGAL_precondition( ( ! CGAL_NTS is_negative( squared_radius)) && ( o != COLLINEAR ) ); base = Rep(cp, squared_radius, o); } const Point_2 & center() const; Orientation orientation() const; const FT & squared_radius() const; CircleH2 opposite() const; Oriented_side oriented_side(const Point_2& ) const; Bounded_side bounded_side(const Point_2& ) const; bool operator==( const CircleH2& ) const; bool operator!=( const CircleH2& ) const; bool has_on_positive_side(const Point_2& ) const; bool has_on_negative_side(const Point_2& ) const; bool has_on_boundary( const Point_2& ) const; bool has_on_bounded_side( const Point_2& ) const; bool has_on_unbounded_side(const Point_2&) const; bool is_degenerate() const; // bool oriented_equal( const CircleH2& ) const; // bool unoriented_equal( const CircleH2& ) const; }; template inline const typename CircleH2::Point_2 & CircleH2::center() const { return get_pointee_or_identity(base).template get<0>(); } template inline const typename CircleH2::FT & CircleH2::squared_radius() const { return get_pointee_or_identity(base).template get<1>(); } template CGAL_KERNEL_INLINE CircleH2 CircleH2::opposite() const { return CircleH2( center(), squared_radius(), CGAL::opposite( orientation() ) ); } template inline Orientation CircleH2::orientation() const { return get_pointee_or_identity(base).template get<2>(); } template CGAL_KERNEL_INLINE Oriented_side CircleH2::oriented_side( const typename CircleH2::Point_2& p) const { FT sq_dist = squared_distance( p, center() ); FT sq_rad = squared_radius(); Comparison_result vgl = CGAL_NTS compare( sq_dist, sq_rad ); Oriented_side rel_pos = (vgl == LARGER ) ? ON_NEGATIVE_SIDE : ( (vgl == SMALLER ) ? ON_POSITIVE_SIDE : ON_ORIENTED_BOUNDARY); if (orientation() == POSITIVE) { return rel_pos; } else // NEGATIVE { return CGAL::opposite( rel_pos ); } } template CGAL_KERNEL_INLINE bool CircleH2::has_on_positive_side(const typename CircleH2::Point_2& p) const { if ( orientation() == POSITIVE ) { return (has_on_bounded_side(p) ); } else { return (has_on_unbounded_side(p) ); } } template CGAL_KERNEL_INLINE bool CircleH2::has_on_boundary(const typename CircleH2::Point_2& p) const { FT sq_dist = squared_distance( p, center() ); FT sq_rad = squared_radius(); return ( sq_dist == sq_rad ); } template CGAL_KERNEL_INLINE bool CircleH2::has_on_negative_side( const typename CircleH2::Point_2&p) const { if ( orientation() == NEGATIVE ) { return (has_on_bounded_side(p) ); } else { return (has_on_unbounded_side(p) ); } } template CGAL_KERNEL_INLINE Bounded_side CircleH2::bounded_side(const typename CircleH2::Point_2& p) const { FT sq_dist = squared_distance( p, center() ); FT sq_rad = squared_radius(); Comparison_result vgl = CGAL_NTS compare( sq_dist, sq_rad ); return (vgl == LARGER ) ? ON_UNBOUNDED_SIDE : ( (vgl == SMALLER ) ? ON_BOUNDED_SIDE : ON_BOUNDARY); } template CGAL_KERNEL_INLINE bool CircleH2::has_on_bounded_side(const typename CircleH2::Point_2& p) const { FT sq_dist = squared_distance( p, center() ); FT sq_rad = squared_radius(); return ( sq_dist < sq_rad ); } template CGAL_KERNEL_INLINE bool CircleH2::has_on_unbounded_side(const typename CircleH2::Point_2&p) const { FT sq_dist = squared_distance( p, center() ); FT sq_rad = squared_radius(); return ( sq_rad < sq_dist ); } template inline bool CircleH2::is_degenerate() const { return ( squared_radius() == FT(0) ); } template CGAL_KERNEL_INLINE bool CircleH2::operator==(const CircleH2& c) const { return ( center() == c.center() ) &&( squared_radius() == c.squared_radius() ) &&( orientation() == c.orientation() ); } template inline bool CircleH2::operator!=(const CircleH2& c) const { return !(*this == c); } } //namespace CGAL #endif // CGAL_CIRCLEH2_H