Files
Extern/C3d/Include/cur_nurbs.h
T
SaraP 0a27141ada Extern :
- C3d aggiornamento librerie ( 118012).
2024-10-08 16:14:52 +02:00

1138 lines
82 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 Two-dimensional NURBS curve. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __CUR_NURBS_H
#define __CUR_NURBS_H
#include <templ_c_array.h>
#include <templ_array2.h>
#include <tool_multithreading.h>
#include <mb_homogeneous.h>
#include <mb_nurbs_function.h>
#include <mb_point_mating.h>
#include <cur_polycurve.h>
#include <alg_base.h>
#include <vector>
#include <iterator>
class MbLine;
class MbBezier;
class MbContour;
//------------------------------------------------------------------------------
/** \brief \ru NURBS кривая в двумерном пространстве.
\en NURBS curve in two-dimensional space. \~
\details \ru NURBS кривая определяется контрольными точками pointList,
весами контрольных точек weights, узловым вектором knots и порядком сплайна degree.\n
Аббревиатура NURBS получена из первых букв словосочетания Non-Uniform Rational B-Spline.
NURBS кривая не проходит через свои контрольные точки.
Узловой вектор knots должен представлять собой неубывающую последовательность действительных чисел.
Множества pointList и weights должны содержать одинаковое количество элементов.
Для не замкнутой кривой узловой вектор knots должен содержать количество элементов множества pointList плюс degree.
Для замкнутой кривой кривой узловой вектор knots должен содержать количество элементов множества pointList плюс 2*degree-1.
Минимальное значение параметра сплайна равно значению элемента узлового вектора с индексом degree-1.
Максимальное значение параметра сплайна равно значению элемента узлового вектора с индексом, равным последнему элементу минус degree-1.
Расчет кривой в каждой своей точке производится на основе нормированных неоднородных В-сплайнов.\n
Семейство В-сплайнов определяется заданной неубывающей последовательностью узловых параметров и заданным порядком B-сплайна.\n
\en NURBS curve is defined by 'pointList' control points,
weights of control points ('weights'), knot vector ('knots') and order of spline ('degree').\n
Abbreviation of NURBS is obtained from the first letters of the Non-Uniform Rational B-Spline phrase.
NURBS curve doesn't pass through its control points.
'knots' knot vector has to be not decreasing sequence of real numbers.
'pointList' and 'weights' sets have to contain the same count of elements.
For not closed curve 'knots' knot vector has to contain the count of elements of 'pointList' set plus 'degree'.
For closed curve 'knots' knot vector has to contain the count of elements of 'pointList' set plus 2*degree-1.
Minimal value of spline parameter is equal to value of element of knot vector with degree-1 index.
Maximal value of spline parameter is equal to value of element of knot vector with index, which is equal to index of last element minus degree-1.
Curve calculation at each point is performed by normalized non-uniform B-splines.\n
Family of B-splines is defined by given crescent sequence of knot parameters and given order of B-spline.\n \~
\ingroup Curves_2D
*/
// ---
class MATH_CLASS MbNurbs : public MbPolyCurve {
private:
size_t degree; ///< \ru Порядок В-сплайна. \en Order of B-spline.
ptrdiff_t uppKnotsIndex; ///< \ru Последний индекс узлового вектора. \en Last index of knot vector.
SArray<double> knots; ///< \ru Узловой вектор. \en Knot vector.
SArray<double> weights; ///< \ru Множество весов контрольных точек. \en Set of weights of the control points.
MbeNurbsCurveForm form; ///< \ru Форма кривой. \en Form of curve.
private:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/** \brief \ru Вспомогательные данные.
\en Auxiliary data. \~
\details \ru Вспомогательные данные служат для ускорения работы объекта.
\en Auxiliary data are used for fast calculations. \n \~
*/
// ---
class MbNurbsAuxiliaryData : public AuxiliaryData {
public:
double tCalc; ///< \ru Текущее значение параметра, по которому вычислены временные данные кривой. \en Current value of parameter the curve temporary data are calculated by.
double * nd; ///< \ru B - базис. \en B - basis.
MbHomogeneous * h0; ///< \ru Текущий сегмент. \en Current segment.
MbHomogeneous * h1; ///< \ru Текущий сегмент. \en Current segment.
MbHomogeneous * h2; ///< \ru Текущий сегмент. \en Current segment.
MbHomogeneous * h3; ///< \ru Текущий сегмент. \en Current segment.
double * wc; ///< \ru Насчитанные значения весов (может быть ноль). \en Calculated values of points (can be null).
MbVector rc[cdt_CountDer]; ///< \ru Насчитанные значения точек. \en Calculated values of points.
ptrdiff_t leftIndex; ///< \ru Левый индекс узлового вектора. \en Left index of knot vector.
double * m_left;
double * m_right;
public:
MbNurbsAuxiliaryData();
MbNurbsAuxiliaryData( const MbNurbsAuxiliaryData & init );
virtual ~MbNurbsAuxiliaryData();
void FreeMemory();
bool CatchMemory( ptrdiff_t, bool );
}; // MbNurbsAuxiliaryData
mutable CacheManager<MbNurbsAuxiliaryData> cache;
public://protected:
DEPRECATE_DECLARE MbNurbs(); ///< \deprecated \ru Метод устарел. \en The method is deprecated.
protected:
/** \brief \ru Конструктор.
\en Constructor. \~
\details \ru Конструктор по порядку, точкам, параметрам и признаку замкнутости. При недопустимых параметрах initDegree и points поведение кривой не определено.\n
\en Constructor by order, points, parameters and an attribute of closedness. If parameters initDegree and points is invalid then the curve behavior is undefined. \n \~
\param[in] degree - \ru Порядок сплайна. Должен быть больше единицы. Не должен превышать количество контрольных точек.
\en A spline order. It must be greater than unity. It shouldn't exceed count of control points. \~
\param[in] cls - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] points - \ru Набор контрольных точек. Количество точек должно быть больше или равно двум.
\en Set of control points. Count of points must be greater than or equal to two. \~
\param[in] weights - \ru Набор весов для контрольных точек. Количество весов должно соответствовать количеству точек.
\en Set of weights for control points. Count of weights must be equal to count of points. \~
\param[in] knots - \ru Последовательность узловых параметров.
\en Sequence of knot parameters. \~
*/
template <class PointsVector, class DoubleVector>
MbNurbs( size_t degree, bool cls, const PointsVector & points,
const DoubleVector * weights, const DoubleVector * knots );
MbNurbs( const MbNurbs & );
public :
virtual ~MbNurbs();
private:
static MbNurbs * Create();
public:
/** \brief \ru Создать копию сплайна.
\en Create copy of spline. \~
\details \ru Создать копию сплайна.\n
\en Create copy of spline.\n \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * Create( const MbNurbs & );
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Создать сплайн и установить параметры сплайна.\n
\en Create spline and set parameters of spline.\n \~
\param[in] initDegree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] initPoints - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] initClosed - \ru Признак замкнутости.
\en A closedness attribute. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
template <class PointsVector>
static MbNurbs * Create( ptrdiff_t initDegree, const PointsVector & initPoints, bool initClosed )
{
MbNurbs * resNurbs = Create();
if ( !resNurbs->Init( initDegree, initPoints, initClosed ) )
::DeleteItem( resNurbs );
return resNurbs;
}
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Создать сплайн и установить параметры сплайна.\n
\en Create spline and set parameters of spline.\n \~
\param[in] initDegree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] initPoints - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] initClosed - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] initWeights - \ru Набор весов для контрольных точек.
\en Set of weights for control points. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
template <class PointsVector, class DoubleVector>
static MbNurbs * Create( ptrdiff_t initDegree, const PointsVector & initPoints, bool initClosed,
const DoubleVector * initWeights )
{
MbNurbs * resNurbs = Create();
if ( !resNurbs->Init( initDegree, initPoints, initClosed, initWeights ) )
::DeleteItem( resNurbs );
return resNurbs;
}
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Создать сплайн и установить параметры сплайна.\n
\en Create spline and set parameters of spline.\n \~
\param[in] initDegree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] initClosed - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] initPoints - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] initWeights - \ru Набор весов для контрольных точек.
\en Set of weights for control points. \~
\param[in] initKnots - \ru Неубывающая последовательность весов.
\en Non-decreasing sequence of weights. \~
\param[in] initForm - \ru Тип построения.
\en Type of construction. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
template <class PointsVector, class DoubleVector>
static MbNurbs * Create( ptrdiff_t initDegree, bool initClosed, const PointsVector & initPoints,
const DoubleVector & initWeights, const DoubleVector & initKnots,
MbeNurbsCurveForm initForm = ncf_Unspecified )
{
MbNurbs * resNurbs = Create();
if ( !resNurbs->Init( initDegree, initClosed, initPoints, initWeights, initKnots, initForm ) )
::DeleteItem( resNurbs );
return resNurbs;
}
/** \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. \~
\param[in] aKnots - \ru Неубывающая последовательность узлов.
\en Nondecreasing sequence of knots. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * CreateThrough( size_t degree, bool cls, const SArray<MbCartPoint> & points,
const SArray<double> & params, SArray<double> * aKnots = nullptr );
/** \brief \ru Заполнить NURBS по данным parasolid.
\en Fill NURBS by parasolid data. \~
\details \ru Заполнить NURBS по данным parasolid.\n
\en Fill NURBS by parasolid data.\n \~
\param[in] degree - \ru Степень сплайна.
\en Order of spline. \~
\param[in] closed - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] rational - \ru Является ли кривая рациональной. Если true - строится NURBS, false - кривая Безье.
\en Whether the curve is rational. if true then NURBS is created, false - Bezier curve. \~
\param[in] count - \ru Количество контрольных точек.
\en Count of control points. \~
\param[in] verts - \ru Массив координат точек. Если сплайн рациональный, четвертая координата - вес точки.
\en An array of coordinates of points. If spline is rational, then the fourth coordinate - weight of point. \~
\param[in] vertsCount - \ru Количество элементов в массиве verts.
\en Count of elements in 'verts' array. \~
\param[in] mul - \ru Массив с данными о кратности каждого узла.
\en Array with multiplicity of each knot. \~
\param[in] mulCount - \ru Количество элементов в массиве mul.
\en Count of elements in 'mul' array. \~
\param[in] knots - \ru Массив со значениями параметров в узлах. Каждое значение представлено один раз.
Информация о кратности узла лежит в элементе массива mul с тем же номером.
\en Array with values of parameters at knots. Each value is presented only once.
Information about knot multiplicity is in the element of 'mul' array with the same index. \~
\param[in] knotsCount - \ru Количество элементов в массиве knots.
\en Count of elements in 'knots' array. \~
\param[in] scl - \ru Коэффициент масштабирования.
\en A scale factor. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * CreateParasolid( size_t degree, bool closed, bool rational, ptrdiff_t count,
const CcArray<double> & verts, ptrdiff_t vertsCount,
const CcArray<ptrdiff_t> & mul, ptrdiff_t mulCount,
const CcArray<double> & knots, ptrdiff_t knotsCount,
double scl );
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Создать сплайн и установить параметры сплайна.\n
\en Create spline and set parameters of spline. \n \~
\param[in] p1 - \ru Начальная точка, через которую проходит сплайн.
\en The initial point the spline passes through. \~
\param[in] v1 - \ru Касательный вектор к кривой в начальной точке.
\en A tangent vector to the curve at the start point. \~
\param[in] p2 - \ru Конечная точка, через которую проходит сплайн.
\en The final point the spline passes through. \~
\param[in] v2 - \ru Касательный вектор к кривой в конечной точке.
\en A tangent vector to the curve at the end point. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * CreateCube( const MbCartPoint & p1, const MbVector & v1, const MbCartPoint & p2, const MbVector & v2 );
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Конструктор сплайна, описывающего дугу конического сечения.\n
\en Constructor of a spline describing the arc of a conic section. \n \~
\param[in] points - \ru Набор из четырех точек, через которое проходит сечение.
Первая и последняя точки определяют начало и конец дуги, соответственно.
\en A set of four points the section passes through.
The first and last points define the beginning and ending of the arc respectively. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * CreateArc( const SArray<MbCartPoint> & points );
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Конструктор сплайна, описывающего дугу окружности.\n
\en Constructor of a spline describing the arc of a circle. \n \~
\param[in] a2 - \ru Половина угла раствора.
\en A half opening angle. \~
\param[in] p1 - \ru Начальная точка дуги.
\en The starting point of the arc. \~
\param[in] p2 - \ru Конечная точка дуги.
\en The end point of the arc. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * CreateArc( double a2, const MbCartPoint & p1, const MbCartPoint & p2 );
/** \brief \ru Создать сплайн.
\en Create spline. \~
\details \ru Конструктор сплайна, описывающего волнистую линию.\n
\en Constructor of a spline describing a wavy line. \n \~
\param[in] p1 - \ru Начальная точка кривой.
\en Start point of curve. \~
\param[in] p2 - \ru Конечная точка кривой.
\en End point of curve. \~
\param[in] height - \ru Высота гребешка волны.
\en Height of the wave. \~
\param[in] periode - \ru Период волны.
\en Period of the wave. \~
\return \ru Возвращает указатель на созданный объект или нулевой указатель в случае неудачи.
\en Returns pointer to the created object or null pointer in case of failure. \~
*/
static MbNurbs * CreateWavyLine( const MbCartPoint & p1, const MbCartPoint & p2, double height, double periode );
public :
VISITING_CLASS( MbNurbs );
/** \ru \name Функции инициализации NURBS-кривой.
\en \name Functions of NURBS curve initialization.
\{ */
// \ru Приведенные ниже функции меняют степень degree, поэтому в них необходим вызов CatchMemory(); \en The following functions change the degree "degree" therefore they call CatchMemory();
/// \ru Установить параметры сплайна по заданной NURBS-кривой. \en Set the spline parameters by a given NURBS curve.
void Init( const MbNurbs & );
/** \brief \ru Инициализация.
\en Initialization. \~
\details \ru Установить параметры сплайна.\n
\en Set parameters of spline.\n \~
\param[in] initDegree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] initPoints - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] initClosed - \ru Признак замкнутости.
\en A closedness attribute. \~
*/
template <class PointsVector>
bool Init( size_t initDegree, const PointsVector & initPoints, bool initClosed )
{
if ( ::IsValidNurbsParams( initDegree, initClosed, initPoints.size() ) )
{
Refresh(); // Must come first, since frees allocated memory
degree = initDegree;
form = ncf_Unspecified;
closed = initClosed;
uppIndex = (ptrdiff_t)initPoints.size() - 1;
pointList.assign( initPoints.begin(), initPoints.end() );
weights.assign( initPoints.size(), 1.0 );
DefineKnotsVector();
return true;
}
return false;
}
/** \brief \ru Инициализация.
\en Initialization. \~
\details \ru Установить параметры сплайна.\n
\en Set parameters of spline.\n \~
\param[in] initDegree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] initPoints - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] initClosed - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] initWeights - \ru Набор весов для контрольных точек.
\en Set of weights for control points. \~
*/
template <class PointsVector, class DoubleVector>
bool Init( size_t initDegree, const PointsVector & initPoints, bool initClosed,
const DoubleVector * initWeights )
{
if ( ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, initWeights ) )
{
Refresh(); // Must come first, since frees allocated memory
degree = initDegree;
form = ncf_Unspecified;
closed = initClosed;
uppIndex = (ptrdiff_t)initPoints.size() - 1;
pointList.assign( initPoints.begin(), initPoints.end() );
if ( initWeights != nullptr ) {
if ( (ptrdiff_t)initWeights->size() == uppIndex + 1 )
weights.assign( initWeights->begin(), initWeights->end() );
else {
C3D_ASSERT_UNCONDITIONAL( false ); // Wrong size of weights vector
weights.assign( initPoints.size(), 1.0 );
}
}
else {
weights.assign( initPoints.size(), 1.0 );
}
DefineKnotsVector();
return true;
}
return false;
}
/** \brief \ru Инициализация.
\en Initialization. \~
\details \ru Установить параметры сплайна.\n
\en Set parameters of spline.\n \~
\param[in] initDegree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] initClosed - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] initPoints - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] initWeights - \ru Набор весов для контрольных точек.
\en Set of weights for control points. \~
\param[in] initKnots - \ru Неубывающая последовательность весов.
\en Non-decreasing sequence of weights. \~
\param[in] initForm - \ru Тип построения.
\en Type of construction. \~
*/
template <class PointsVector, class DoubleVector>
bool Init( size_t initDegree, bool initClosed, const PointsVector & initPoints,
const DoubleVector & initWeights, const DoubleVector & initKnots,
MbeNurbsCurveForm initForm = ncf_Unspecified )
{
if ( ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, &initWeights, &initKnots ) ) {
Refresh(); // Must come first, since frees allocated memory
degree = initDegree;
closed = initClosed;
pointList = initPoints;
form = initForm;
weights = initWeights;
knots = initKnots;
uppIndex = (ptrdiff_t)pointList.size() - 1;
uppKnotsIndex = (ptrdiff_t)knots.size() - 1;
SetClamped();
return true;
}
return false;
}
/** \brief \ru Инициализация.
\en Initialization. \~
\details \ru Установить параметры сплайна.\n
\en Set parameters of spline.\n \~
\param[in] degree - \ru Порядок сплайна.
\en A spline order. \~
\param[in] cls - \ru Признак замкнутости.
\en A closedness attribute. \~
\param[in] points - \ru Набор контрольных точек.
\en Set of control points. \~
\param[in] knots - \ru Неубывающая последовательность узлов.
\en Non-decreasing sequence of knots. \~
\param[in] nPoints - \ru Количество контрольных точек.
\en Count of control points. \~
\param[in] nKnots - \ru Количество узлов.
\en Count of knots. \~
*/
bool Init( size_t degree, bool cls, const CcArray<double> & points,
const CcArray<double> & knots, ptrdiff_t nPoints, ptrdiff_t nKnots );
/** \brief \ru Инициализация.
\en Initialization. \~
\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. \~
\param[in] aKnots - \ru Неубывающая последовательность узлов.
\en Nondecreasing sequence of knots. \~
*/
bool InitThrough( size_t degree,
bool cls,
const SArray<MbCartPoint> & points,
const SArray<double> & params,
SArray<double> * aKnots = nullptr );
/** \brief \ru Инициализация.
\en Initialization. \~
\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. \~
\param[in] aKnots - \ru Неубывающая последовательность узлов.
\en Nondecreasing sequence of knots. \~
*/
bool InitThrough( size_t degree,
bool cls,
const c3d::ParamPointsVector & points,
const c3d::DoubleVector & params,
c3d::DoubleVector * aKnots = nullptr );
/** \brief \ru Инициализация.
\en Initialization. \~
\details \ru Инициализировать прямолинейный сплайн.\n
\en Initialize a straight spline. \n \~
\param[in] t1 - \ru Начальный узел.
\en The initial knot. \~
\param[in] p1 - \ru Начальная точка, через которую проходит сплайн.
\en The initial point the spline passes through. \~
\param[in] t2 - \ru Конечный узел.
\en The final knot. \~
\param[in] p2 - \ru Конечная точка, через которую проходит сплайн.
\en The final point the spline passes through. \~
*/
bool InitLine( double t1, const MbCartPoint & p1, double t2, const MbCartPoint & p2 );
/** \brief \ru Инициализация.
\en Initialization. \~
\details \ru Инициализировать кубическую кривую как сплайн.\n
\en Initialize a cubic curve as a spline. \n \~
\param[in] p1 - \ru Начальная точка, через которую проходит сплайн.
\en The initial point the spline passes through. \~
\param[in] v1 - \ru Касательный вектор к кривой в начальной точке.
\en A tangent vector to the curve at the start point. \~
\param[in] p2 - \ru Конечная точка, через которую проходит сплайн.
\en The final point the spline passes through. \~
\param[in] v2 - \ru Касательный вектор к кривой в конечной точке.
\en A tangent vector to the curve at the end point. \~
*/
bool InitCube( const MbCartPoint & p1, const MbVector & v1, const MbCartPoint & p2, const MbVector & v2 );
// \ru Интерполяция. \en Interpolation.
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн второго порядка по точкам, параметрам и признаку замкнутости.
\en Create a planar spline of second-order by points, parameters and attribute of closedness. \~
*/
static MbNurbs * CreateNURBS2( const SArray<MbCartPoint> & points, const SArray<double> & params, bool cls );
/// \ru Создать кубический NURBS по точкам, через которые он проходит, и параметрам сопряжения. \en Create cubic NURBS by parameters of conjugation and points which it passes through.
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> &, MbeSplineParamType spType,
const c3d::PntMatingData2D & begData,
const c3d::PntMatingData2D & endData );
/// \ru Создать кубический NURBS по интерполяционным точкам и данным сопряжения в каждой точке. \en Create cubic NURBS by interpolation points and data of conjugation at each point.
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> &, MbeSplineParamType spType,
bool closed, RPArray<c3d::PntMatingData2D> & );
/// \ru Создать кубический NURBS по интерполяционным точкам, их параметрам и данным сопряжения в каждой точке. \en Create cubic NURBS by interpolation points, parameters and data of conjugation at each point.
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> &, const SArray<double> &,
bool closed, RPArray<c3d::PntMatingData2D> & );
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн четвертого порядка по точкам, признаку замкнутости и типу параметризации.\n
Сплайн проходит через точки. Используется граничное условие отсутствия узла.
\en Create a planar spline of fourth order by points, attribute of closedness and parametrization type.\n
NURBS passes through points. Used boundary condition of knot absence. \~
*/
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> &, bool cls, MbeSplineParamType spType,
MbeSplineCreateType useInitThrough = sct_Version2 );
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн четвертого порядка по точкам, параметрам и признаку замкнутости.\n
Используется граничное условие отсутствия узла.
\en Create a planar spline of fourth order by points, parameters and attribute of closedness.\n
Used boundary condition of knot absence. \~
*/
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> & points, const SArray<double> & params, bool cls,
MbeSplineCreateType useInitThrough = sct_Version2 );
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн четвертого порядка по весам, точкам, параметрам и признаку замкнутости.\n
Используется граничное условие отсутствия узла.
\en Create a planar spline of fourth order by weights, points, parameters and attribute of closedness.\n
Used boundary condition of knot absence. \~
*/
static MbNurbs * CreateNURBS4( const SArray<double> & weights, const SArray<MbCartPoint> & points,
SArray<double> & params, bool cls );
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн четвертого порядка по точкам, параметрам и признаку замкнутости
с граничными условиями - заданными векторами первых или вторых производных.\n
Имеет 2 кратных внутренних узла, принадлежит классу дифференцируемых ( но не дважды дифференцируемых ) функций.
\en Create a planar spline of fourth order by points, parameters and attribute of closedness
with boundary conditions - given vectors of first or second derivatives.\n
Has 2 multiple internal knots, belongs to class of differentiable (but not twice differentiable) functions. \~
\param[in] bfstS - \ru Если true, то начальное граничное условие - вектор первой производной, иначе - вектор второй производной.
\en If true, then start boundary condition is the vector of the first derivative, otherwise - the vector of the second derivative. \~
\param[in] bfstN - \ru Если true, то конечное граничное условие - вектор первой производной, иначе - вектор второй производной.
\en If true, then end boundary condition is the vector of first derivative, otherwise - vector of second derivative. \~
*/
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> & points, const SArray<double> & params,
const MbVector &, const MbVector &, bool cls,
bool bfstS = true, bool bfstN = true );
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн четвертого порядка по точкам, производным, параметрам и признаку замкнутости.\n
Имеет 2 кратных внутренних узла, принадлежит классу дифференцируемых ( но не дважды дифференцируемых ) функций.
\en Create a planar spline of fourth order by points, derivatives, parameters and attribute of closedness.\n
It has 2 multiple internal knots, belongs to the class of differentiable (but not twice differentiable) functions. \~
*/
static MbNurbs * CreateNURBS4( const SArray<MbCartPoint> & points, const SArray<MbVector> & vectors,
const SArray<double> & params, bool cls );
/** \brief \ru Интерполяция.
\en Interpolation. \~
\details \ru Создать плоский сплайн четвертого порядка по составному сплайну Безье четвертого порядка.\n
Внимание! Параметризация отлична от параметризации исходной кривой Безье.
\en Create a planar spline of fourth order by composite Bezier spline of fourth order.\n
If closedness is necessary - call UnClamped( bezier.IsClosed() ). \~
*/
static MbNurbs * CreateNURBS4( const MbBezier & );
/// \ru Установить сопряжение на конце. \en Set conjugation at the end.
bool AttachG( c3d::PntMatingData2D & connectData, bool beg );
/** \brief \ru Увеличить порядок кривой, не изменяя ее геометрическую форму и параметризацию.
\en Increase order of curve without changing its geometric shape and parametrization. \~
\details \ru Увеличить порядок кривой, не изменяя ее геометрическую форму и параметризацию. \n
\en Increase order of curve without changing its geometric shape and parametrization. \n \~
\param[in] newDegree - \ru Новый порядок сплайна.
\en New order of spline. \~
\param[in] relEps - \ru Допустимая погрешность изменения формы.
\en Permissible shape error. \~
\return \ru Возвращает true, если порядок сплайна был изменен.
\en Returns true if the order of the spline was changed. \~
*/
bool RaiseDegree( size_t newDegree, double relEps = Math::paramEpsilon );
/** \brief \ru Уменьшить порядок кривой на 1, не изменяя ее геометрическую форму и параметризацию.
\en Decrease order of nurbs curve by 1 without changing its geometric shape and parametrization. \~
\details \ru Уменьшить порядок кривой на 1, не изменяя ее геометрическую форму и параметризацию. \n
\en Decrease order of nurbs curve by 1 without changing its geometric shape and parametrization. \n \~
\param[in] relEps - \ru Допустимая погрешность изменения формы.
\en Permissible shape error. \~
\return \ru Возвращает true, если порядок сплайна был изменен.
\en Returns true if the order of the spline was changed. \~
*/
bool ReductionDegree( double relEps = Math::paramEpsilon );
/** \brief \ru Задать порядок сплайна.
\en Set the spline order. \~
\details \ru Задать порядок сплайна. \n
При изменении порядка параметризация сплайна сбрасывается на равномерную, форма сплайна меняется. \n
\en Set the spline order. \n
When you change the order, the parameterization of the spline is reset to uniform, the shape of the spline changes. \n \~
\param[in] newDegree - \ru Новый порядок сплайна.
\en A new spline order. \~
\return \ru Возвращает true, если порядок сплайна был изменен.
\en Returns true if the order of the spline was changed. \~
*/
bool SetDegree( size_t newDegree );
/// \ru Увеличить порядок на 1. \en Increase the order by 1.
void DegreeIncrease();
/// \ru Установить тип формы. \en Set the type of shape.
void SetFormType( MbeNurbsCurveForm f ) { form = f; }
/// \ru Точка на кратном узле. \en The point on a multiple knot.
bool PointOnMultipleKnot( const MbCartPoint & point ) const;
/** \} */
/** \ru \name Общие функции геометрического объекта.
\en \name Common functions of geometric object.
\{ */
MbePlaneType IsA() const override; // \ru Тип элемента. \en A type of element.
MbPlaneItem & Duplicate( MbRegDuplicate * = nullptr ) const override; // \ru Сделать копию элемента \en Create a copy of the element
bool IsSame( const MbPlaneItem & other, double accuracy = LENGTH_EPSILON ) const override; // \ru Является ли кривая other копией данной кривой? \en Whether the curve is duplicate of current curve.
bool SetEqual( const MbPlaneItem & ) override; // \ru Сделать элементы равными. \en Make elements equal.
void Transform( const MbMatrix & matr, MbRegTransform * ireg = nullptr, const MbSurface * newSurface = nullptr ) override; // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix.
void Move( const MbVector & to, MbRegTransform * = nullptr, const MbSurface * newSurface = nullptr ) override; // \ru Сдвиг. \en Translation.
void Rotate( const MbCartPoint & pnt, const MbDirection & angle, MbRegTransform * = nullptr, const MbSurface * newSurface = nullptr ) override; // \ru Поворот. \en Rotation.
void GetProperties( MbProperties & ) override; // \ru Выдать свойства объекта. \en Get properties of the object.
void SetProperties( const MbProperties & ) override; // \ru Записать свойства объекта. \en Set properties of the object.
void GetBasisPoints( MbControlData & ) const override; // \ru Выдать контрольные точки объекта. \en Get control points of object.
void SetBasisPoints( const MbControlData & ) override; // \ru Изменить объект по контрольным точкам. \en Change the object by control points.
/** \} */
/** \ru \name Функции описания области определения кривой.
\en \name Functions describing the domain of a curve.
\{ */
double GetTMin() const override; // \ru Вернуть минимальное значение параметра. \en Get the minimum value of parameter.
double GetTMax() const override; // \ru Вернуть максимальное значение параметра. \en Get the maximum value of parameter.
bool IsClosed() const override; // \ru Замкнутость кривой. \en A curve closedness.
bool IsDegenerate( double eps = Math::LengthEps ) const override; // \ru Проверка вырожденности кривой. \en Check curve degeneracy.
bool IsPeriodic() const override; // \ru Периодичность замкнутой кривой. \en Periodicity of a closed curve.
/** \} */
/** \ru \name Функции для работы в области определения кривой.
Функции PointOn, FirstDer, SecondDer, ThirdDer,... корректируют параметр
при выходе его за пределы области определения.
\en \name Functions for working in the curve's domain.
Functions PointOn, FirstDer, SecondDer, ThirdDer,... correct parameter
when it is out of domain bounds.
\{ */
void PointOn ( double & t, MbCartPoint & pnt ) const override; // \ru Точка на кривой. \en Point on the curve.
void FirstDer ( double & t, MbVector & fd ) const override; // \ru Первая производная. \en First derivative.
void SecondDer( double & t, MbVector & sd ) const override; // \ru Вторая производная. \en Second derivative.
void ThirdDer ( double & t, MbVector & td ) const override; // \ru Третья производная. \en Third derivative.
/** \} */
/** \ru \name Функции доступа к группе данных для работы внутри и вне области определения параметра кривой.
\en \name Functions for get of the group of data inside and outside the curve's domain of parameter.
\{ */
// \ru Вычислить значения точки и производных для заданного параметра. \en Calculate point and derivatives of object for given parameter. \~
void Explore( double & t, bool ext,
MbCartPoint & pnt, MbVector & fir, MbVector * sec, MbVector * thir ) const override;
// \ru Вычислить значения производных для заданного параметра. \en Calculate derivatives of object for given parameter. \~
void Derivatives( double & t, bool ext, MbVector & fir, MbVector * sec, MbVector * thi ) const;
// \ru Функции, продолжающие кривую не по касательной как _PointOn() и др., а по кривой. \en Functions which do not continue curve along the tangent as _PointOn (), etc., and along a curve.
/// \ru Точка на продолжении кривой. \en Point on the curve extension.
void ExtPointOn ( double t, MbCartPoint & pnt ) const;
/// \ru Первая производная на продолжении кривой. \en The first derivative on the curve extension.
void ExtFirstDer ( double t, MbVector & fd ) const;
/// \ru Вторая производная на продолжении кривой. \en The second derivative on the curve extension.
void ExtSecondDer( double t, MbVector & sd ) const;
/// \ru Третья производная на продолжении кривой. \en The third derivative on the curve extension.
void ExtThirdDer ( double t, MbVector & td ) const;
/// \ru Продлить кривую. \en Extend the curve. \~
MbResultType Extend( const MbCurveExtensionParameters & parameters, c3d::PlaneCurveSPtr & resCurve ) const override;
/** \} */
/** \ru \name Общие функции кривой
\en \name Common functions of curve
\{ */
// \ru Добавить габарит в прямоугольник. \en Add a bounding box to rectangle.
void CalculateGabarit ( MbRect & ) const override;
bool IsStraight( bool ignoreParams = false ) const override; // \ru Прямолинейность кривой. \en Straightness of curve.
// \ru Посчитать метрическую длину \en Calculate the metric length
double CalculateMetricLength() const override;
// \ru Сдвинуть параметр t на расстояние len. \en Move parameter t on the metric distance len.
bool DistanceAlong( double & t, double len, int curveDir, double eps = Math::LengthEps,
VERSION version = Math::DefaultMathVersion() ) const override;
// \ru Вычислить метрическую длину кривой.\en Calculate the metric length of a curve.
double CalculateLength( double t1, double t2 ) const override;
size_t GetCount() const override;
MbNurbs * NurbsCurve( const MbCurveIntoNurbsInfo & ) const override;
MbCurve * NurbsCurve( const MbNurbsParameters & tParameters ) const override; // \ru Построить NURBS копию кривой. \en Construct a NURBS copy of a curve.
MbContour * NurbsContour() const override;
// \ru Построить усеченную кривую c учетом заданной двумерной точности. \en Construct a trimmed curve with the given two-dimensional accuracy.
MbCurve * Trimmed( double t1, double t2, int sense, const MbDimAccuracy & xyEps, bool saveParamLenAndLaw ) const override;
using MbCurve::Trimmed; // \ru Метод базового класса MbCurve без учета двумерной точности. Точность по умолчанию - MbDimAccuracy::twoDimAcc. \en Method of MbCurve base class without two-dimensional accuracy. The default accuracy is MbDimAccuracy::twoDimAcc.
void Refresh() override; // \ru Сбросить все временные данные. \en Reset all temporary data.
void Inverse( MbRegTransform * iReg = nullptr ) override; // \ru Изменение направления кривой на противоположное. \en Set the opposite direction of curve.
// \ru Определить, является ли кривая репараметризованно такой же. \en Define whether a reparameterized curve is the same.
bool IsReparamSame( const MbCurve & curve, double & factor ) const override;
double Step ( double t, double sag ) const override; // \ru Вычисление шага аппроксимации с учетом радиуса кривизны. \en Calculation of the approximation step with consideration of the curvature radius.
double DeviationStep( double t, double angle ) const override; // \ru Вычисление шага аппроксимации по угловой толерантности. \en Calculation of the approximation step by angular tolerance.
void CalculatePolygon( double sag, MbPolygon & ) const override;
MbeState DeletePart( double t1, double t2, MbCurve *& part2 ) override; // \ru Удалить часть поликривой между параметрами t1 и t2. \en Remove a part of the polyline between t1 and t2 parameters.
MbeState TrimmPart ( double t1, double t2, MbCurve *& part2 ) override; // \ru Оставить часть поликривой между параметрами t1 и t2. \en Save a part of the polyline between t1 and t2 parameters.
MbeState Deformation( const MbRect &, const MbMatrix & ) override; // \ru Деформация. \en Deformation.
bool GoThroughPoint( MbCartPoint &p0 ) override; // \ru Прохождение сплайна через точку. \en Passing of spline through the point.
void TangentPoint( const MbCartPoint & pnt, SArray<double> & tFind ) const override; // \ru Вычисление всех касательных к кривой из данной точки. \en Calculation of all tangents to the curve from a given point.
void OffsetCuspPoint( SArray<double> & tCusps, double dist ) const override; // \ru Определение особых точек офсетной кривой. \en Determination of singular points of the offset curve.
bool GetCentre( MbCartPoint & ) const override; // \ru Выдать центр кривой. \en Give the curve center.
double GetRadius( double accuracy = PARAM_REGION ) const override; // \ru Дать физический радиус объекта или ноль, если это невозможно. \en Get the physical radius of the object or null if it impossible.
bool GetAxisPoint( MbCartPoint & p ) const override; // \ru Выдать центр оси кривой. \en Give the curve axis center.
bool IsSimilarToCurve( const MbCurve & curve, double precision = PARAM_PRECISION ) const override; // \ru Подобные ли кривые для объединения (слива). \en Whether the curves to union (joining) are similar.
/// \ru Касание сплайна прямой. \en Touching the spline by line.
void MakeTangentLine( MbLine * line );
/// \ru Определить выпуклую оболочку сегмента кривой. \en Determine the convex hull of the curve segment.
void ConvexHull( ptrdiff_t seg, MbCartPoint * p ) const;
/// \ru Получить границы участков кривой, которые описываются одной аналитической функцией. \en Get the boundaries of the curve sections that are described by one analytical function. \~
void GetAnalyticalFunctionsBounds( std::vector<double> & params ) const override;
/** \} */
/** \ru \name Общие функции полигональной кривой.
\en \name Common functions of polygonal curve.
\{ */
void GetRuleInterval( ptrdiff_t index, double & t1, double & t2 ) const override; // \ru Выдать интервал влияния точки B-сплайна. \en Get range of influence of B-spline point.
void Rebuild() override; // \ru Перестроить B-сплайн. \en Rebuild B-spline.
void SetClosed( bool cls ) override; // \ru Установить признак замкнутости. \en Set the closedness attribute.
void RemovePoint( ptrdiff_t index ) override; // \ru Удалить точку. \en Remove the point.
void RemovePoints() override; // \ru Удалить все точки. \en Delete all points.
void AddPoint( const MbCartPoint & pnt ) override; // \ru Добавить точку в конец массива. \en Add point to the end of the array.
void InsertPoint( ptrdiff_t index, const MbCartPoint & pnt ) override; // \ru Вставить точку по индексу. \en Insert a point by index.
void InsertPoint( double t, const MbCartPoint & pnt, double xEps, double yEps ) override; // \ru Вставить точку. \en Insert a point.
void ChangePoint( ptrdiff_t index, const MbCartPoint & pnt ) override; // \ru Заменить вершину pointList[index] на pnt. \en Replace the vertex pointList[index] with pnt.
bool ChangePointsValue( const SArray<MbCartPoint> & pntList ) override; // \ru Заменить точки новыми при сохранении остальных параметров. \en Replace points with new one and save the other parameters.
bool CheckParam ( double & t, ptrdiff_t & i0, ptrdiff_t & i1, double & t0, double & t1 ) const override; // \ru Загнать параметр, получить локальный индексы и параметры. \en Move parameter, get local indices and parameters.
double GetParam( ptrdiff_t i ) const override;
size_t GetParamsCount() const override;
void ResetTCalc() const override; // \ru Сбросить текущее значение параметра \en Reset the current value of the parameter
// \ru Расстояние до точки. \en The distance to a point.
double DistanceToPoint( const MbCartPoint & to ) const override;
// \ru Расстояние до точки, если оно меньше d. \en Distance to the point if it is less than d.
bool DistanceToPointIfLess( const MbCartPoint & to, double & d ) const override;
// \ru Найти проекцию точки на кривую. \en Find the point projection to the curve.
double PointProjection( const MbCartPoint & pnt ) const override;
// \ru Найти проекцию точки на кривую. \en Find the point projection to the curve.
bool NearPointProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon,
double & t, bool ext, MbRect1D * tRange = nullptr ) const override;
bool IsContinuousDerivative( bool & contLength, bool & contDirect, c3d::DoubleVector * params = nullptr, double epsilon = EPSILON ) const override; // \ru Непрерывна ли первая производная? \en Have the first derivative the continuous?
// \ru Устранить разрывы первых производных по длине. \en Eliminate the discontinuities of the first derivative at length.
bool SetContinuousDerivativeLength( VERSION version, double epsilon = EPSILON ) override;
void GetStartPoint( MbCartPoint & ) const override;
void GetEndPoint ( MbCartPoint & ) const override;
/** \} */
/** \ru \name Функции B-сплайна.
\en \name Functions of B-spline.
\{ */
/// \ru Добавить точку с весом. \en Add a point with weight.
void AddPoint( ptrdiff_t index, const MbCartPoint & pnt, double weight );
/// \ru Добавить точку в конец массива. \en Add point to the end of the array.
void AddPoint( const MbCartPoint & pnt, double weight );
/// \ru Сделать контур из NURBS-кривой. \en Create a contour from the NURBS curve.
MbContour * CreateContour() const;
/// \ru Выделить часть. \en Break a part.
MbNurbs * Break( double t1, double t2 ) const;
/// \ru Получить форму В-сплайна. \en Get form of B-spline.
MbeNurbsCurveForm GetFormType() const { return form; }
/// \ru Выдать порядок сплайна. \en Get the spline order.
size_t GetDegree() const { return degree; }
/// \ru Вернуть признак рациональности, но не регулярности кривой. \en Get attribute of rationality, but no regularity of curve.
bool IsRational() const;
/// \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; }
// \ru BEG: для библиотеки (хорошо бы избавиться) \en BEG: for the library (it would be good to get rid of this)
/// \ru Добавить точку в конец массива. \en Add point to the end of the array.
void LtAddPoint ( MbCartPoint & pnt, double weight ) { C3D_ASSERT_UNCONDITIONAL( false ); pointList.push_back( pnt ); weights.push_back( weight ); }
/// \ru Добавить характерную точку в степенном представлении в конец массива. \en Add a control point with degree representation to the end of the array.
void LtAddPowerPoint( MbCartPoint & pnt ) { C3D_ASSERT_UNCONDITIONAL( false ); pointList.push_back( pnt ); }
/// \ru Добавить узел в конец узлового вектора. \en Add a knot to the end of knot vector.
void LtAddKnot ( double knot ) { C3D_ASSERT_UNCONDITIONAL( false ); knots.push_back( knot ); }
/// \ru Задать порядок сплайна. \en Set the spline order.
void LtSetDegree( size_t newDegree ) { C3D_ASSERT_UNCONDITIONAL( false ); if ( newDegree >= 2 && form == ncf_Unspecified ) { degree = newDegree; } }
/// \ru Установить признак замкнутости. \en Set the closedness attribute.
void LtSetClosed( bool cls ) { C3D_ASSERT_UNCONDITIONAL( false ); if ( form == ncf_Unspecified ) { closed = cls; } }
/// \ru Изменить степень, замкнутость и тип формы. \en Change degree, closedness and type of shape.
void LtSetData( size_t d, bool c, MbeNurbsCurveForm f );
/// \ru Перестроить сплайн после накачки из библиотеки. \en Rebuild the spline.
bool LtRebuild();
/// \ru Инициализация. \en Initialization.
void LtInit();
// \ru Преобразование кусочно степенной формы в NURBS-кривую. \en Convert a piecewise exponential form to a NURBS-curve.
bool LtInitPowerArc();
bool LtTrimmed( double t1, double t2, int sense = 1 );
// \ru END: для библиотеки (хорошо бы избавиться) \en END: for the library (it would be good escape)
/// \ru Создать Bezier форму Nurbs. \en Create a Bezier shape of Nurbs.
void Bezier( MbNurbs & bezierForm ) const;
/// \ru Присоединить nurbs. \en Attach nurbs.
bool Concatenate( MbNurbs & );
/// \ru Задать вес для вершины. \en Set weight for control point.
void SetWeight( ptrdiff_t pointNumber, double newWeight );
/// \ru Получить кратность узла. \en Get the knot multiplicity.
size_t KnotMultiplicity( ptrdiff_t knotIndex ) const;
/// \ru Определение базисного узлового вектора. \en Determination of basis knot vector.
void DefineKnotsVector();
/// \ru Переопределение базисного узлового вектора из Close в Open. \en Redetermination of the basis knot vector from Close to Open.
bool OpenKnotsVector();
/// \ru Переопределение базисного узлового вектора из Open в Close. \en Redetermination of the basis knot vector from Open to Close.
bool CloseKnotsVector();
/// \ru Сдвинуть параметр замкнутого сплайна. \en Shift parameter of closed spline.
void CyclicShift( ptrdiff_t interval );
void CyclicShift( double t );
bool BasicFunctions( double & t, ptrdiff_t k, CcArray<double> & values, ptrdiff_t & left, double & sum );
void CheckForm();
/// \ru Преобразовать кривую в коническое сечение, если это возможно. \en Transform a curve into a conic section if it is possible.
MbCurve * ConvertToConic();
/// \ru Установить область изменения параметра. \en Set the range of parameter.
bool SetLimitParam( double newTMin, double newTMax );
// \ru Базовые операции над NURBS-кривой. \en Base operation with NURBS curve.
/// \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 Удалить все внутренние узлы, если это возможно. \en Remove all internal knots if it is possible.
void RemoveAllKnots( double relEps = Math::paramEpsilon, double absEps = Math::lengthEpsilon );
/// \ru Преобразовать данный nurbs в форму Безье, узловой вектор в зажатый. \en Convert this nurbs to Bezier form; knot vector to clamped.
bool DecomposeCurve();
/// \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 );
/// \ru Добавить кривую в конец. \en Add curve to the end.
void AddCurve ( MbNurbs &, bool bmerge = true );
/// \ru Добавить кривые в конец. \en Add curves to the end.
template <class NurbsCurves>
void AddCurves( NurbsCurves & curves )
{
for ( size_t i = 0, icount = curves.size(); i < icount; ++i ) {
if ( curves[i] != nullptr )
AddCurve( *curves[i] );
}
}
/** \brief \ru Разбить кривую.
\en Split the curve. \~
\details \ru Разбить недифференцируемую NURBS-кривую четвертой степени в трижды кратном внутреннем узле.\n
Если внутренних трижды кратных узлов не существует, то в массив заносится копия кривой.\n
Если bline = true, то проверить вырожденность в прямую, если прямая - преобразовать в прямую.
\en Split the non-differentiable NURBS-curve of fourth degree at internal knot with multiplicity of three.\n
If there are no internal knots with multiplicity of three, then the array is filled with copy of curve.\n
If bline = true, then check the curve for degeneration into a line, if it is a line then transform to a line. \~
*/
bool BreakC0NURBS4( RPArray<MbCurve> &, bool bline = true );
/// \ru Разбить NURBS-кривую в местах, где кривая не дифференцируема. Параметризация не сохраняется. \en Split NURBS-curve at places where the curve is non-differentiable. Parametrization does not remain.
bool BreakC0( c3d::PlaneCurvesSPtrVector &, double metricAcc = METRIC_EPSILON, VERSION version = Math::DefaultMathVersion() );
/// \ru Расширить незамкнутую NURBS-кривую по касательным. \en Extend open NURBS-curve by tangents.
bool ExtendNurbs( double, double, bool bmerge = false );
/** \brief \ru Замкнуть кривую.
\en Make curve closed. \~
\details \ru Замкнуть фактически замкнутую кривую.\n
То есть если первая и последняя точки кривой совпадают, но она реализована как незамкнутая,
то одна из совпадающих точек убирается и кривая делается замкнутой.
\en Make actually closed curve closed.\n
That is, if the first and the last points of curve are coincident, but curve implemented as open,
then one of coincident points is taken away and curve becomes closed. \~
*/
void FixClosedNurbs();
/** \} */
protected:
bool CanChangeClosed() const override; // \ru Можно ли поменять признак замкнутости. // ЯТ К6 \en Whether it is possible to change the attribute of closedness. // ЯТ К6
private: // \ru Системные методы. \en System methods.
bool CatchMemory( MbNurbsAuxiliaryData * cache ) const; // \ru Выделить память. \en Allocate memory.
void FreeMemory( MbNurbsAuxiliaryData * cache ) const; // \ru Освободить память. \en Free memory.
void VerifyParam( double & t ) const; // \ru Загнать параметр t в параметрическую область кривой. \en Parameter set in the curve region.
void CalculateSegment( double & t, MbNurbsAuxiliaryData * cache ) const; // \ru Рассчитать базисные функции и разностные формы на участке. \en Calculate the basis functions and differential forms on the region.
void CalculateSpline( ptrdiff_t n, MbNurbsAuxiliaryData * cache ) const; // \ru Рассчитать точку NURBS-кривой или производную n-го порядка. \en Calculate point of NURBS-curve or n-th order derivative.
void CalculateSplineWeight( double & t, ptrdiff_t n, MbNurbsAuxiliaryData * cache ) const;
bool InitSegments( MbNurbsAuxiliaryData * cache ) const;
/** \brief \ru Инициализация.
\en Initialization. \~
\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. \~
*/
template <class PointsVector, class ParamsVector>
bool InitThroughTempl( size_t degree,
bool cls,
const PointsVector & points,
const ParamsVector & params,
ParamsVector * aKnots = nullptr );
// \ru Служебные аналоги публичных функций, которые используют заданный кэш. \en Service analogs of public functions that use a given cache.
void PointOn( double & t, MbCartPoint & pnt, MbNurbsAuxiliaryData * ucache ) const; // \ru Точка на кривой. \en Point on the curve.
void FirstDer( double & t, MbVector & fd, MbNurbsAuxiliaryData * ucache ) const; // \ru Первая производная. \en First derivative.
void SecondDer( double & t, MbVector & sd, MbNurbsAuxiliaryData * ucache ) const; // \ru Вторая производная. \en Second derivative.
void Derivatives( double & t, bool ext, MbVector & fir, MbVector * sec, MbVector * thi, MbNurbsAuxiliaryData * ucache ) const;
void SetClamped(); // \ru Делаем зажатый узловой вектор. \en Set clamped knots vector.
void ResetCache(); // \ru Очистить кэш главного потока, сбросить остальные кэши. \en Clear main thread cache, reset other caches.
bool NurbsPlus( MbNurbs & nurbs, double tin, double tax, double tRegion ) const;
// \ru Расчет весовых функций и их первых производных. \en Calculation of weight functions and its first derivatives.
ptrdiff_t WeightFunctions( double & x, CcArray<double> & ) const;
// \ru Вычисление шага аппроксимации в обе стороны. \en Calculation of approximation step in both directions.
double StepD( double & t, double sag, bool checkAngle = false, double angle = 0.0, MbNurbsAuxiliaryData * cache = nullptr ) const;
// \ru Вычисление шага аппроксимации сплайна второго порядка. \en Calculation of approximation step of second order spline.
double PolylineStep( double t, bool half, MbNurbsAuxiliaryData * cache ) const;
// \ru Уточнить проекцию \en Specify projection.
double SpecifyProjection( const MbCartPoint & pnt, double xEpsilon, double yEpsilon, double t, bool ext ) const;
void operator = ( const MbNurbs & ); // \ru Не реализовано. \en Not implemented.
DECLARE_PERSISTENT_CLASS_NEW_DEL( MbNurbs )
};
IMPL_PERSISTENT_OPS( MbNurbs )
//------------------------------------------------------------------------------
// Конструктор математического В-сплайна.
// ---
template <class PointsVector, class DoubleVector>
MbNurbs::MbNurbs( size_t initDegree, bool initClosed, const PointsVector & initPoints,
const DoubleVector * initWeights, const DoubleVector * initKnots )
: MbPolyCurve ( )
, degree ( 0 )
, uppKnotsIndex( SYS_MAX_T ) // Максимальный индекс узлового вектора.
, knots ( )
, weights ( )
, form ( ncf_Unspecified ) // Форма В-сплайна.
, cache ( )
{
if ( ::IsValidNurbsParamsExt( initDegree, initClosed, initPoints, initWeights, initKnots ) ) {
pointList.assign( initPoints.begin(), initPoints.end() );
uppIndex = (ptrdiff_t)pointList.size() - 1; // Количество точек.
closed = initClosed;
degree = initDegree; // Степень В-сплайна.
if ( initWeights != nullptr )
weights.assign( initWeights->begin(), initWeights->end() );
else
weights.assign( initPoints.size(), 1.0 );
if ( initKnots != nullptr ) {
knots.assign( initKnots->begin(), initKnots->end() );
uppKnotsIndex = (ptrdiff_t)knots.size() - 1;
}
else {
DefineKnotsVector();
}
Refresh();
}
}
//------------------------------------------------------------------------------
// \ru Добавить точку в конец массива. \en Add point to the end of the array.
// ---
inline
void MbNurbs::AddPoint( const MbCartPoint & pnt, double weight )
{
pointList.push_back( pnt );
weights.push_back( weight );
form = ncf_Unspecified;
Rebuild();
}
//------------------------------------------------------------------------------
// \ru Является ли сплайн прямолинейным \en Whether the spline is straight
// ---
template <class Nurbs, class Point, class Vector>
bool IsStraightNurbs( const Nurbs & nurbs, double mEps = METRIC_EPSILON )
{
bool isStraight = false;
if ( !nurbs.IsClosed() ) {
size_t wtsCnt = nurbs.GetWeightsCount();
isStraight = true;
if ( wtsCnt > 1 ) {
double wt0 = nurbs.GetWeight(0);
for ( size_t k = 1; k < wtsCnt; k++ ) {
double wt = nurbs.GetWeight(k);
if ( ::fabs(wt0 - wt) > EXTENT_EQUAL ) {
isStraight = false;
break;
}
}
}
if ( isStraight ) {
isStraight = false;
std::vector<Point> pnts;
pnts.reserve( nurbs.GetPointsCount() );
nurbs.GetPointList( pnts );
if ( c3d::ArePointsOnLine<Point, Vector>( pnts, mEps ) )
isStraight = true;
}
}
return isStraight;
}
#endif // __CUR_NURBS_H