test_pie/external/exact_ccd/interval_base.h

150 lines
3.5 KiB
C++

// ---------------------------------------------------------
//
// interval_base.h
// Tyson Brochu 2011
//
// Interface definition for Interval types.
//
// ---------------------------------------------------------
#ifndef TUNICATE_INTERVAL_BASE_H
#define TUNICATE_INTERVAL_BASE_H
#include "vec.h"
namespace CCD
{
class IntervalBase
{
public:
inline virtual ~IntervalBase() {}
virtual double stored_left() const = 0;
virtual double stored_right() const = 0;
inline virtual Vec2d get_actual_interval() const;
inline virtual Vec2d get_internal_representation() const;
inline virtual bool contains_zero() const;
inline virtual bool indefinite_sign() const;
inline virtual bool is_certainly_negative( ) const;
inline virtual bool is_certainly_positive( ) const;
inline virtual bool is_certainly_zero( ) const;
inline virtual bool certainly_opposite_sign( const IntervalBase& other ) const;
inline virtual bool same_sign( const IntervalBase& other ) const;
inline virtual double estimate() const;
};
// ----------------------------------------
inline Vec2d IntervalBase::get_actual_interval() const
{
return Vec2d( -stored_left(), stored_right() );
}
// ----------------------------------------
inline Vec2d IntervalBase::get_internal_representation() const
{
return Vec2d( stored_left(), stored_right() );
}
// ----------------------------------------
inline bool IntervalBase::contains_zero() const
{
// true if a <= 0 && b >= 0
// remember v[0] == -a
return ( stored_left() >= 0 && stored_right() >= 0 );
}
// ----------------------------------------
// TODO: This is equivalent to contains_zero(), should be removed
inline bool IntervalBase::indefinite_sign() const
{
return ( stored_left() >= 0 && stored_right() >= 0 );
}
// ----------------------------------------
inline bool IntervalBase::is_certainly_negative( ) const
{
return ( stored_right() < 0 );
}
// ----------------------------------------
inline bool IntervalBase::is_certainly_positive( ) const
{
return ( stored_left() < 0 );
}
// ----------------------------------------
inline bool IntervalBase::is_certainly_zero( ) const
{
return ( stored_left() == 0 && stored_right() == 0 );
}
// ----------------------------------------
inline bool IntervalBase::certainly_opposite_sign( const IntervalBase& other ) const
{
return ( ( this->is_certainly_negative() && other.is_certainly_positive() ) ||
( this->is_certainly_positive() && other.is_certainly_negative() ) );
}
// ----------------------------------------
inline bool IntervalBase::same_sign( const IntervalBase& other ) const
{
return ( this->contains_zero() ||
other.contains_zero() ||
( this->is_certainly_negative() && other.is_certainly_negative() ) ||
( this->is_certainly_positive() && other.is_certainly_positive() ) );
}
// ----------------------------------------
inline double IntervalBase::estimate() const
{
double est = 0.5 * (-stored_left() + stored_right());
if ( est == 0 && !is_certainly_zero() )
{
// don't return zero as an estimate if the interval is not identically zero.
est = 1e-20;
}
return est;
}
// ----------------------------------------
inline bool certainly_opposite_sign( const IntervalBase& a, const IntervalBase& b )
{
return a.certainly_opposite_sign( b );
}
// ----------------------------------------
inline bool same_sign( const IntervalBase& a, const IntervalBase& b )
{
return a.same_sign(b);
}
}
#endif