Files
Extern/C3d/Include/alg_dimension.h
T
SaraP c8860b2e96 Extern :
- C3d aggiornamento delle librerie ( 117931).
2022-12-16 15:24:30 +01:00

916 lines
50 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru Радиальный размер к поверхности. Расстояние между поверхностями.
\en Radial dimension of surface. Distance between surfaces. \~
\details \ru Функции построения окружности или дуги для радиального размера к поверхности.
Функция вычисления экстремальных расстояний между поверхностями.
\en Functions of construction of a circle or an arc for radial dimension of surface.
A function of calculation of extreme distances between surfaces. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __ALG_DIMENSION_H
#define __ALG_DIMENSION_H
#include <templ_s_array.h>
#include <mb_enum.h>
#include <mb_cart_point.h>
#include <curve3d.h>
#include <surface.h>
class MATH_CLASS MbCartPoint3D;
class MATH_CLASS MbVector3D;
class MATH_CLASS MbPlacement3D;
class MATH_CLASS MbAxis3D;
class MATH_CLASS MbPlaneCurve;
class MATH_CLASS IProgressIndicator;
////////////////////////////////////////////////////////////////////////////////
//
// \ru Построение окружности или дуги для радиального размера к поверхности, \en Construction of a circle or an arc for radial dimension of surface
// \ru имеющей круговую параметрическую линию u=const или v=const \en which has a circular parametric line u=const or v=const.
// \ru Перечень поверхностей, имеющих параметрическую линию u=const или u=const: \en The enumeration of surfaces which have a parametric line u=const or u=const:
// MbCylinderSurface, v=const
// MbConeSurface, v=const
// MbSphereSurface, u=const
// MbTorusSurface, u=const
// MbLoftedSurface, v=const
// MbElevationSurface, v=const
// MbExtrusionSurface, v=const
// MbRevolutionSurface, u=const
// MbEvolutionSurface, u=const
// MbExactionSurface, u=const
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
/** \brief \ru Построить окружность или дугу для радиального размера к поверхности.
\en Construct a circle or an arc for radial dimension of surface. \~
\details \ru Построение выполняется по заданной параметрической точке поверхности. Поверхность
должна иметь круговую параметрическую линию u=const или v=const. Перечень поверхностей,
имеющих параметрическую линию u=const или v=const:
MbCylinderSurface v=const, \n MbConeSurface v=const, \n
MbSphereSurface u=const, \n MbTorusSurface u=const, \n
MbLoftedSurface v=const, \n MbElevationSurface v=const, \n
MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n
MbEvolutionSurface u=const, \n MbExactionSurface u=const.
\en Construction is performed by the given parametric point on surface. A surface
should have a circular parametric line u=const or v=const. The enumeration of surfaces
which have a parametric line u=const or v=const.
MbCylinderSurface v=const, \n MbConeSurface v=const, \n
MbSphereSurface u=const, \n MbTorusSurface u=const, \n
MbLoftedSurface v=const, \n MbElevationSurface v=const, \n
MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n
MbEvolutionSurface u=const, \n MbExactionSurface u=const. \~
\param[in] surface - \ru Исходная поверхность.
\en The initial surface. \~
\param[in] surface_uv - \ru Координаты исходной точки на поверхности.
\en Coordinates of the initial point on surface. \~
\param[out] plane_curve - \ru Требуемая окружность или дуга.
\en The required circle or an arc. \~
\ingroup Algorithms_3D
*/ // ---
MATH_FUNC (void) RadiusDimension3D( const MbSurface & surface,
const MbCartPoint & surface_uv,
MbPlaneCurve *& plane_curve );
//------------------------------------------------------------------------------
/** \brief \ru Построить окружность или дугу для радиального размера к поверхности.
\en Construct a circle or an arc for radial dimension of surface. \~
\details \ru Построение выполняется по заданной по заданной пространственной точке. Поверхность
должна иметь круговую параметрическую линию u=const или v=const. Перечень поверхностей,
имеющих параметрическую линию u=const или u=const:
MbCylinderSurface v=const, \n MbConeSurface v=const, \n
MbSphereSurface u=const, \n MbTorusSurface u=const, \n
MbLoftedSurface v=const, \n MbElevationSurface v=const, \n
MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n
MbEvolutionSurface u=const, \n MbExactionSurface u=const.
\en Construction is performed by the given spatial point. A surface
should have a circular parametric line u=const or v=const. The enumeration of surfaces
which have a parametric line u=const or v=const.
MbCylinderSurface v=const, \n MbConeSurface v=const, \n
MbSphereSurface u=const, \n MbTorusSurface u=const, \n
MbLoftedSurface v=const, \n MbElevationSurface v=const, \n
MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n
MbEvolutionSurface u=const, \n MbExactionSurface u=const. \~
\param[in] surface - \ru Исходная поверхность.
\en The initial surface. \~
\param[in] point - \ru Пространственные координаты исходной точки.
\en Space coordinates of the initial point. \~
\param[out] plane_curve - \ru Требуемая окружность или дуга.
\en The required circle or an arc. \~
\ingroup Algorithms_3D
*/ // ---
MATH_FUNC (void) RadiusDimension3D( const MbSurface & surface,
const MbCartPoint3D & point,
MbPlaneCurve *& plane_curve );
//------------------------------------------------------------------------------
/** \brief \ru Построить окружность или дугу для радиального размера к поверхности.
\en Construct a circle or an arc for radial dimension of surface. \~
\details \ru Построение выполняется по заданному плейсменту. Поверхность должна иметь
круговую параметрическую линию u=const или v=const. Перечень поверхностей, имеющих
параметрическую линию u=const или u=const:
MbCylinderSurface v=const, \n MbConeSurface v=const, \n
MbSphereSurface u=const, \n MbTorusSurface u=const, \n
MbLoftedSurface v=const, \n MbElevationSurface v=const, \n
MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n
MbEvolutionSurface u=const, \n MbExactionSurface u=const.
\en Construction is performed by the given placement. A surface should have
a circular parametric line u=const or v=const. The enumeration of surfaces with
a parametric line u=const or v=const.
MbCylinderSurface v=const, \n MbConeSurface v=const, \n
MbSphereSurface u=const, \n MbTorusSurface u=const, \n
MbLoftedSurface v=const, \n MbElevationSurface v=const, \n
MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n
MbEvolutionSurface u=const, \n MbExactionSurface u=const. \~
\param[in] surface - \ru Исходная поверхность.
\en The initial surface. \~
\param[in] place - \ru Исходный плейсмент.
\en The initial placement. \~
\param[out] plane_curve - \ru Требуемая окружность или дуга.
\en The required circle or an arc. \~
\ingroup Algorithms_3D
*/ // ---
MATH_FUNC (void) RadiusDimension3D( const MbSurface & surface,
const MbPlacement3D & place,
MbPlaneCurve *& plane_curve );
//------------------------------------------------------------------------------
/** \brief \ru Можно ли построить окружность или дугу для радиального размера к поверхности.
\en Whether a circle or an arc can be constructed for radial dimension of surface. \~
\details \ru Можно построить, если тип базовой поверхности: st_CylinderSurface или st_ConeSurface,
или st_SphereSurface, или st_TorusSurface.
\en It can be constructed if the type of a base surface is st_CylinderSurface or st_ConeSurface,
or st_SphereSurface, or st_TorusSurface. \~
\param[in] surface - \ru Исходная поверхность.
\en The initial surface. \~
\return \ru true, если можно построить.
\en true if it can be constructed. \~
\ingroup Algorithms_3D
*/ // ---
MATH_FUNC (bool) IsPossibleRadiusDimension3D( const MbSurface & surface );
//------------------------------------------------------------------------------
/** \brief \ru Результат замера расстояния и угла между поверхностями.
\en The result of measurement of dimension and angle between surfaces. \~
\details \ru Результат замера расстояния и угла между поверхностями.
\en The result of measurement of dimension and angle between surfaces. \~
\ingroup Algorithms_3D
*/ // ---
enum MbeSurfAxesMeasureRes
{
// \ru ошибочные результат \en mistaken result
samr_SurfSurf_Failed = -3, ///< \ru Ошибка при работе с поверхностями. \en An error is occurred while working with surfaces.
samr_AxisSurf_Failed = -2, ///< \ru Ошибка при работе с осью и поверхностью. \en An error is occurred while working with axis and surface.
samr_AxisAxis_Failed = -1, ///< \ru Ошибка при работе с осями. \en An error is occurred while working with axes.
// \ru пустой результат \en an empty result.
samr_Undefined = 0, ///< \ru Не получилось или не измерялось. \en Failed or didn't measured.
// \ru две оси \en two axes
samr_AxisAxis_Coaxial, ///< \ru Оси совпадают. \en Axes are coincident.
samr_AxisAxis_Parallel, ///< \ru Оси параллельны. \en Axes are parallel.
samr_AxisAxis_Intersecting, ///< \ru Оси пересекаются. \en Axes are crossed.
samr_AxisAxis_Distant, ///< \ru Оси на расстоянии. \en Axes are located at a distance.
// \ru одна ось (какая из осей есть, см. по возвращаемому флагу функции замера) \en one axis (see the returned flag of measurement function to detect which one exactly)
samr_AxisSurf_Colinear, ///< \ru Ось лежит на поверхности. \en The axis lies on the surface.
samr_AxisSurf_Parallel, ///< \ru Ось параллельна поверхности. \en The axis is parallel to the surface.
samr_AxisSurf_Intersecting, ///< \ru Ось пересекает поверхность. \en The axis crosses the surface.
samr_AxisSurf_Distant, ///< \ru Ось на расстоянии от поверхности. \en The axis is located at a distance from the surface.
// \ru две плоские поверхности \en two planar surfaces
samr_SurfSurf_Colinear, ///< \ru Одна поверхность лежит на другой. \en One surface lies on another one.
samr_SurfSurf_Parallel, ///< \ru Поверхности параллельны. \en Surfaces are parallel.
samr_SurfSurf_Intersecting, ///< \ru Поверхности пересекаются. \en Surfaces are intersecting inside domain.
// \ru samr_SurfSurf_Distant, // находятся на расстоянии \en samr_SurfSurf_Distant, // located at a distance
};
//------------------------------------------------------------------------------
/** \brief \ru Расстояние между осями поверхностей.
\en Distance between axes of surfaces. \~
\details \ru Рассчитывается расстояние между осями поверхностей, имеющих оси вращения,
или расстояние между поверхностью, имеющей ось, и плоской поверхностью.
\en Calculate distance between axes of revolution surfaces
or distance between revolution surface and planar surface. \~
\param[in] surface1, sameSense1 - \ru Первая поверхность и ее направление.
\en The first surface and its direction. \~
\param[in] surface2, sameSense2 - \ru Вторая поверхность и ее направление.
\en The second surface and its direction. \~
\param[out] axis1, exist1 - \ru Ось первой поверхности и флаг ее наличия.
\en The axis of the first surface and the flag of its existence. \~
\param[out] axis2, exist2 - \ru Ось второй поверхности и флаг ее наличия.
\en The axis of the second surface and the flag of its existence. \~
\param[out] p1 - \ru Точка на первой оси или поверхности.
\en The point on the first axis or surface. \~
\param[out] p2 - \ru Точка на второй оси или поверхности.
\en The point on the second axis or surface. \~
\param[out] angle - \ru Угол между осями или осью поверхностью.
\en The angle between axes or between an axis and a surface. \~
\param[out] distance - \ru Минимальное расстояние между осями.
\en Minimal distance between axes. \~
\param[in] angle - \ru Угловая погрешность.
\en The angle accuracy. \~
\return \ru Вариант полученного замера или вариант ошибки.
\en The variant of the obtained measurement or the variant of error. \~
\ingroup Algorithms_3D
*/ // ---
MATH_FUNC (MbeSurfAxesMeasureRes) SurfAxesDistAngle( const MbSurface & surface1, bool sameSense1,
const MbSurface & surface2, bool sameSense2,
MbAxis3D & axis1, bool & exist1,
MbAxis3D & axis2, bool & exist2,
MbCartPoint3D & p1,
MbCartPoint3D & p2,
double & angle,
double & distance,
double angleEps = ANGLE_EPSILON );
//------------------------------------------------------------------------------
/** \brief \ru Расстояние между точками на объектах (кривая-кривая, кривая-поверхность или поверхность-поверхность).
\en Distance between points on objects (curve-curve, curve-surface, surface-surface). \~
\details \ru Класс содержит данные о расстоянии между точками и координатами этих точек на объектах.
\en The class contains data about the distance between points and their coordinates on objects surfaces. \~
\ingroup Algorithms_3D
*/ // ---
template <class Param1, class Param2>
class MbItemItemDist {
template <typename Par1, typename Par2>
friend class MbMinMaxItemItemDistances;
private:
double d; ///< \ru Расстояние. \en Distance.
Param1 par1; ///< \ru Параметр на первом объекте. \en Parameter on the first object.
Param2 par2; ///< \ru Параметр на втором объекте. \en Parameter on the second object.
uint8 sign; ///< \ru Знак расстояния. \en Sign of direction.
public:
/// \ru Параметрическая точка (1D или 2D). \en Parametric point (1D or 2D).
struct ParamPoint {
double x;
double y;
bool s;
ParamPoint( double t ) : x( t ), y( t ), s( false ) {}
ParamPoint( const MbCartPoint & p ) : x( p.x ), y( p.y ), s( true ) {}
};
public:
/// \ru Конструктор. \en Constructor.
MbItemItemDist() : d( UNDEFINED_DBL ), par1(), par2(), sign( 1 ) {}
/// \ru Конструктор по данным. \en The constructor by data.
MbItemItemDist( double _d, const Param1 & _par1, const Param2 & _par2, bool plus ) { Init( _d, _par1, _par2, plus ); }
/// \ru Конструктор копирования. \en Copy constructor.
MbItemItemDist( const MbItemItemDist & other ) { Init( other ); }
/// \ru Деструктор. \en The destructor.
virtual ~MbItemItemDist() {}
public:
/// \ru Функция копирования. \en Copy function.
void Init( const MbItemItemDist & obj ) { d = obj.d; par1 = obj.par1; par2 = obj.par2; sign = obj.sign; }
/// \ru Получить расстояние. \en Get distance.
double GetDistance() const { return d; }
/// \ru Получить точку на первой поверхности. \en Get the point on the first surface.
const Param1 & GetParamOne() const { return par1; }
/// \ru Получить точку на второй поверхности. \en Get the point on the second surface.
const Param2 & GetParamTwo() const { return par2; }
/// \ru Расстояние положительное? \en Is the distance positive?
bool IsPositive() const { return (sign > 0); }
/// \ru Расстояние отрицательное? \en Is the distance negative?
bool IsNegative() const { return (sign < 1); }
/// \ru Оператор присваивания. \en Assignment operator.
const MbItemItemDist & operator = ( const MbItemItemDist & other ) { Init( other ); return (*this); }
private:
// \ru Инициализатор. \en Initializer.
void Init( double _d, const Param1 & _par1, const Param2 & _par2, bool plus )
{
d = _d;
par1 = _par1;
par2 = _par2;
sign = plus ? 1 : 0;
}
};
//------------------------------------------------------------------------------
// MbItemItemDist typedefs
// ---
typedef MbItemItemDist<double, double> MbCurvCurvDist;
typedef MbItemItemDist<double, MbCartPoint> MbCurvSurfDist;
typedef MbItemItemDist<MbCartPoint, double> MbSurfCurvDist;
typedef MbItemItemDist<MbCartPoint, MbCartPoint> MbSurfSurfDist;
DEPRECATE_DECLARE_REPLACE( MbSurfSurfDist )
typedef MbSurfSurfDist MbSurfDist; // old
//------------------------------------------------------------------------------
// сортировать по возрастанию расстояния
// ---
template <class ItemItemDist>
bool ItemItemDistCompFunc( const ItemItemDist & sd1, const ItemItemDist & sd2 )
{
bool isFirstLessSecond = false;
const double mEps = LENGTH_EPSILON;
const double pEps = PARAM_EPSILON;
double d1 = sd1.GetDistance();
double d2 = sd2.GetDistance();
if ( d1 < d2 - mEps )
isFirstLessSecond = true;
else if ( ::fabs( d1 - d2 ) <= mEps ) {
const typename ItemItemDist::ParamPoint parOne1( sd1.GetParamOne() );
const typename ItemItemDist::ParamPoint parOne2( sd2.GetParamOne() );
if ( parOne1.x < parOne2.x - pEps )
isFirstLessSecond = true;
else if ( parOne1.s && parOne2.s && ::fabs( parOne1.x - parOne2.x ) <= pEps ) {
if ( parOne1.y < parOne2.y - pEps )
isFirstLessSecond = true;
else if ( ::fabs( parOne1.y - parOne2.y ) <= pEps ) {
if ( d1 < d2 )
isFirstLessSecond = true;
}
}
}
return isFirstLessSecond;
}
//------------------------------------------------------------------------------
/** \brief \ru Расстояния с точками между поверхностями.
\en Distances between surfaces with points. \~
\details \ru Расстояния с точками между поверхностями.
\en Distances between surfaces with points. \~
\ingroup Algorithms_3D
*/ // ---
template <class Param1, class Param2>
class MbMinMaxItemItemDistances {
private :
std::vector< MbItemItemDist<Param1,Param2> > allDistances; ///< \ru Расстояние и параметры на поверхностях. \en Distance and parameters on surfaces.
mutable double midDistance; ///< \ru Среднее расстояние. \en Average distance.
mutable double minDistance; ///< \ru Минимальное расстояние. \en Minimal distance.
mutable double maxDistance; ///< \ru Максимальное расстояние. \en Maximal distance.
mutable bool sorted; ///< \ru Признак сортированности. \en Attribute of being sorted.
public:
/// \ru Конструктор. \en Constructor.
MbMinMaxItemItemDistances( size_t nReserve = 0 )
: allDistances( )
, midDistance ( UNDEFINED_DBL )
, minDistance ( UNDEFINED_DBL )
, maxDistance ( UNDEFINED_DBL )
, sorted ( false )
{
allDistances.reserve( std_min( nReserve, (size_t)c3d::COUNT_MAX ) );
}
/// \ru Деструктор. \en Destructor.
virtual ~MbMinMaxItemItemDistances()
{
RemoveAll( true );
}
public:
bool IsEmpty() const { return allDistances.empty(); } ///< \ru Есть ли замеры? \en Are there any measurements?
size_t GetCount() const { return allDistances.size(); } ///< \ru Количество замеров. \en The number of measurements.
ptrdiff_t GetMaxIndex() const { return ((ptrdiff_t)allDistances.size() - 1); } ///< \ru Индекс последнего замера. \en Index of the last measurement
/// \ru Зарезервировать память под nReserve элементов. \en Reserve memory for 'nReserve' elements.
void Reserve( size_t nReserve )
{
allDistances.reserve( allDistances.size() + nReserve );
}
/// \ru Удалить все элементы. \en Delete all elements.
void RemoveAll( bool freeMemory )
{
allDistances.clear();
if ( freeMemory ) {
allDistances.shrink_to_fit();
}
midDistance = minDistance = maxDistance = UNDEFINED_DBL;
}
/// \ru Освободить лишнюю память. \en Free the unnecessary memory.
void AdjustMemory()
{
allDistances.shrink_to_fit();
}
public:
/// \ru Получить расстояние по индексу. \en Get the distance by the index.
bool GetDistance( size_t k, double & d ) const
{
if ( k < allDistances.size() ) {
d = allDistances[k].GetDistance();
return true;
}
return false;
}
/// \ru Получить расстояние со знаком, по индексу. \en Get the signed distance by the index.
bool GetSignedDistance( size_t k, double & d ) const
{
if ( k < allDistances.size() ) {
d = allDistances[k].GetDistance();
if ( allDistances[k].IsNegative() )
d = -d;
return true;
}
return false;
}
/// \ru Считаем ли вы расстояние отрицательным. \en Whether the distance is negative.
bool IsNegativeDistance( size_t k ) const { return ((k < allDistances.size()) ? allDistances[k].IsNegative() : false); }
/// \ru Получить минимальное расстояние. \en Get minimal distance.
bool GetMinDistance( double & d ) const
{
bool res = false;
size_t count = allDistances.size();
if ( count > 0 ) {
if ( minDistance != UNDEFINED_DBL ) {
d = minDistance;
res = true;
}
else if ( count > 1 ) {
minDistance = MB_MAXDOUBLE;
for ( size_t k = 0; k < count; ++k ) {
double curDistance = allDistances[k].GetDistance();
if ( curDistance < minDistance ) {
minDistance = curDistance;
res = true;
}
}
if ( res )
d = minDistance;
else
minDistance = UNDEFINED_DBL;
}
else {
minDistance = allDistances.front().GetDistance();
d = minDistance;
res = true;
}
}
return res;
}
/// \ru Получить максимальное расстояние. \en Get maximal distance.
bool GetMaxDistance( double & d ) const
{
bool res = false;
size_t count = allDistances.size();
if ( count > 0 ) {
if ( maxDistance != UNDEFINED_DBL ) {
d = maxDistance;
res = true;
}
else if ( count > 1 ) {
maxDistance = -MB_MAXDOUBLE;
for ( size_t k = 0; k < count; ++k ) {
double curDistance = allDistances[k].GetDistance();
if ( curDistance > maxDistance ) {
maxDistance = curDistance;
res = true;
}
}
if ( res )
d = maxDistance;
else
maxDistance = UNDEFINED_DBL;
}
else {
maxDistance = allDistances.front().GetDistance();
d = maxDistance;
res = true;
}
}
return res;
}
/// \ru Получить среднее расстояние. \en Get average distance.
bool GetMidDistance( double & d ) const
{
bool res = false;
size_t count = allDistances.size();
if ( count > 0 ) {
if ( count > 1 ) {
if ( midDistance != UNDEFINED_DBL ) {
d = midDistance;
res = true;
}
else {
midDistance = 0.0;
for ( size_t k = 0; k < count; ++k )
midDistance += allDistances[k].GetDistance();
midDistance /= ((double)count);
d = midDistance;
res = true;
}
}
else {
midDistance = allDistances.front().GetDistance();
d = midDistance;
res = true;
}
}
return res;
}
/// \ru Получить расстояние и точки на поверхностях. \en Get distance and points on surface.
bool GetItemDistance( size_t k, double & d, Param1 & par1, Param2 & par2 ) const
{
if ( k < allDistances.size() ) {
d = allDistances[k].GetDistance();
par1 = allDistances[k].GetParamOne();
par2 = allDistances[k].GetParamTwo();
return true;
}
return false;
}
DEPRECATE_DECLARE_REPLACE( GetItemDistance )
bool GetSurfDistance( size_t k, double & d, Param1 & par1, Param2 & par2 ) const
{
return GetItemDistance( k, d, par1, par2 );
}
/// \ru Получить расстояние и точки на поверхностях. \en Get distance and points on surface.
bool GetItemDistance( size_t k, double & d, bool & plus, Param1 & par1, Param2 & par2 ) const
{
if ( k < allDistances.size() ) {
d = allDistances[k].GetDistance();
par1 = allDistances[k].GetParamOne();
par2 = allDistances[k].GetParamTwo();
plus = allDistances[k].IsPositive();
return true;
}
return false;
}
DEPRECATE_DECLARE_REPLACE( GetItemDistance )
bool GetSurfDistance( size_t k, double & d, bool & plus, Param1 & par1, Param2 & par2 ) const
{
return GetItemDistance( k, d, plus, par1, par2 );
}
/// \ru Добавить расстояние и точки на поверхностях. \en Add distance and points on surface.
bool AddItemDistance( double d, bool plus, const Param1 & par1, const Param2 & par2,
bool addEqual, double eps = LENGTH_EPSILON )
{
if ( ::fabs( d ) < LENGTH_EPSILON )
d = 0.0;
C3D_ASSERT( d >= 0 );
if ( d > 0.0 ) {
size_t count = allDistances.size();
bool add = true;
if ( !addEqual ) {
for ( size_t k = 0; k < count; ++k ) {
if ( ::fabs( d - allDistances[k].GetDistance() ) < eps ) {
add = false;
break;
}
}
}
if ( add ) {
if ( count > 0 ) {
if ( maxDistance != UNDEFINED_DBL && d > maxDistance )
maxDistance = d;
else if ( minDistance != UNDEFINED_DBL && d < minDistance )
minDistance = d;
}
else
minDistance = maxDistance = d;
MbItemItemDist<Param1,Param2> surfDistance( d, par1, par2, plus );
allDistances.push_back( surfDistance );
midDistance = UNDEFINED_DBL;
return true;
}
}
return false;
}
/// \ru Добавить расстояние и точки на поверхностях. \en Add distance and points on surface.
DEPRECATE_DECLARE_REPLACE( AddItemDistance )
bool AddSurfDistance( double d, bool plus, const Param1 & par1, const Param2 & par2,
bool addEqual, double eps = LENGTH_EPSILON )
{
return AddItemDistance( d, plus, par1, par2, addEqual, eps );
}
/// \ru Сортировать по возрастанию расстояния. \en Sort by distance in the ascending order.
void Sort()
{
if ( allDistances.size() > 1 ) {
std::sort( allDistances.begin(), allDistances.end(), ItemItemDistCompFunc< MbItemItemDist<Param1,Param2> > );
minDistance = allDistances.front().GetDistance();
maxDistance = allDistances.back().GetDistance();
sorted = true;
}
}
/// \ru Убрать объекты с одинаковыми расстояниями. \en Remove objects with similar distances.
void RemoveEqualDistances( double eps = LENGTH_EPSILON )
{
if ( allDistances.size() > 1 ) {
if ( !sorted )
Sort();
bool wasRemoved = false;
for ( ptrdiff_t k = ((ptrdiff_t)allDistances.size() - 1); k > 0; k-- ) {
ptrdiff_t m = k - 1;
double dThis = allDistances[k].GetDistance();
double dPrev = allDistances[m].GetDistance();
if ( ::fabs( dThis - dPrev ) < eps ) {
allDistances.erase( allDistances.begin() + m );
wasRemoved = true;
}
}
if ( wasRemoved ) {
midDistance = UNDEFINED_DBL;
minDistance = allDistances.front().GetDistance();
maxDistance = allDistances.back().GetDistance();
}
}
}
/// \ru Оператор присваивания. \en Assignment operator.
void operator = ( const MbMinMaxItemItemDistances & other )
{
allDistances = other.allDistances; // \ru расстояние и параметры на поверхностях
midDistance = other.midDistance; // \ru среднее расстояние
minDistance = other.minDistance; // \ru минимальное расстояние
maxDistance = other.maxDistance; // \ru максимальное расстояние
sorted = other.sorted; // \ru признак сортированности
}
private:
MbMinMaxItemItemDistances( const MbMinMaxItemItemDistances & );
};
//------------------------------------------------------------------------------
// MbMinMaxSurfSurfDists typedefs
// ---
typedef MbMinMaxItemItemDistances<double, double> MbMinMaxCurvCurvDists;
typedef MbMinMaxItemItemDistances<double, MbCartPoint> MbMinMaxCurvSurfDists;
typedef MbMinMaxItemItemDistances<MbCartPoint, double> MbMinMaxSurfCurvDists;
typedef MbMinMaxItemItemDistances<MbCartPoint, MbCartPoint> MbMinMaxSurfSurfDists;
DEPRECATE_DECLARE_REPLACE( MbMinMaxSurfSurfDists )
typedef MbMinMaxItemItemDistances<MbCartPoint, MbCartPoint> MbMinMaxSurfDists; // old
//------------------------------------------------------------------------------
/** \brief \ru Экстремальные расстояния между поверхностями.
\en Extreme distances between surfaces. \~
\details \ru Экстремальные расстояния между поверхностями по сетке на первой поверхности,
причем замеры осуществляются в заданном направлении (если есть вектор)
или по нормалям к первой поверхности.
\en Extreme distances between surfaces by mesh on the first surface,
measurements are performed in a given direction (if the vector is set)
or by normals of the first surface. \~
\param[in] surface1 - \ru Первая поверхность.
\en The first surface. \~
\param[in] u1cnt - \ru Количество точек по u (первая поверхность).
\en The number of points by u (the first surface) \~
\param[in] v1cnt - \ru Количество точек по v (первая поверхность).
\en The number of points by v (the first surface) \~
\param[in] dir - \ru Вектор заданного направления (если нет, то по нормали).
\en The vector of direction (if not set then by the normal). \~
\param[in] orient - \ru Относительное направление поиска.
\en Relative search direction. \~
\param[in] useEqualDistances - \ru Оставлять равные расстояния.
\en Whether to use the equal distances. \~
\param[in] surface2 - \ru Вторая поверхность.
\en The second surface. \~
\param[in,out] nMin - \ru Количество регистрируемых минимумов.
\en The number of recorded minimums. \~
\param[in,out] nMax - \ru Количество регистрируемых максимумов.
\en The number of recorded maximums. \~
\param[out] allResults - \ru Все результаты.
\en All results. \~
\param[out] minResults - \ru Результаты-минимумы.
\en Results-minimums. \~
\param[out] maxResults - \ru Результаты-максимумы.
\en Results-maximums. \~
\param[in,out] indicator - \ru Интерфейс-индикатор процесса выполнения.
\en Interface-indicator of the execution process. \~
\return \ru Возвращает результат замера (получен, не получен или же процесс был прерван).
\en Returns the result of measurement (obtained, not obtained, or the process has been aborted). \~
\ingroup Algorithms_3D
*/ // ---
//DEPRECATE_DECLARE_REPLACE( MinMaxSurfaceSurfaceGridDistances )
MATH_FUNC (MbeProcessState) MinMaxDistances( const MbSurface & surface1,
ptrdiff_t u1cnt,
ptrdiff_t v1cnt,
const MbVector3D * dir,
const MbeSenseValue & orient,
bool useEqualDistances,
const MbSurface & surface2,
ptrdiff_t & nMin,
ptrdiff_t & nMax,
MbMinMaxSurfSurfDists & allResults,
MbMinMaxSurfSurfDists & minResults,
MbMinMaxSurfSurfDists & maxResults,
IProgressIndicator * indicator = nullptr );
//------------------------------------------------------------------------------
/** \brief \ru Параметры операции сеточного поиска минимумов и максимумов.
\en Parameters of the operation of the grid search for minima and maxima. \~
\details \ru Параметры операции сеточного поиска минимумов и максимумов расстояний между объектами.
\en Parameters of the grid search operation for minima and maxima of distances between objects. \~
\ingroup Algorithms_3D
*/ // ---
class MATH_CLASS MbMinMaxGridDistancesParams {
public:
c3d::ConstSpaceItemSPtr srcItem; ///< \ru Базовый объект (кривая или поверхность). \en Base object (curve or surface). \~
c3d::IndicesPair srcSplitsCount; ///< \ru Количество разбиений (точек). \en Number of partitions (points). \~
c3d::ConstSpaceItemSPtr dstItem; ///< \ru Целевой объект (кривая или поверхность). \en Target object (curve or surface). \~
MbVector3D projDirection; ///< \ru Вектор заданного направления (если нет, то по нормали). \en he vector of direction (if not set then by the normal). \~
MbeSenseValue projOrient; ///< \ru Относительное направление поиска. \en Relative search direction. \~
bool useEqualDistances; ///< \ru Оставлять равные расстояния. \en Whether to use the equal distances. \~
size_t desiredMinimaNumber; ///< \ru Желаемое число выдаваемых минимумов. \en Desired minima number.
size_t desiredMaximaNumber; ///< \ru Желаемое число выдаваемых максимумов. \en Desired maxima number.
VERSION version; ///< \ru Версия. \en Version.
private:
mutable IProgressIndicator * progress; ///< \ru Индикатор прогресса выполнения операции. \en A progress indicator of the operation.
private:
MbMinMaxGridDistancesParams(); // \ru Не реализовано. \en Not implemented.
public:
/// \ru Конструктор по параметрам. \en Constructor by parameters.
MbMinMaxGridDistancesParams( const MbSurface & srcSurface,
size_t srcUCnt,
size_t srcVCnt,
const MbSurface & dstSurface,
VERSION ver = Math::DefaultMathVersion() )
: srcItem ( &srcSurface )
, srcSplitsCount ( srcUCnt, srcVCnt )
, dstItem ( &dstSurface )
, projDirection ( )
, projOrient ( orient_BOTH )
, useEqualDistances ( false )
, desiredMinimaNumber( 1 )
, desiredMaximaNumber( 1 )
, version ( ver )
, progress ( nullptr )
{}
/// \ru Конструктор по параметрам. \en Constructor by parameters.
MbMinMaxGridDistancesParams( const MbSurface & srcSurface,
size_t srcUCnt,
size_t srcVCnt,
const MbVector3D * dir,
const MbeSenseValue & orient,
bool useEqualDists,
const MbSurface & dstSurface,
size_t nMin,
size_t nMax,
VERSION ver = Math::DefaultMathVersion() )
: srcItem ( &srcSurface )
, srcSplitsCount ( srcUCnt, srcVCnt )
, dstItem ( &dstSurface )
, projDirection ( )
, projOrient ( orient )
, useEqualDistances ( useEqualDists )
, desiredMinimaNumber( nMin )
, desiredMaximaNumber( nMax )
, version ( ver )
, progress ( nullptr )
{
SetProjectionDirection( dir, orient );
}
/// \ru Конструктор по параметрам. \en Constructor by parameters.
MbMinMaxGridDistancesParams( const MbCurve3D & srcCurve,
size_t srcTCnt,
const MbSurface & dstSurface,
VERSION ver = Math::DefaultMathVersion() )
: srcItem ( &srcCurve )
, srcSplitsCount ( srcTCnt, 0 )
, dstItem ( &dstSurface )
, projDirection ( )
, projOrient ( orient_BOTH )
, useEqualDistances ( false )
, desiredMinimaNumber( 1 )
, desiredMaximaNumber( 1 )
, version ( ver )
, progress ( nullptr )
{}
/// \ru Конструктор по параметрам. \en Constructor by parameters.
MbMinMaxGridDistancesParams( const MbCurve3D & srcCurve,
size_t srcTCnt,
const MbCurve3D & dstCurve,
VERSION ver = Math::DefaultMathVersion() )
: srcItem ( &srcCurve )
, srcSplitsCount ( srcTCnt, 0 )
, dstItem ( &dstCurve )
, projDirection ( )
, projOrient ( orient_BOTH )
, useEqualDistances ( false )
, desiredMinimaNumber( 1 )
, desiredMaximaNumber( 1 )
, version ( ver )
, progress ( nullptr )
{}
public:
/// \ru Получить базовый объект. \en Get base object.
const MbSpaceItem & GetBaseItem () const { return *srcItem; }
/// \ru Получить целевой объект. \en Get target object.
const MbSpaceItem & GetTargetItem() const { return *dstItem; }
/// \ru Получить количество разбиений базового объекта. \en Get base object splits count.
const c3d::IndicesPair & GetBaseSplitsCount() const { return srcSplitsCount; }
/// \ru Получить общий вектора поиска. \en Get general search direction.
bool GetProjectionDirection( MbVector3D & dir, MbeSenseValue & orient ) const
{
if ( projDirection.Length() > LENGTH_EPSILON ) {
dir = projDirection;
orient = projOrient;
return true;
}
return false;
}
/// \ru Получить общий вектора поиска. \en Get general search direction.
bool GetUseEqualDistances() const { return useEqualDistances; }
/// \ru Получить желаемое число выдаваемых минимумов. \en Get desired minima number.
size_t GetDesiredMinimaNumber() const { return desiredMinimaNumber; }
/// \ru Получить желаемое число выдаваемых максимумов. \en Get desired maxima number.
size_t GetDesiredMaximaNumber() const { return desiredMaximaNumber; }
/// \ru Получить версию. \en Get version.
VERSION GetVersion() const { return version; }
public:
/// \ru Установить общее направление поиска. \en Set general search direction.
bool SetProjectionDirection( const MbVector3D * dirPtr, MbeSenseValue orient )
{
if ( dirPtr != nullptr ) {
const MbVector3D & dir = *dirPtr;
double dirLen = dir.Length();
if ( dirLen > LENGTH_EPSILON && dirLen < c3d::MAX_LENGTH ) {
projDirection = dir;
projOrient = orient;
return true;
}
}
return false;
}
/// \ru Установить флаг использования одинаковых расстояний. \en Set flag to use equal distances.
void SetUseEqualDistances( bool useEqualDists ) { useEqualDistances = useEqualDists; }
/// \ru Установить желаемые числа выдаваемых минимумов и максимумов. \en Get desired minima and maxima numbers.
void SetDisiredMinMaxNumbers( size_t minNum, size_t maxNum ) { desiredMinimaNumber = minNum; desiredMaximaNumber = maxNum; }
public:
/// \ru Установить внешний индикатор прогресса выполнения. \en Set external progress indicator.
void SetProgressIndicator( IProgressIndicator * prog ) { progress = prog; }
/// \ru Установить внешний индикатор прогресса выполнения. \en Set external progress indicator.
IProgressIndicator * TakeProgressIndicator() const { return progress; }
OBVIOUS_PRIVATE_COPY( MbMinMaxGridDistancesParams )
};
//------------------------------------------------------------------------------
/** \brief \ru Результаты операции сеточного поиска минимумов и максимумов.
\en Results of the operation of the grid search for minima and maxima. \~
\details \ru Результаты операции сеточного поиска минимумов и максимумов расстояний между объектами.
\en Results of the grid search operation for minima and maxima of distances between objects. \~
\ingroup Algorithms_3D
*/ // ---
template <class Param1, class Param2>
class MbMinMaxGridDistancesResults {
public:
MbMinMaxItemItemDistances<Param1, Param2> allResults; ///< \ru Все результаты. \en All results. \~
MbMinMaxItemItemDistances<Param1, Param2> minResults; ///< \ru Результаты-минимумы. \en Results-minimums. \~
MbMinMaxItemItemDistances<Param1, Param2> maxResults; ///< \ru Результаты-максимумы. \en Results-maximums. \~
public:
/// \ru Получить фактическое число минимумов. \en Get real minima number.
size_t GetActualMinimaNumber() const { return minResults.GetCount(); }
/// \ru Получить фактическое число максимумов. \en Get desired maxima number.
size_t GetActualMaximaNumber() const { return maxResults.GetCount(); }
};
//------------------------------------------------------------------------------
/** \brief \ru Экстремальные расстояния между объектами (кривыми или поверхностями).
\en Extreme distances between objects (curves or surfaces). \~
\details \ru Экстремальные расстояния между объектами по сетке на первом объекте,
причем замеры выполняются в заданном направлении (если есть вектор)
или по нормалям к первому объекту.
\en Extreme distances between objects along the grid on the first object,
and measurements are taken in a given direction (if there is a vector)
or along the normal to the first object. \~
\param[in] params - \ru Параметры операции сеточного поиска минимумов и максимумов.
\en Parameters of the operation of the grid search for minima and maxima. \~
\param[out] results - \ru Результаты операции сеточного поиска минимумов и максимумов.
\en Results of the operation of the grid search for minima and maxima. \~
\return \ru Возвращает результат замера (получен, не получен или же процесс был прерван).
\en Returns the result of measurement (obtained, not obtained, or the process has been aborted). \~
\ingroup Algorithms_3D
*/ // ---
MATH_FUNC (MbeProcessState) MinMaxSurfaceSurfaceGridDistances( const MbMinMaxGridDistancesParams & params,
MbMinMaxGridDistancesResults<MbCartPoint, MbCartPoint> & results );
#endif // __ALG_DIMENSION_H