mirror of https://github.com/CGAL/cgal
344 lines
8.2 KiB
C++
344 lines
8.2 KiB
C++
// 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 <sven@inf.ethz.ch>, Bernd Gaertner
|
|
|
|
#ifndef CGAL_MIN_CIRCLE_2_ADAPTERC2_H
|
|
#define CGAL_MIN_CIRCLE_2_ADAPTERC2_H
|
|
|
|
// includes
|
|
#ifndef CGAL_OPTIMISATION_BASIC_H
|
|
# include <CGAL/Optimisation/basic.h>
|
|
#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<PT,DA> Circle;
|
|
|
|
private:
|
|
DA dao; // data accessor object
|
|
Circle circle; // current circle
|
|
friend class CGAL::Min_circle_2< CGAL::Min_circle_2_adapterC2<PT,DA> >;
|
|
|
|
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<PT_,DA_>&);
|
|
|
|
template < class PT_, class DA_ >
|
|
std::istream&
|
|
operator >> ( std::istream&,
|
|
CGAL::_Min_circle_2_adapterC2__Circle<PT_,DA_>&);
|
|
|
|
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<PT_,DA_>&);
|
|
|
|
friend std::istream& operator >> <> ( std::istream&,
|
|
CGAL::_Min_circle_2_adapterC2__Circle<PT_,DA_>&);
|
|
|
|
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<PT_,DA_>& 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<PT_,DA_>& 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<PT_,DA_>& 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<PT_,DA_>& 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 ==================================================================
|