Files
SaraP f29512578a Extern :
- C3d aggiornamento delle librerie ( 117832).
2022-07-21 14:53:00 +02:00

489 lines
17 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru Габаритные объекты. Одномерный куб.
\en Bounding box objects. One-dimensional box. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __MB_RECT1D_H
#define __MB_RECT1D_H
#include <mb_enum.h>
//------------------------------------------------------------------------------
/// \ru Одномерный куб. \en One-dimensional box.
/**
\ingroup Mathematic_Base_3D
*/ // ---
class MATH_CLASS MbRect1D {
public:
double zmin; ///< \ru Начало диапазона. \en Start of range.
double zmax; ///< \ru Конец диапазона. \en End of range.
public:
/// \ru Конструктор по умолчанию. \en Default constructor.
MbRect1D ( ) : zmin( MB_MAXDOUBLE ), zmax( -MB_MAXDOUBLE ) {}
/// \ru Конструктор копирования. \en Copy constructor.
MbRect1D ( const MbRect1D & );
/// \ru Конструктор по заданным значениям границ. \en Constructor by given bounds.
MbRect1D ( double pmin, double pmax, bool equalize = true );
/// \ru Инициализировать неустановленным. \en Initialize unspecified.
void Init ( );
/// \ru Инициализировать другим кубом. \en Initialize by another box.
void Init ( const MbRect1D & );
/// \ru Инициализировать заданными значениями границ. \en Initialize by given bounds.
void Init ( double pmin, double pmax, bool equalize = true );
/// \ru Создать вывернутый одномерный куб. \en Create reverted one-dimensional box.
void Invert ();
/// \ru Сократить одномерный куб на заданный коэффициент и расширить на дельта. \en Decrease one-dimensional box by a given factor and increase by delta.
void Short ( double, bool bis = true, double delta = LENGTH_EPSILON );
/// \ru Сократить одномерный куб на заданный коэффициент относительно точки и расширить на дельта. \en Decrease one-dimensional box by a given factor relative to point and increase by delta.
void Short ( double, double, bool bis = true, double delta = LENGTH_EPSILON );
/// \ru Включить точку. \en Include point.
void Include ( double, bool bis = true, double delta = LENGTH_EPSILON );
/// \ru Установить куб. \en Set box.
void Include ( const MbRect1D & , bool bis = true, double delta = LENGTH_EPSILON );
/// \ru Включить точку. \en Include point.
void IncludeEx ( double );
/// \ru Установить куб. \en Set box.
void IncludeEx ( const MbRect1D & );
///< \ru Выровнять диапазон. \en Justify range.
void Equalize ( double &, double & ) const;
/// \ru Выровнять диапазон (zmin, zmax). \en Justify range (zmin, zmax).
void Equalize ( );
/// \ru Является ли область вывернутой. \en Check if region is reverted.
bool IsEmpty ( ) const;
/// \ru Является ли область вырожденной. \en Check if region is degenerate.
bool IsDegenert ( ) const;
/// \ru Есть ли пересечение с другим прямоугольником. \en Is there intersection with another rectangle.
bool IsIntersect( const MbRect1D & ) const;
/// \ru Есть ли пересечение с точкой. \en Is there intersection with point.
bool IsIntersect( double ) const;
/// \ru Есть ли пересечение с другим прямоугольником. \en Is there intersection with another rectangle.
bool IsIntersect( double, double ) const;
/// \ru Есть ли пересечение с пустым кубом. \en Is there intersection with empty box.
bool IsEmptyInt ( double ) const;
/// \ru Загнать одномерную точку в куб. \en Drive one-dimensional point to box.
void SetInR ( double & ) const;
/// \ru Загнать одномерную точку в куб. \en Drive one-dimensional point to box.
void SetInRect ( double & ) const;
/// \ru Загнать другую область в куб. \en Drive another region to box.
void SetInRect ( MbRect1D & ) const;
/// \ru Получить минимум. \en Get minimum.
double GetMin () const { return zmin; }
/// \ru Получить максимум. \en Get maximum.
double GetMax () const { return zmax; }
/// \ru Задать минимум. \en Set minimum.
void SetMin( double v ) { zmin = v; }
/// \ru Задать максимум. \en Set maximum.
void SetMax( double v ) { zmax = v; }
/// \ru Получить характерный масштаб одномерного куба. \en Get characteristic scale of one-dimensional box.
double GetScale () const;
/// \ru Увеличить куб. \en Increase box.
void Increase ( double );
/// \ru Проверить принадлежность границе первого параметра с точностью, заданной вторым. \en Check if first parameter belongs to bound with tolerance given by second parameter.
bool IsBound ( double, double ) const;
/// \ru Cдвинуть куб. \en Move box.
void Move ( double );
/// \ru Проверить два куба на равенство с заданной точностью. \en Check equality of two boxes with given tolerance.
bool IsEqual ( const MbRect1D &, double eps ) const;
/// \ru Найти габарит пересечения двух габаритов. \en Find bounding box of two bounding boxes intersection.
bool Intersection( const MbRect1D &, const MbRect1D &, double eps = LENGTH_EPSILON );
/// \ru Являются ли объекты равными? \en Determine whether an object is equal?
bool IsSame( const MbRect1D & other, double accuracy ) const {
return ( (::fabs(zmin - other.zmin) < accuracy) && (::fabs(zmax - other.zmax) < accuracy) );
}
/// \ru Проверить на равенство (точность PARAM_REGION). \en Check for equality (tolerance PARAM_REGION).
bool operator ==( const MbRect1D & ) const;
/// \ru Проверка на меньше (точность PARAM_REGION). \en Check for lesser (tolerance PARAM_REGION).
bool operator < ( const MbRect1D & ) const;
};
//------------------------------------------------------------------------------
// \ru Выровнять диапазон. \en Justify range.
// ---
inline
void MbRect1D::Equalize( double & ozmin, double & ozmax ) const
{
if ( ozmin > ozmax ) {
double maxvalue = ozmin;
ozmin = ozmax;
ozmax = maxvalue;
}
}
//------------------------------------------------------------------------------
// \ru Выровнять диапазон. \en Justify range.
// ---
inline
void MbRect1D::Equalize()
{
Equalize( zmin, zmax );
}
//------------------------------------------------------------------------------
// \ru Конструктор. \en Constructor.
// ---
inline
MbRect1D::MbRect1D( double ozmin, double ozmax, bool equalize )
: zmin( ozmin )
, zmax( ozmax )
{
if ( equalize )
Equalize(); // \ru Выровнять куб. \en Justify box.
}
//------------------------------------------------------------------------------
// \ru Конструктор. \en Constructor.
// ---
inline
MbRect1D::MbRect1D( const MbRect1D & other )
: zmin( other.zmin )
, zmax( other.zmax )
{
}
//------------------------------------------------------------------------------
// \ru Инициализировать. \en Initialize.
// ---
inline
void MbRect1D::Init()
{
zmin = MB_MAXDOUBLE;
zmax = -MB_MAXDOUBLE;
}
//------------------------------------------------------------------------------
// \ru Инициализировать. \en Initialize.
// ---
inline
void MbRect1D::Init( double ozmin, double ozmax, bool equalize )
{
zmin = ozmin; // \ru Присвоить значения. \en Assign values.
zmax = ozmax;
if ( equalize )
Equalize(); // \ru Выровнять куб. \en Justify box.
}
//------------------------------------------------------------------------------
// \ru Инициализировать. \en Initialize.
// ---
inline
void MbRect1D::Init( const MbRect1D & other )
{
zmin = other.zmin;
zmax = other.zmax;
}
//------------------------------------------------------------------------------
// \ru Сократить одномерный куб на заданный коэфициент. \en Decrease one-dimensional box by given factor.
// ---
inline
void MbRect1D::Short( double ks, bool bis, double d )
{
double delta = bis ? d : 0;
double l = ( zmax - zmin ) * 0.5;
double cz = zmin + l;
l *= ks;
l += delta;
zmin = cz - l;
zmax = cz + l;
}
//------------------------------------------------------------------------------
// \ru Сократить одномерный куб на заданный коэффициент относительно точки. \en Decrease one-dimensional box by given factor relative to point.
// ---
inline
void MbRect1D::Short( double ks, double cz, bool bis, double d )
{
double delta = bis ? d : 0;
zmax = cz > zmax ? cz + delta : ( zmax - cz ) * ks + cz + delta;
zmin = cz < zmin ? cz - delta : ( zmin - cz ) * ks + cz - delta;
}
//------------------------------------------------------------------------------
// \ru Включить одномерную точку. \en Include one-dimensional point.
// ---
inline
void MbRect1D::Include( double other, bool bis, double delta )
{
if ( other > zmax )
zmax = bis ? other + delta : other; // \ru Расширить. \en Increase.
if ( other < zmin )
zmin = bis ? other - delta : other; // \ru Расширить. \en Increase.
}
//------------------------------------------------------------------------------
// \ru Добавить не пустой габарит. \en Add non-empty bounding box.
// ---
inline
void MbRect1D::Include( const MbRect1D & other, bool bis, double delta )
{
if ( !other.IsEmpty() ) {
Include( other.zmin, bis, delta );
Include( other.zmax, bis, delta );
}
}
//-------------------------------------------------------------------------------
// \ru Включить точку. \en Include point.
// ---
inline
void MbRect1D::IncludeEx( double other )
{
if ( other > zmax )
zmax = other;
if ( other < zmin )
zmin = other;
}
//-------------------------------------------------------------------------------
// \ru Установить куб. \en Set box.
// ---
inline
void MbRect1D::IncludeEx( const MbRect1D & other )
{
if ( !other.IsEmpty() ) {
IncludeEx( other.zmin );
IncludeEx( other.zmax );
}
}
//------------------------------------------------------------------------------
// \ru Является ли область пустой. \en Check if region is empty.
// ---
inline
bool MbRect1D::IsEmpty() const
{
return zmin > zmax;
}
//------------------------------------------------------------------------------
// \ru Является ли область вырожденной. \en Check if region is degenerate.
// ---
inline
bool MbRect1D::IsDegenert() const
{
return zmax - zmin < LENGTH_REGION;
}
//------------------------------------------------------------------------------
// \ru Включение точки в прямоугольник. \en Point inclusion in rectangle.
// ---
inline
bool MbRect1D::IsIntersect( double other ) const
{
return other <= zmax && other >= zmin;
}
//------------------------------------------------------------------------------
// \ru Включение точки в прямоугольник. \en Point inclusion in rectangle.
// ---
inline
bool MbRect1D::IsIntersect( double z1, double z2 ) const
{
Equalize( z1, z2 );
return std_max( zmin, z1 ) <= std_min( zmax, z2 );
}
//------------------------------------------------------------------------------
// \ru Пересечение с другим прямоугольником. \en Check intersection with another rectangle.
// ---
inline
bool MbRect1D::IsIntersect( const MbRect1D & other ) const
{
return std_max( zmin, other.zmin ) <= std_min( zmax, other.zmax );
}
//------------------------------------------------------------------------------
// \ru Пересечение с пустым кубом. \en Is there intersection with empty box.
// ---
inline
bool MbRect1D::IsEmptyInt( double other ) const
{
return other <= zmax || other >= zmin;
}
//------------------------------------------------------------------------------
// \ru Загнать одномерную точку в куб. \en Drive one-dimensional point to box.
// ---
inline
void MbRect1D::SetInR( double & z ) const
{
if ( z < zmin )
z = zmin;
else
if ( z > zmax )
z = zmax;
}
//------------------------------------------------------------------------------
// \ru Загнать одномерную точку в куб. \en Drive one-dimensional point to box.
// ---
inline
void MbRect1D::SetInRect( double & z ) const
{
if ( IsEmpty() ) {
if( !IsEmptyInt(z) )
z = zmin;
}
else {
SetInR( z );
}
}
//------------------------------------------------------------------------------
// \ru Загнать другую область в куб. \en Drive another region to box.
// ---
inline
void MbRect1D::SetInRect( MbRect1D & other ) const
{
SetInRect( other.zmin );
SetInRect( other.zmax );
}
//------------------------------------------------------------------------------
// \ru Создать вывернутый одномерный куб. \en Create reverted one-dimensional box.
// ---
inline
void MbRect1D::Invert()
{
double oldzmax = zmax;
zmax = -zmin;
zmin = -oldzmax;
}
//------------------------------------------------------------------------------
// \ru Получить характерный масштаб одномерного куба. \en Get characteristic scale of one-dimensional box.
// ---
inline
double MbRect1D::GetScale() const
{
return (zmax - zmin);
}
//------------------------------------------------------------------------------
// \ru Увеличить куб. \en Increase box.
// ---
inline
void MbRect1D::Increase( double delta )
{
zmax += delta;
zmin -= delta;
}
//------------------------------------------------------------------------------
// \ru Принадлежность границе первого параметра с точность заданной вторым. \en Check if the first parameter belongs to bound with tolerance given by second parameter.
// ---
inline
bool MbRect1D::IsBound( double z, double delta ) const
{
return ::fabs( z - zmin ) < delta || ::fabs( z - zmax ) < delta;
}
//-------------------------------------------------------------------------------
// \ru Сдвиг. \en Move.
// ---
inline
void MbRect1D::Move( double shift )
{
zmin += shift;
zmax += shift;
}
//-------------------------------------------------------------------------------
// \ru Равны ли двы куба. \en Check if two boxes are equal.
// ---
inline
bool MbRect1D::IsEqual( const MbRect1D & other, double eps ) const
{
return ( ::fabs(zmin - other.zmin) < eps && ::fabs(zmax - other.zmax) < eps );
}
//------------------------------------------------------------------------------
// \ru Проверка на равенство. \en Check for equality.
// ---
inline
bool MbRect1D::operator == ( const MbRect1D & other ) const
{
return IsEqual( other, PARAM_REGION );
}
//------------------------------------------------------------------------------
// \ru Проверка на меньше. \en Check for lesser.
// ---
inline
bool MbRect1D::operator < ( const MbRect1D & other ) const
{
return ( zmin < other.zmin - PARAM_REGION ) ||
( ( ::fabs( zmin - other.zmin ) < PARAM_REGION ) && ( zmax < other.zmax - PARAM_REGION ) );
}
//------------------------------------------------------------------------------
// \ru Габарит пересечения двух габаритов. \en Bounding box of two bounding boxes intersection.
// ---
inline
bool MbRect1D::Intersection( const MbRect1D & r1, const MbRect1D & r2, double eps )
{
bool isInt = false;
if ( !r1.IsEmpty() && !r2.IsEmpty() ) {
eps = ::fabs( eps );
zmin = std_max( r1.zmin, r2.zmin );
zmax = std_min( r1.zmax, r2.zmax );
if ( zmax > zmin + eps )
isInt = true;
}
if ( !isInt )
Init();
return isInt;
}
#endif // __MB_RECT1D_H