//////////////////////////////////////////////////////////////////////////////// /** \file \brief \ru Tриангуляция двумерной области. \en Triangulation of two-dimensional region. \~ */ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // "PGrid.cpp" // \ru PGrid.h - заголовочный файл триангуляции массива двумерных точек. \en PGrid.h - header file of two-dimensional point array triangulation. // \ru Содержит следующие разделы: \en Contains the following sections: // \ru - Триангуляция двумерной области \en - Triangulation of a two-dimensional region // \ru - Вершина полигона \en - Vertex of a polygon // \ru - Многоугольник \en - Polygon // \ru - Аппроксимация плоской области треугольными пластинами \en - Approximation of a planar region by triangular plates // \ru - Трингуляция двумерного региона \en - Triangulation of a two-dimensional region // \ru - Выпуклая триангуляция неупорядоченного массива двумерных точек \en - Convex triangulation of unordered array of two-dimensional points // //////////////////////////////////////////////////////////////////////////////// #ifndef __MESH_PLANE_GRID_H #define __MESH_PLANE_GRID_H #include #include #include #include #include #include class MATH_CLASS MbRegion; class MATH_CLASS MbMatrix3D; class MATH_CLASS ProgressBarWrapper; //------------------------------------------------------------------------------ /** \brief \ru Tреугольник. \en Triangle. \~ \details \ru Tреугольник определен, как тройка точек, заданных индексами вершин триангуляции MbPlanarGrid. \n \en Triangle is defined as triple of points defined by indices of vertices of MbPlanarGrid triangulation. \n \~ \ingroup Algorithms_2D */ // --- class MbTri { protected : size_t pIndex[3]; // \ru Номера вершин треугольника в массиве точек \en Indices of triangle vertices in array of points public : MbTri() { pIndex[0] = pIndex[1] = pIndex[2] = SYS_MAX_T; } MbTri( size_t j0, size_t j1, size_t j2, bool orientation ) { Init( j0, j1, j2, orientation ); } ~MbTri() {} private: MbTri( const MbTri & ); // \ru Не реализовано \en Not implemented void operator = ( const MbTri & ); // \ru Не реализовано \en Not implemented public : void Init( size_t j0, size_t j1, size_t j2, bool orientation ) { if ( orientation ) { // \ru Совпадает направление обхода \en Traverse direction coincides pIndex[0] = j0; pIndex[1] = j1; pIndex[2] = j2; } else { pIndex[1] = j1; pIndex[2] = j0; pIndex[0] = j2; } } bool GetTriangle ( size_t & i0, size_t & i1, size_t & i2 ) const { i0 = pIndex[0]; i1 = pIndex[1]; i2 = pIndex[2]; return true; } size_t GetIndex( size_t n ) const { return pIndex[n % 3]; } bool IsTriangleEdge( size_t k0, size_t k1, size_t & eInd ) const { eInd = SYS_MAX_T; if ( k0 == pIndex[0] && k1 == pIndex[1] ) eInd = 0; else if ( k0 == pIndex[1] && k1 == pIndex[2] ) eInd = 1; else if ( k0 == pIndex[2] && k1 == pIndex[0] ) eInd = 2; return (eInd != SYS_MAX_T); } }; // MbTri //------------------------------------------------------------------------------ /** \brief \ru Tриангуляция двумерной области. \en Triangulation of a two-dimensional region. \~ \details \ru Tриангуляция двумерной области. \n \en Triangulation of a two-dimensional region. \n \~ \ingroup Algorithms_2D */ // --- class MATH_CLASS MbPlanarGrid { private: SArray points; ///< \ru Вершины триангуляции. \en Vertices of triangulation. SArray triangles; ///< \ru Множество треугольников. \en Array of triangles. public: MbPlanarGrid() : points( 0, 1 ), triangles( 0, 1 ) {} ~MbPlanarGrid() {}; public: void PointsReserve ( size_t size ) { points.Reserve( size ); } void TrianglesReserve ( size_t size ) { triangles.Reserve( size ); } void PointsSetMaxDelta ( uint16 size ) { points.SetMaxDelta( size ); } void TrianglesSetMaxDelta( uint16 size ) { triangles.SetMaxDelta( size ); } void PointsAdjust() { points.Adjust(); } void TrianglesAdjust() { triangles.Adjust(); } size_t GetPointsCount () const { return points.Count(); } size_t GetTrianglesCount() const { return triangles.Count(); } void AddTriangle( size_t j0, size_t j1, size_t j2, bool o ) { triangles.Add()->Init( j0, j1, j2,o ); } void AddPoint ( const MbFloatPoint & p ) { points.Add( p ); } void AddPoint ( const MbCartPoint & p ) { points.Add( p ); } /// \ru Выдать декартову точку. \en Get Cartesian point. bool GetPoint ( size_t k, MbCartPoint & p ) const; /// \ru Выдать точку. \en Get point. bool GetPoint ( size_t k, MbFloatPoint & p ) const; /// \ru Получить индексы точек треугольника. \en Get indices of points of the triangle. bool GetTriangle( size_t k, size_t & i0, size_t & i1, size_t & i2 ) const; /// \ru Получить точки треугольника. \en Get points of the triangle. bool GetTrianglePoints( size_t k, MbCartPoint & p0, MbCartPoint & p1, MbCartPoint & p2 ) const; OBVIOUS_PRIVATE_COPY( MbPlanarGrid ) }; //------------------------------------------------------------------------------ /// \ru Выдать декартову точку \en Get Cartesian point // --- inline bool MbPlanarGrid::GetPoint( size_t k, MbCartPoint & p ) const { if ( k < points.Count() ) { p = points[k]; return true; } return false; } //------------------------------------------------------------------------------ /// \ru Выдать точку \en Get point // --- inline bool MbPlanarGrid::GetPoint( size_t k, MbFloatPoint & p ) const { if ( k < points.Count() ) { p = points[k]; return true; } return false; } //------------------------------------------------------------------------------ /// \ru Вершина полигона \en Vertex of a polygon // --- class TriVertex { private: TriVertex * next; ///< \ru Следующая вершина \en Next vertex TriVertex * prev; ///< \ru Предыдущая вершина \en Previous vertex size_t index; ///< \ru Номер точки в массиве точек триангуляции \en Index of point in array of points of triangulation public: TriVertex( size_t i ) : index(i) { next = this; prev = this; } public: ~TriVertex() {} public: /// \ru Смежная вершина (следующая или предыдущая). \en Adjacent vertex (next or previous). TriVertex * Neighbor ( MbeMoveType ) const; /// \ru Следующая вершина. \en Next vertex. TriVertex * Next () const { return next; } /// \ru Предыдущая вершина. \en Previous vertex. TriVertex * Prev () const { return prev; } /// \ru Номер точки текущей вершины. \en Index of point of current vertex. size_t Index () const { return index; } /// \ru Вставить вершину после текущей. \en Insert vertex after the current one. TriVertex * Insert ( TriVertex & ); /// \ru Исключить текущую вершину (возвращает исключенную, текущей становится предыдущая) \en Exclude the current vertex (returns excluded vertex, previous vertex becomes the current one) TriVertex * Detach (); /// \ru Соединить две цепочки вершин. \en Connect two vertex chains. void Splice ( TriVertex & ); /// \ru Разделить цепочку вершин вершиной. \en Disconnect vertex chain by a vertex. TriVertex * Split ( TriVertex & ); OBVIOUS_PRIVATE_COPY( TriVertex ) }; //------------------------------------------------------------------------------ /// \ru Многоугольник \en Polygon // --- class TriPoly { private: TriVertex * vertex; ///< \ru Текущая вершина. \en Current vertex. intptr_t size; ///< \ru Количество вершин. \en Count of vertices. public: TriPoly() : vertex( NULL ), size( 0 ) {} TriPoly( TriVertex * vert ) : vertex( vert ), size( 0 ) { Resize(); } public: ~TriPoly(); public: intptr_t Size() const { return size; } ///< \ru Размер цепочки вершин \en Size of vertex chain size_t Index() const { return (vertex != NULL) ? vertex->Index() : SYS_MAX_T; } ///< \ru Индекс вершины \en Index of vertex TriVertex * This() const { return vertex; } ///< \ru Текущая вершина \en Current vertex TriVertex * Next() const; ///< \ru Следующая вершина \en Next vertex TriVertex * Prev() const; ///< \ru Предыдущая вершина \en Previous vertex TriVertex * Neighbor( MbeMoveType rotation ) const; ///< \ru Соседняя вершина \en Neighboring vertex TriVertex * Advance ( MbeMoveType rotation ); ///< \ru Перемещение указателя текущей вершины на соседа \en Move current vertex pointer to the neighbor TriVertex * SetVertex( TriVertex * ); ///< \ru Перемещение указателя текущей вершины на указанную \en Move current vertex pointer to the given one TriVertex * Insert( TriVertex & ); ///< \ru Вставка новой вершины \en Insert new vertex void Remove(); ///< \ru Удаление текущей вершины \en Remove the current vertex TriPoly * Split( TriVertex &, bool createNew ); ///< \ru Резка многоугольника вдоль хорды \en Cutting of polygon along a chord bool GetTriangle( size_t & k0, size_t & k1, size_t & k2 ) const; ///< \ru Получить индексы вершин треугольника (когда вершин больше 2) \en Get indices of triangle vertices (when there are more than 2 vertices) template bool CalculateGab( const SArray & pnts, Gab & rect ) const; private: void Resize(); ///< \ru Обновление размера \en Set size to zero OBVIOUS_PRIVATE_COPY( TriPoly ) }; //------------------------------------------------------------------------------ // \ru Посчитать габарит цепочки вершин \en Calculate bounding box of vertex chain // --- template bool TriPoly::CalculateGab( const SArray & pnts, Gab & rect ) const { bool isDone = false; rect.SetEmpty(); size_t pntsCnt = pnts.Count(); if ( Size() > 0 && pntsCnt > 0 ) { const TriVertex * v0 = This(); size_t ind0 = v0->Index(); if ( ind0 < pntsCnt ) { isDone = true; const Point & pnt0 = pnts[ind0]; rect |= pnt0; TriVertex * v = v0->Next(); while( v0 != v && isDone ) { isDone = false; size_t ind = v->Index(); if ( ind < pntsCnt ) { const Point & pnt = pnts[ind]; rect |= pnt; v = v->Next(); isDone = true; } } } } C3D_ASSERT( isDone ); return isDone; } /* //------------------------------------------------------------------------------ // \ru Треугольник со ссылками на смежные(соседние) с ним треугольники \en Triangle with references to triangles adjacent (neighboring) to it // --- class MbLinkedTri : public MbTri { protected: MbTri * neighbors[3]; // \ru Соседние треугольники \en Neighboring triangles // \ru Нумерация соседних треугольников: \en Numeration of neighboring triangles: // \ru 0 - смежный через ребро на вершинах 0,1 \en 0 - adjacent at edge with vertices 0,1 // \ru 1 - смежный через ребро на вершинах 1,2 \en 1 - adjacent at edge with vertices 1,2 // \ru 2 - смедный через ребра на вершинах 2,0 \en 2 - adjacent at edge with vertices 2,0 public: MbLinkedTri() : MbTri() { neighbors[0] = neighbors[1] = neighbors[2] = NULL; }; ~MbLinkedTri() {}; public: MbTri * GetNeighbor( size_t n ) const { return neighbors[n % 3]; } void SetNeighbor( size_t n, MbTri * neighbor ) { neighbors[n % 3] = neighbor; } bool IsBoundary() const; // \ru Является ли треугольник граничным \en Whether the triangle is boundary OBVIOUS_PRIVATE_COPY( MbLinkedTri ) }; //------------------------------------------------------------------------------ // \ru Является ли треугольник граничным \en Whether the triangle is boundary // --- inline bool MbLinkedTri::IsBoundary() const { bool isBoundary = (neighbors[0] == NULL) || (neighbors[1] == NULL) || (neighbors[2] == NULL); return isBoundary; } // */ //------------------------------------------------------------------------------ // \ru Аппроксимация плоской области треугольными пластинами \en Approximation of planar region by triangular plates // \ru Функция удаляет полигионы точек из массива \en The function removes polygons of points from the array // --- MATH_FUNC (void) CalculatePlanarGrid( PArray< SArray > & poly, MbPlanarGrid & grid ); //------------------------------------------------------------------------------ /** \brief \ru Трингуляция двумерного региона \en Triangulation of a two-dimensional region \~ \details \ru Трингуляция двумерного региона. Регион region должен быть корректным (на некорректном работает неправильно) \en Triangulation of a two-dimensional region. 'region' region has to be correct (improper handling of incorrect ones) \~ \ingroup Polygonal_Objects */ // --- MATH_FUNC (void) TriangulateRegion( const MbRegion & region, double sag, MbPlanarGrid & grid ); //------------------------------------------------------------------------------ /// \ru Выпуклая триангуляция неупорядоченного массива двумерных точек \en Convex triangulation of unordered array of two-dimensional points // --- MATH_FUNC (bool) TriangulateConvexCloud( const SArray & uvPnts, double xEps, double yEps, const MbMatrix3D & from, SArray & triangles, ProgressBarWrapper * progBar ); #endif // __PGRID_H