Files
Extern/C3d/Include/func_composite_function.h
SaraP 827b79f766 Extern :
- C3d aggiornamento delle librerie ( 117987).
2024-04-16 14:59:59 +02:00

329 lines
23 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru Составная функция.
\en Composite Function. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __FUNC_COMPOSITE_FUNCTION_H
#define __FUNC_COMPOSITE_FUNCTION_H
#include <function.h>
#include <templ_sptr.h>
#include <templ_rp_array.h>
#include <mb_enum.h>
//------------------------------------------------------------------------------
/** \brief \ru Составная функция.
\en Composite function. \~
\details \ru Скалярная составная функция скалярного параметра состоит из набора функций (сегментов). \n
В составной функции начало каждого последующего сегмента стыкуется с концом предыдущего.
Составная функция является замкнутой, если конец последнего сегмента стыкуется с началом первого сегмента.\n
Начальное значение параметра составной функции равно нулю.
Параметрическая длина составной функции равна сумме параметрических длин составляющих её сегментов. \n
В качестве сегментов составной функции не используются другие составные функции.
Если составную функцию нужно построить на основе других составных функций,
то последние должны рассматриваться как совокупность составляющих их функций, а не как единые функции.\n
\en Scalar composite function of scalar parameter consists of a set of functions (segments). \n \~
The beginning of each subsequent segment of composite function is joined to the end of the previous one.
Composite function is closed if the end of last segment is joined to the beginning of the first segment.\n
If the segments of a composite function are not smoothly joined then the composite function will have breaks.
The initial value of the composite function is equal to zero.
The parametric length of a composite function is equal to the sum of the parametric lengths of components of its segments. \n
Other composite curves are not used as segments of the composite function.
If it is required to create a composite function based on other composite functions,
then the latter must be regarded as a set of their functions, and not as single functions. \n
\ingroup Functions
*/
// ---
class MATH_CLASS MbCompositeFunction : public MbFunction {
protected :
RPArray<MbFunction> segments; ///< \ru Множество сегментов составной функции. \en A set of composite function segments.
bool closed; ///< \ru Признак замкнутости функции. \en An attribute of function closedness.
double paramLength; ///< \ru Параметрическая длина функции. \en Parametric length of a composite function.
public :
/// \ru Конструктор по функции. \en Constructor by function.
MbCompositeFunction( MbFunction & segment, bool same ); // \ru same - функции или их копии \en same - functions or their copies
/// \ru Конструктор по набору функции. \en Constructor by functions.
template <class FunctionVector>
MbCompositeFunction( const FunctionVector & initSegments, bool same ); // \ru same - функции или их копии \en same - functions or their copies
protected:
MbCompositeFunction(); ///< \ru Пустой контур. \en Empty composite function.
MbCompositeFunction( const MbCompositeFunction & ); ///< \ru Конструктор копирования. \en Copy constructor.
public :
virtual ~MbCompositeFunction();
public:
// \ru Общие функции математического объекта. \en Common functions of mathematical object.
MbeFunctionType IsA () const override; // \ru Тип элемента. \en A type of element.
MbFunction & Duplicate() const override; // \ru Сделать копию элемента. \en Create a copy of the element.
bool IsSame ( const MbFunction & other, double accuracy = LENGTH_EPSILON ) const override; // \ru Являются ли объекты равными. \en Determine whether objects are equal
bool IsSimilar( const MbFunction & ) const override; // \ru Являются ли объекты подобными. \en Determine whether objects are similar.
bool SetEqual ( const MbFunction & ) override; // \ru Сделать равным \en Make equal
void GetProperties( MbProperties & ) override; // \ru Выдать свойства объекта \en Get properties of the object
void SetProperties( const MbProperties & ) override; // \ru Записать свойства объекта \en Set properties of the object
double GetTMax () const override; // \ru Вернуть максимальное значение параметра \en Get the maximum value of parameter
double GetTMin () const override; // \ru Вернуть минимальное значение параметра \en Get the minimum value of parameter
bool IsClosed () const override; // \ru Замкнутость функции \en A function closedness
void SetClosed( bool cl ) override; // \ru Замкнутость функции \en A function closedness
double Value ( double & t ) const override; // \ru Значение функции для t \en The value of function for a given t
double FirstDer ( double & t ) const override; // \ru Первая производная по t \en The first derivative with respect to t
double SecondDer ( double & t ) const override; // \ru Вторая производная по t \en The second derivative with respect to t
double ThirdDer ( double & t ) const override; // \ru Третья производная по t \en The third derivative with respect to t
double _Value ( double t ) const override; // \ru Значение функции для t \en The value of function for a given t
double _FirstDer ( double t ) const override; // \ru Первая производная по t \en The first derivative with respect to t
double _SecondDer ( double t ) const override; // \ru Вторая производная по t \en The second derivative with respect to t
double _ThirdDer ( double t ) const override; // \ru Третья производная по t \en The third derivative with respect to t
// \ru Вычислить значение и производные. \en Calculate value and derivatives of object for given parameter. \~
void Explore( double & t, bool ext,
double & val, double & fir, double * sec, double * thr ) const override;
// \ru Вычислить аргумент t по значению функции. \en Calculate the argument t by the function value.
double Argument( double & val ) const override;
void Inverse( MbRegTransform * iReg = nullptr ) override; // \ru Изменить направление \en Change direction
double Step( double t, double sag ) const override;
double DeviationStep( double t, double angle ) const override;
/// \ru Создать функцию из части функции между параметрами t1 и t2 c выбором направления sense. \en Create a function in part of the function between the parameters t1 and t2 choosing the direction.
MbFunction * Trimmed( double t1, double t2, int sense ) const override;
// \ru Разбить функцию точкой с параметром t и вернуть отрезанную часть. \en Function break by the parameter t, and cut off part of the function: begs == true - save the initial half, beg == false - save the final half.
MbFunction * BreakFunction( double t, bool beg ) override;
void Break( double t1, double t2 ); ///< \ru Выделить часть функции. \en Select a part of a function.
double MinValue ( double & t ) const override; // \ru Минимальное значение функции \en The minimum value of function
double MaxValue ( double & t ) const override; // \ru Максимальное значение функции \en The maximum value of function
double MidValue () const override; // \ru Среднее значение функции \en The middle value of function
bool IsGood () const override; // \ru Корректность функции \en Correctness of function
bool IsConst() const override;
bool IsLine () const override;
/// \ru Сместить функцию. \en Shift a function.
void SetOffsetFunc( double off, double scale ) override;
bool SetLimitParam( double newTMin, double newTMax ) override; // \ru Установить область изменения параметра \en Set range of parameter
void SetLimitValue( size_t n, double newValue ) override; // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point)
double GetLimitValue( size_t n ) const override; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point)
void SetLimitDerive( size_t n, double newValue, double dt ) override; // \ru Установить значение на конце ( 1 - в начале, 2 - в конце) \en Set the value at the end (1 - at start point, 2 - at end point)
double GetLimitDerive( size_t n ) const override; // \ru Дать значение на конце ( 1 - в начале, 2 - в конце) \en Get the value at the end (1 - at start point, 2 - at end point)
bool InsertValue( double t, double newValue ) override; // \ru Установить значение для параметра t. \en Set the value for the parameter t.
/// \ ru Определение точек излома контура. \en The determination of contour smoothness break points.
void BreakPoints( std::vector<double> & vBreaks, double precision = ANGLE_REGION ) const override;
/** \} */
/** \ru \name Функции работы с сегментами контура
\en \name Function for working with segments of contour
\{ */
/// \ru Инициализация по набору кривых (sameCurves - функции или их копии). \en Initialize by curves (sameCurves - curves or their copies).
template <class FunctionVector>
bool Init( const FunctionVector & initSegments, bool same, bool cls );
/** \brief \ru Найти сегмент контура.
\en Find a contour segment. \~
\details \ru Найти сегмент контура по параметру контура. \n
\en Find a contour segment by parameter on contour. \n \~
\param[in,out] t - \ru Параметр контура.
\en Composite function parameter. \~
\param[out] tSeg - \ru Параметр сегмента контура.
\en Composite function segment parameter. \~
\return \ru Возвращает номер сегмента в случае успешного выполнения или -1.
\en Returns the segment number in case of successful execution or -1. \~
*/
ptrdiff_t FindSegment( double & t, double & tSeg ) const;
/** \brief \ru Найти параметр контура.
\en Find a contour segment. \~
\details \ru Найти параметр контура по номеру сегмента и параметру сегмента. \n
\en Find a contour parameter by segment number and segment parameter. \n \~
\param[in] iSeg - \ru Номер сегмента (индекс).
\en Segment number (index). \~
\param[in] tSeg - \ru Параметр сегмента контура.
\en Segment parameter. \~
\return \ru Возвращает параметр контура или UNDEFINED_DBL в случае неудачи.
\en Returns the contour parameter or UNDEFINED_DBL if failure. \~
*/
double FindParameter( size_t iSeg, double tSeg ) const;
size_t GetSegmentsCount() const { return segments.size(); } ///< \ru Выдать количество сегментов контура. \en Get the number of contour segments.
template <class CurvesVector>
void GetSegments( CurvesVector & curves ) const; ///< \ru Получить функции контура. \en Get contour segments.
void DetachSegments(); ///< \ru Отцепить все сегменты контура. \en Detach all segments of contour.
void DeleteSegments(); ///< \ru Отсоединить используемые сегменты и удалить остальные. \en Delete used segments and remove other segments.
void DeleteSegment( size_t ind ); ///< \ru Удалить сегмент контура. \en Delete the segment of contour.
MbFunction * DetachSegment( size_t ind ); ///< \ru Отцепить сегмент контура. \en Detach the segment of contour.
const MbFunction * GetSegment( size_t ind ) const { return segments[ind]; } ///< \ru Выдать сегмент контура по индексу. \en Get contour segment by the index.
MbFunction * SetSegment( size_t ind ) { return segments[ind]; } ///< \ru Выдать сегмент контура по индексу. \en Get contour segment by the index.
void SetSegment ( MbFunction & newSegment, size_t ind, bool same ); ///< \ru Заменить сегмент в контуре. \en Replace a segment in the contour.
void AddSegment ( MbFunction & newSegment, bool same ); ///< \ru Добавить сегмент в контур. \en Add a segment to the contour.
void AddAtSegment ( MbFunction & newSegment, size_t ind, bool same ); ///< \ru Добавить сегмент в контур перед сегментом с индексом ind. \en Add a segment to the contour before the segment with index ind.
void AddAfterSegment( MbFunction & newSegment, size_t ind, bool same ); ///< \ru Добавить сегмент в контур после сегмента с индексом ind. \en Add a segment to the contour after the segment with index ind.
/** \brief \ru Добавить (усеченную) копию сегмента в конец контура.
\en Add a (truncated) segment copy to the end of the contour. \~
\details \ru Добавить (усеченную) копию сегмента в конец контура. \n
\en Add a (truncated) segment copy to the end of the contour. \n \~
\param[in] pBasis- \ru Исходная функция.
\en Initial function. \~
\param[in] t1 - \ru Начальный параметр усечения.
\en Truncation starting parameter. \~
\param[in] t2 - \ru Конечный параметр усечения.
\en Truncation ending parameter. \~
\param[in] sense - \ru Направление усеченной функции относительно исходной. \n
sense = 1 - направление функции сохраняется.
sense = -1 - направление функции меняется на обратное.
\en Direction of a trimmed function in relation to an initial function.
sense = 1 - direction does not change.
sense = -1 - direction changes to the opposite value. \~
\return \ru Возвращает в случае успешного выполнения ненулевой указатель на добавленную кривую.
\en Returns, if successful, a non-zero pointer to the added function. \~
*/
MbFunction * AddSegment( MbFunction & pBasis, double t1, double t2, int sense );
void SegmentsAdd( MbFunction & newSegment, bool calculateParamLength = true ); ///< \ru Добавить сегмент в контур без проверки. \en Add a segment to the contour without checking.
/// \ru Сбросить переменные кэширования. \en Reset variables caching.
void Clear() {
CalculateParamLengthAndClosed(); // \ru Параметрическая длина контура. \en Parametric length of a contour.
}
/// \ru Управление распределением памяти в массиве segments. \en Control of memory allocation in the array "segments".
void SegmentsReserve( size_t additionalSpace ) { segments.Reserve( additionalSpace ); } ///< \ru Зарезервировать место. \en Reserve space.
void SegmentsAdjust () { segments.Adjust(); } ///< \ru Удалить лишнюю память. \en Free the unnecessary memory.
/// \ru Проверка непрерывности контура. \en Check for contour continuity.
bool CheckConnection( double eps = METRIC_PRECISION ) const;
void CalculateParamLength(); ///< \ru Рассчитать параметрическую длину. \en Calculate parametric length.
void CheckClosed( double eps ); ///< \ru Установить признак замкнутости контура. \en Set the closedness attribute of contour.
private:
void SetClosed(); // \ru Проверить и установить признак замкнутости контура. \en Check and set closedness attribute of contour.
void CalculateParamLengthAndClosed(); // \ru Посчитать параметрическую длину и признак замкнутости \en Calculate parametric length and closedness attribute
ptrdiff_t _FindSegment( double & t, double & tSeg ) const; // \ru Нахождение сегмента контура \en Finding of a contour segment
DECLARE_PERSISTENT_CLASS_NEW_DEL( MbCompositeFunction )
MbCompositeFunction & operator = ( const MbCompositeFunction & ); // Not implemented.
}; // MbCompositeFunction
IMPL_PERSISTENT_OPS( MbCompositeFunction )
//------------------------------------------------------------------------------
// \ru Конструктор по набору функций. \en Constructor by functions.
// ---
template <class FunctionVector>
MbCompositeFunction::MbCompositeFunction( const FunctionVector & initSegments, bool same )
: MbFunction ( )
, segments ( initSegments.size(), 1 )
, closed ( false )
, paramLength( 0.0 ) // параметрическая длина контура не рассчитана
{
const size_t count = initSegments.size();
if ( count > 0 ) {
for ( size_t i = 0; i < count; ++i ) {
const MbFunction * initSegment = initSegments[i];
if ( initSegment != nullptr ) {
if ( initSegment->IsA() == ft_CompositeFunction ) { // \ru Присланный контур удаляет владелец. \en contour should be deleted by owner.
const MbCompositeFunction * cntr = static_cast<const MbCompositeFunction *>( initSegment );
MbCompositeFunction * contour = const_cast<MbCompositeFunction *>( cntr );
size_t cnt = contour->segments.size();
for ( size_t j = 0; j < cnt; j++ ) {
MbFunction * seg = contour->segments[j];
if ( seg != nullptr ) {
MbFunction * segment = same ? seg : static_cast<MbFunction *>( &seg->Duplicate() );
segments.push_back( segment );
segment->AddRef();
}
}
}
else {
MbFunction * segment = same ? const_cast<MbFunction *>( initSegment ) : static_cast<MbFunction *>( &initSegment->Duplicate() );
segments.push_back( segment );
segment->AddRef();
}
}
}
CalculateParamLengthAndClosed();
}
}
//------------------------------------------------------------------------------
// \ru Инициализация по набору функций. \en Initialize by functions.
// ---
template <class FunctionVector>
bool MbCompositeFunction::Init( const FunctionVector & initSegments, bool sames, bool cls )
{
size_t count = initSegments.size();
if ( count > 0 ) {
::AddRefItems( initSegments );
DeleteSegments();
segments.reserve( count );
for ( size_t i = 0; i < count; ++i ) {
const MbFunction * initSegment = initSegments[i];
if ( initSegment != nullptr ) {
if ( initSegment->IsA() == ft_CompositeFunction ) { // \ru Присланный контур удаляет владелец. \en contour should be deleted by owner.
const MbCompositeFunction * cntr = static_cast<const MbCompositeFunction *>( initSegment );
MbCompositeFunction * contour = const_cast<MbCompositeFunction *>( cntr );
size_t cnt = contour->segments.size();
for ( size_t j = 0; j < cnt; j++ ) {
MbFunction * seg = contour->segments[j];
if ( seg != nullptr ) {
MbFunction * segment = sames ? seg : static_cast<MbFunction *>( &seg->Duplicate() );
segments.push_back( segment );
segment->AddRef();
}
}
}
else {
MbFunction * segment = sames ? const_cast<MbFunction *>( initSegment ) : static_cast<MbFunction *>( &initSegment->Duplicate() );
segments.push_back( segment );
segment->AddRef();
}
}
}
::DecRefItems( initSegments );
CalculateParamLength();
closed = cls;
return true;
}
return false;
}
//------------------------------------------------------------------------------
// \ru Получить функции. \en Get segments.
// ---
template <class CurvesVector>
void MbCompositeFunction::GetSegments( CurvesVector & funcs ) const
{
size_t segmentsCnt = segments.size();
funcs.reserve( funcs.size() + segmentsCnt );
SPtr<MbFunction> function;
for ( size_t k = 0; k < segmentsCnt; ++k ) {
function = const_cast<MbFunction *>(segments[k]);
if ( function != nullptr ) {
funcs.push_back( function );
::DetachItem( function );
}
}
}
#endif // __FUNC_COMPOSITE_FUNCTION_H