cgal/Min_circle_2/include/CGAL/Min_circle_2_adapterH2.h

384 lines
9.9 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_ADAPTERH2_H
#define CGAL_MIN_CIRCLE_2_ADAPTERH2_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_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<PT,DA> Circle;
private:
DA dao; // data accessor object
Circle circle; // current circle
friend class CGAL::Min_circle_2< CGAL::Min_circle_2_adapterH2<PT,DA> >;
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<PT_,DA_>&);
template < class PT_, class DA_ >
std::istream&
operator >> ( std::istream&,
CGAL::_Min_circle_2_adapterH2__Circle<PT_,DA_>&);
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<RT> 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<PT_,DA_>&);
friend std::istream& operator >> <> ( std::istream&,
CGAL::_Min_circle_2_adapterH2__Circle<PT_,DA_>&);
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<PT_,DA_>& 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<PT_,DA_>& 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<PT_,DA_>& 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<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_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 ==================================================================