// Copyright (c) 1997-2001 Freie Universitaet Berlin (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Sven Schoenherr , Bernd Gaertner #ifndef CGAL_MIN_CIRCLE_2_ADAPTERH2_H #define CGAL_MIN_CIRCLE_2_ADAPTERH2_H // includes #ifndef CGAL_OPTIMISATION_BASIC_H # include #endif CGAL_BEGIN_NAMESPACE // Class declarations // ================== template < class Traits_ > class Min_circle_2; template < class PT_, class DA_ > class Min_circle_2_adapterH2; template < class PT_, class DA_ > class _Min_circle_2_adapterH2__Circle; // Class interface and implementation // ================================== template < class PT_, class DA_ > class Min_circle_2_adapterH2 { public: // types typedef PT_ PT; typedef DA_ DA; // nested types typedef PT Point; typedef CGAL::_Min_circle_2_adapterH2__Circle Circle; private: DA dao; // data accessor object Circle circle; // current circle friend class CGAL::Min_circle_2< CGAL::Min_circle_2_adapterH2 >; public: // creation Min_circle_2_adapterH2( const DA& da = DA()) : dao( da), circle( da) { } // operations CGAL::Orientation orientation( const Point& p, const Point& q, const Point& r) const { typedef typename DA_::RT RT; RT phx; RT phy; RT phw; RT qhx; RT qhy; RT qhw; RT rhx; RT rhy; RT rhw; dao.get( p, phx, phy, phw); dao.get( q, qhx, qhy, qhw); dao.get( r, rhx, rhy, rhw); return( static_cast< CGAL::Orientation>( CGAL_NTS sign( ( phx*rhw - rhx*phw) * ( qhy*rhw - rhy*qhw) - ( phy*rhw - rhy*phw) * ( qhx*rhw - rhx*qhw)))); } }; // Nested type `Circle' template < class PT_, class DA_ > std::ostream& operator << ( std::ostream&, const CGAL::_Min_circle_2_adapterH2__Circle&); template < class PT_, class DA_ > std::istream& operator >> ( std::istream&, CGAL::_Min_circle_2_adapterH2__Circle&); template < class PT_, class DA_ > class _Min_circle_2_adapterH2__Circle { public: // typedefs typedef PT_ PT; typedef DA_ DA; typedef typename DA_::RT RT; typedef CGAL::Quotient FT; private: // data members DA dao; // data accessor object RT center_hx; // center's hx-coordinate RT center_hy; // center's hy-coordinate RT center_hw; // center's hw-coordinate FT sqr_rad; // squared radius // private member functions FT sqr_dist( const RT& phx, const RT& phy, const RT& phw, const RT& qhx, const RT& qhy, const RT& qhw) const { RT dhx( phx*qhw - qhx*phw); RT dhy( phy*qhw - qhy*phw); RT dhw( phw*qhw); return( FT( dhx*dhx + dhy*dhy, dhw*dhw)); } friend std::ostream& operator << <> ( std::ostream&, const CGAL::_Min_circle_2_adapterH2__Circle&); friend std::istream& operator >> <> ( std::istream&, CGAL::_Min_circle_2_adapterH2__Circle&); public: // types typedef PT Point; typedef FT Distance; // creation _Min_circle_2_adapterH2__Circle( const DA& da) : dao( da) { } void set( ) { center_hx = RT( 0); center_hy = RT( 0); center_hw = RT( 1); sqr_rad = -FT( 1); } void set( const Point& p) { dao.get( p, center_hx, center_hy, center_hw); sqr_rad = FT( 0); } void set( const Point& p, const Point& q) { RT phx; RT phy; RT phw; RT qhx; RT qhy; RT qhw; dao.get( p, phx, phy, phw); dao.get( q, qhx, qhy, qhw); center_hx = ( phx*qhw + qhx*phw); center_hy = ( phy*qhw + qhy*phw); center_hw = ( phw*qhw * RT( 2)); sqr_rad = sqr_dist( phx, phy, phw, center_hx, center_hy, center_hw); } void set( const Point& p, const Point& q, const Point& r) { RT phx; RT phy; RT phw; RT qhx; RT qhy; RT qhw; RT rhx; RT rhy; RT rhw; dao.get( p, phx, phy, phw); dao.get( q, qhx, qhy, qhw); dao.get( r, rhx, rhy, rhw); RT qhx_phx( qhx*phw - phx*qhw); RT qhy_phy( qhy*phw - phy*qhw); // denominator: qhw*phw RT rhx_phx( rhx*phw - phx*rhw); RT rhy_phy( rhy*phw - phy*rhw); // denominator: rhw*phw RT phw2( phw*phw); RT qhw2( qhw*qhw); RT rhw2( rhw*rhw); RT p2( phx*phx + phy*phy); // denominator: phw2 RT q2_p2( ( qhx*qhx + qhy*qhy) * phw2 - p2 * qhw2); // denominator: qhw2*phw2 RT r2_p2( ( rhx*rhx + rhy*rhy) * phw2 - p2 * rhw2); // denominator: rhw2*phw2 center_hx = q2_p2*rhy_phy * rhw - r2_p2*qhy_phy * qhw; center_hy = r2_p2*qhx_phx * qhw - q2_p2*rhx_phx * rhw; center_hw = ( qhx_phx*rhy_phy - rhx_phx*qhy_phy) * phw*qhw*rhw * RT( 2); sqr_rad = sqr_dist( phx, phy, phw, center_hx, center_hy, center_hw); } // predicates CGAL::Bounded_side bounded_side( const Point& p) const { RT phx; RT phy; RT phw; dao.get( p, phx, phy, phw); return( CGAL::Bounded_side( CGAL_NTS sign( sqr_rad - sqr_dist( phx, phy, phw, center_hx, center_hy, center_hw)))); } bool has_on_bounded_side( const Point& p) const { RT phx; RT phy; RT phw; dao.get( p, phx, phy, phw); return( sqr_dist( phx, phy, phw, center_hx, center_hy, center_hw) < sqr_rad); } bool has_on_boundary( const Point& p) const { RT phx; RT phy; RT phw; dao.get( p, phx, phy, phw); return( sqr_dist( phx, phy, phw, center_hx, center_hy, center_hw) == sqr_rad); } bool has_on_unbounded_side( const Point& p) const { RT phx; RT phy; RT phw; dao.get( p, phx, phy, phw); return( sqr_rad < sqr_dist( phx, phy, phw, center_hx, center_hy, center_hw)); } bool is_empty( ) const { return( CGAL::is_negative( sqr_rad)); } bool is_degenerate( ) const { return( ! CGAL::is_positive( sqr_rad)); } // additional operations for checking bool operator == ( const CGAL::_Min_circle_2_adapterH2__Circle& c) const { return( ( center_hx*c.center_hw == c.center_hx*center_hw) && ( center_hy*c.center_hw == c.center_hy*center_hw) && ( sqr_rad == c.sqr_rad ) ); } bool operator != ( const CGAL::_Min_circle_2_adapterH2__Circle& c) const { return( ! ( *this == c)); } Point center( ) const { Point p; dao.set( p, center_hx, center_hy, center_hw); return( p); } const Distance& squared_radius( ) const { return( sqr_rad); } }; // I/O template < class PT_, class DA_ > std::ostream& operator << ( std::ostream& os, const CGAL::_Min_circle_2_adapterH2__Circle& c) { switch ( CGAL::get_mode( os)) { case CGAL::IO::PRETTY: os << "CGAL::Min_circle_2_adapterH2::Circle( " << c.center_hx << ", " << c.center_hy << ", " << c.center_hw << ", " << c.sqr_rad << ')'; break; case CGAL::IO::ASCII: os << c.center_hx << ' ' << c.center_hy << ' ' << c.center_hw << ' ' << c.sqr_rad; break; case CGAL::IO::BINARY: CGAL::write( os, c.center_hx); CGAL::write( os, c.center_hy); CGAL::write( os, c.center_hw); CGAL::write( os, c.sqr_rad); break; default: CGAL_optimisation_assertion_msg( false, "CGAL::get_mode( os) invalid!"); break; } return( os); } template < class PT_, class DA_ > std::istream& operator >> ( std::istream& is, CGAL::_Min_circle_2_adapterH2__Circle& c) { switch ( CGAL::get_mode( is)) { case CGAL::IO::PRETTY: std::cerr << std::endl; std::cerr << "Stream must be in ascii or binary mode" << std::endl; break; case CGAL::IO::ASCII: is >> c.center_hx >> c.center_hy >> c.center_hw >> c.sqr_rad; break; case CGAL::IO::BINARY: CGAL::read( is, c.center_hx); CGAL::read( is, c.center_hy); CGAL::read( is, c.center_hw); CGAL::read( is, c.sqr_rad); break; default: CGAL_optimisation_assertion_msg( false, "CGAL::IO::mode invalid!"); break; } return( is); } CGAL_END_NAMESPACE #endif // CGAL_MIN_CIRCLE_2_ADAPTERH2_H // ===== EOF ==================================================================