// 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_ADAPTERC2_H #define CGAL_MIN_CIRCLE_2_ADAPTERC2_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_adapterC2; template < class PT_, class DA_ > class _Min_circle_2_adapterC2__Circle; // Class interface and implementation // ================================== template < class PT_, class DA_ > class Min_circle_2_adapterC2 { public: // types typedef PT_ PT; typedef DA_ DA; // nested types typedef PT Point; typedef CGAL::_Min_circle_2_adapterC2__Circle Circle; private: DA dao; // data accessor object Circle circle; // current circle friend class CGAL::Min_circle_2< CGAL::Min_circle_2_adapterC2 >; public: // creation Min_circle_2_adapterC2( 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_::FT FT; FT px; FT py; FT qx; FT qy; FT rx; FT ry; dao.get( p, px, py); dao.get( q, qx, qy); dao.get( r, rx, ry); return( static_cast< CGAL::Orientation>( CGAL_NTS sign( ( px-rx) * ( qy-ry) - ( py-ry) * ( qx-rx)))); } }; // Nested type `Circle' template < class PT_, class DA_ > std::ostream& operator << ( std::ostream&, const CGAL::_Min_circle_2_adapterC2__Circle&); template < class PT_, class DA_ > std::istream& operator >> ( std::istream&, CGAL::_Min_circle_2_adapterC2__Circle&); template < class PT_, class DA_ > class _Min_circle_2_adapterC2__Circle { public: // typedefs typedef PT_ PT; typedef DA_ DA; typedef typename DA_::FT FT; private: // data members DA dao; // data accessor object FT center_x; // center's x-coordinate FT center_y; // center's y-coordinate FT sqr_rad; // squared radius // private member functions FT sqr_dist( const FT& px, const FT& py, const FT& qx, const FT& qy) const { FT dx( px - qx); FT dy( py - qy); return( dx*dx + dy*dy); } friend std::ostream& operator << <> ( std::ostream&, const CGAL::_Min_circle_2_adapterC2__Circle&); friend std::istream& operator >> <> ( std::istream&, CGAL::_Min_circle_2_adapterC2__Circle&); public: // types typedef PT Point; typedef FT Distance; // creation _Min_circle_2_adapterC2__Circle( const DA& da) : dao( da) { } void set( ) { center_x = FT( 0); center_y = FT( 0); sqr_rad = -FT( 1); } void set( const Point& p) { dao.get( p, center_x, center_y); sqr_rad = FT( 0); } void set( const Point& p, const Point& q) { FT px; FT py; FT qx; FT qy; dao.get( p, px, py); dao.get( q, qx, qy); center_x = ( px+qx) / FT( 2); center_y = ( py+qy) / FT( 2); sqr_rad = sqr_dist( px, py, center_x, center_y); } void set( const Point& p, const Point& q, const Point& r) { FT px; FT py; FT qx; FT qy; FT rx; FT ry; dao.get( p, px, py); dao.get( q, qx, qy); dao.get( r, rx, ry); FT qx_px( qx - px); FT qy_py( qy - py); FT rx_px( rx - px); FT ry_py( ry - py); FT p2 ( px*px + py*py); FT q2_p2( qx*qx + qy*qy - p2); FT r2_p2( rx*rx + ry*ry - p2); FT denom( ( qx_px*ry_py - rx_px*qy_py) * FT( 2)); center_x = ( q2_p2*ry_py - r2_p2*qy_py) / denom; center_y = ( r2_p2*qx_px - q2_p2*rx_px) / denom; sqr_rad = sqr_dist( px, py, center_x, center_y); } // predicates CGAL::Bounded_side bounded_side( const Point& p) const { FT px; FT py; dao.get( p, px, py); return( CGAL::Bounded_side( CGAL_NTS sign( sqr_rad - sqr_dist( px, py, center_x, center_y)))); } bool has_on_bounded_side( const Point& p) const { FT px; FT py; dao.get( p, px, py); return( sqr_dist( px, py, center_x, center_y) < sqr_rad); } bool has_on_boundary( const Point& p) const { FT px; FT py; dao.get( p, px, py); return( sqr_dist( px, py, center_x, center_y) == sqr_rad); } bool has_on_unbounded_side( const Point& p) const { FT px; FT py; dao.get( p, px, py); return( sqr_rad < sqr_dist( px, py, center_x, center_y)); } 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_adapterC2__Circle& c) const { return( ( center_x == c.center_x) && ( center_y == c.center_y) && ( sqr_rad == c.sqr_rad ) ); } bool operator != ( const CGAL::_Min_circle_2_adapterC2__Circle& c) const { return( ! ( *this == c)); } Point center( ) const { Point p; dao.set( p, center_x, center_y); 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_adapterC2__Circle& c) { switch ( CGAL::get_mode( os)) { case CGAL::IO::PRETTY: os << "CGAL::Min_circle_2_adapterC2::Circle( " << c.center_x << ", " << c.center_y << ", " << c.sqr_rad << ')'; break; case CGAL::IO::ASCII: os << c.center_x << ' ' << c.center_y << ' ' << c.sqr_rad; break; case CGAL::IO::BINARY: CGAL::write( os, c.center_x); CGAL::write( os, c.center_y); 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_adapterC2__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_x >> c.center_y >> c.sqr_rad; break; case CGAL::IO::BINARY: CGAL::read( is, c.center_x); CGAL::read( is, c.center_y); 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_ADAPTERC2_H // ===== EOF ==================================================================