Files
Extern/C3d/Include/func_nurbs_function.h
T
SaraP d6eac07eea Extern :
- C3d aggiornamento librerie ( 118019).
2024-12-12 08:37:52 +01:00

252 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru NURBS функция.
\en NURBS function. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __FUNC_NURBS_FUNCTION_H
#define __FUNC_NURBS_FUNCTION_H
#include <function.h>
#include <templ_s_array.h>
#include <mb_nurbs_function.h>
#include <tool_multithreading.h>
//------------------------------------------------------------------------------
/** \brief \ru NURBS функция.
\en NURBS function. \~
\details \ru NURBS функция определяется контрольными точками pointList,
весами контрольных точек weights, узловым вектором knots и порядком сплайна degree. \n
\en NURBS function is defined by 'pointList' control points,
weights of control points ('weights'), knot vector ('knots') and order of spline ('degree').\n. \n \~
\ingroup Functions
*/
// ---
class MATH_CLASS MbNurbsFunction : public MbFunction {
protected:
size_t degree; ///< \ru Порядок В-сплайна. \en Order of B-spline.
SArray<double> pointList; ///< \ru Множество контрольных точек. \en Set of control points.
SArray<double> weights; ///< \ru Множество весов контрольных точек. \en Set of weights of the control points.
SArray<double> knots; ///< \ru Узловой вектор. \en Knot vector.
ptrdiff_t uppIndex; ///< \ru Количество участков кривой (равно количество контрольных точек минус единица). \en Count of curve pieces (is equal to count of control points minus one).
ptrdiff_t uppKnotsIndex; ///< \ru Последний индекс узлового вектора. \en Last index of knot vector.
bool closed; ///< \ru Признак замкнутости кривой. \en An attribute of curve closedness.
//------------------------------------------------------------------------------
/** \brief \ru Вспомогательные данные.
\en Auxiliary data. \~
\details \ru Вспомогательные данные служат для ускорения работы объекта.
\en Auxiliary data are used for fast calculations. \n \~
*/
// ---
class MbNurbsFunctionAuxiliaryData : public AuxiliaryData {
public:
Array2<double> values;
SArray<double> pointsM;
SArray<double> weightM;
public:
MbNurbsFunctionAuxiliaryData() : values(), pointsM(), weightM() {}
MbNurbsFunctionAuxiliaryData( const MbNurbsFunctionAuxiliaryData & ) : AuxiliaryData {}, values(), pointsM(), weightM() {}
virtual ~MbNurbsFunctionAuxiliaryData() {}
};
mutable CacheManager<MbNurbsFunctionAuxiliaryData> cache;
public :
/// \ru Конструктор по точкам и признаку замкнутости. \en Constructor by points and an attribute of closedness.
MbNurbsFunction( size_t d, const SArray<double> & values, bool cls );
/// \ru Конструктор по точкам, параметрам и признаку замкнутости. \en Constructor by points, parameters and an attribute of closedness.
MbNurbsFunction( size_t d, const SArray<double> & values, const SArray<double> & knots, bool cls );
private:
/// \ru Конструктор. \en Constructor.
MbNurbsFunction();
MbNurbsFunction( const MbNurbsFunction & );
public :
virtual ~MbNurbsFunction();
public:
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Сплайн, проходящий через заданные точки при заданных параметрах.\n
В случае замкнутости нужно передавать массив с совпадением первой и последней точек.\n
\en Spline passing through given points at given parameters.\n
In case of closedness it is necessary to pass the array with coincidence of the first and the last points.\n \~
\param[in] degree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] cls - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] points - \ru Набор точек, через которые проходит сплайн.
\en Set of points which the spline passes through. \~
\param[in] params - \ru Последовательность узловых параметров.
\en Sequence of knot parameters. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbsFunction * CreateThrough( size_t deg, bool cls, const SArray<double> & points,
const SArray<double> & params, const SArray<double> * aKnots = nullptr );
/// \ru Инициализация сплайна, проходящего через заданные точки при заданных параметрах. В случае замкнутости нужно передавать массив с совпадением первой и последней точек.\n \~
/// \en Initialization of spline passing through given points at given parameters. In case of closedness it is necessary to pass the array with coincidence of the first and the last points.\n \~
bool InitThrough( size_t deg, bool cls, const SArray<double> & points, const SArray<double> & params, const SArray<double> * aKnots = nullptr );
private:
/// \ru Инициализация по точкам и признаку замкнутости. \en Initialization by values and an attribute of closedness.
template <class DoubleVector>
bool Init( size_t initDegree, const DoubleVector & initPoints, bool initClosed )
{
if ( ::IsValidNurbsParams( initDegree, initClosed, initPoints.size() ) ) {
degree = initDegree;
closed = initClosed;
uppIndex = (ptrdiff_t)initPoints.size() - 1;
pointList.assign( initPoints.begin(), initPoints.end() );
weights.assign( initPoints.size(), 1.0 );
uppKnotsIndex = ::DefineKnotsVector( degree, closed, uppIndex, knots );
return true;
}
return false;
}
/// \ru Инициализация по точкам, параметрам и признаку замкнутости. \en Initialization by values, knots and an attribute of closedness.
template <class DoubleVector>
bool Init( size_t initDegree, const DoubleVector & initPoints, const DoubleVector & initKnots, bool initClosed )
{
if ( ::IsValidNurbsParams( initDegree, initClosed, initPoints.size(), initPoints.size(), initKnots.size() ) ) {
degree = initDegree;
closed = initClosed;
pointList = initPoints;
weights.assign( initPoints.size(), 1.0 );
knots = initKnots;
uppIndex = (ptrdiff_t)pointList.size() - 1;
uppKnotsIndex = (ptrdiff_t)knots.size() - 1;
SetClamped();
return true;
}
return false;
}
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 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 curve 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;
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 pdrdmeter t.
// \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;
MbFunction * Break( double t1, double t2 ) const; ///< \ru Выделить часть функции. \en Select a part of a function.
/// \ru Добавление нового узла; возвращает количество узлов, которые удалось вставить. \en Addition of a new knots; returns the number of knots which have been inserted.
size_t InsertKnots( double & newKnot, size_t multiplicity, double relEps );
/// \ru Удалить кратный внутренний узел id, num раз; вернуть количество удалений, которое удалось сделать. \en Remove multiple internal 'id' knot 'num' times, return count of removals was successfully made.
ptrdiff_t RemoveKnot( ptrdiff_t id, ptrdiff_t num, double relEps = Math::paramEpsilon, double absEps = Math::lengthEpsilon );
/// \ru Преобразовать узловой вектор в зажатый (если кривая замкнута и clm = false) или разжатый (если кривая не замкнута и clm = true). \en Transform knot vector to clamped (if curve is closed and clm = false) or unclamped (if curve is open and clm = true).
bool UnClamped( bool clm );
void SetClamped(); // \ru Делаем зажатый узловой вектор. \en Set clamped knots vector.
size_t GetValuesCount() const; // \ru Выдать количество опорных точек \en Get the number of control points
double GetValue( size_t index ) const; // \ru Дать значение точки по номеру \en Get the value of point by its number
bool SetValue( size_t index, double v ); // \ru Установить значение точки по номеру \en Set the value of point by its number
void GetValueList( SArray<double> & vals ) const; ///< \ru Вернуть массив контрольных значений. \en Get array of control values.
/// \ru Получить размер весового вектора. \en Get a size of weights vector.
size_t GetWeightsCount() const { return weights.size(); }
/// \ru Получить весовой вектор. \en Get a weights vector.
template <class WeightsVector>
void GetWeights( WeightsVector & wts, bool justSet = true ) const { if ( justSet ) { wts.clear(); }; std::copy( weights.begin(), weights.end(), std::back_inserter( wts ) ); }
/// \ru Получить значение элемента весового вектора по индексу. \en Get a weights vector element value by index.
double GetWeight( size_t ind ) const { return weights[ind]; }
/// \ru Получить значение элемента весового вектора по индексу. \en Get a weights vector element value by index.
double & SetWeight( size_t ind ) { return weights[ind]; }
/// \ru Получить размер узлового вектора. \en Get a size of knots vector.
size_t GetKnotsCount() const { return knots.size(); }
/// \ru Получить узловой вектор. \en Get a knots vector.
template <class KnotsVector>
void GetKnots( KnotsVector & kts, bool justSet = true ) const { if ( justSet ) { kts.clear(); }; std::copy( knots.begin(), knots.end(), std::back_inserter( kts ) ); }
/// \ru Получить значение элемента узлового вектора по индексу. \en Get a knots vector element value by index.
double GetKnot( size_t ind ) const { return knots[ind]; }
/// \ru Получить значение элемента узлового вектора по индексу. \en Get a knots vector element value by index.
double & SetKnot( size_t ind ) { return knots[ind]; }
/// \ru Вернуть максимальный индекс узлового вектора. \en Get the maximal index of knots vector.
ptrdiff_t GetUppKnotsIndex() const { return uppKnotsIndex; }
bool CheckParam( double & t ) const; // \ru Проверить параметр. \en Parameter check.
private:
// \ru Вычисление функции и веса. \en Calculating the function and weight.
bool CalculateValue( double & t, size_t deriveN, Array2<double> & values,
ptrdiff_t & left, double & valw, double & weig ) const;
// \ru Вычисление производной функции и производной веса. \en Calculating the function and weight derivatives.
void CalculateFirst( const Array2<double> & values, const ptrdiff_t & left,
SArray<double> & pointsM, SArray<double> & weightM,
double & firw, double & weig_ ) const;
void CalculateDerive( const Array2<double> & values, const ptrdiff_t & left, size_t deriveN,
SArray<double> & pointsM, SArray<double> & weightM,
double & derw, double & weig_ ) const;
void operator = ( const MbNurbsFunction & ); // \ru Не реализовано \en Not implemented
DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbsFunction )
};
IMPL_PERSISTENT_OPS( MbNurbsFunction )
#endif // __FUNC_NURBS_FUNCTION_H