| 
 namespace Shev
{
    const nat undef_index = 0xFFFFFFFF;
    class Facet
    {
        Facet ( const Facet & );
    public:
        Plane3d plane;
        nat nv;
        DynArray<nat> index;
        int info;
        Facet () : plane ( Vector3d ( 0., 0., 0. ), 0. ), nv(0), info(-123456789) {}
        Facet & operator = ( const Facet & );
        Facet & operator += ( const Vector3d & v )
        {
            plane += v;
            return *this;
        }
        template <class T> Facet & operator *= ( const T & t )
        {
            plane *= t;
            return *this;
        }
        Facet & resize ( nat n )
        {
            index.resize ( ( nv = n ) > 0 ? 3 * nv + 1 : 0 );
            return *this;
        }
        Facet & initPlane ( CArrRef<Vector3d> vertex );
        double getArea ( CArrRef<Vector3d> vertex ) const; // Площадь грани
        double perimeter ( CArrRef<Vector3d> vertex ) const; // Периметр грани
        Def<Vector3d> centerOfMass ( CArrRef<Vector3d> vertex ) const; // Центр масс грани
    };
    class Polyhedron
    {
        Polyhedron ( const Polyhedron & );
    public:
        DynArray<Vector3d> vertex;
        DynArray<Facet> facet;
        Polyhedron () {}
        Polyhedron ( nat nv, nat nf ) : vertex(nv), facet(nf) {}
        explicit Polyhedron ( const Tetrahedron & fig ) { *this = fig; }
        explicit Polyhedron ( const Cuboid3d & fig ) { *this = fig; }
        Polyhedron & linkFacets (); // Связать грани
        Polyhedron & initPlanes (); // Заполнить плоскости
        Polyhedron & operator = ( const Polyhedron & poly )
        {
            if ( this != & poly )
            {
                vertex = poly.vertex;
                facet = poly.facet;
            }
            return *this;
        }
        Polyhedron & operator = ( const Tetrahedron & fig );
        Polyhedron & operator = ( const Cuboid3d & fig )
        {
            return makeCuboid ( fig.a, fig.b, fig.c ) *= Conform3d ( fig.spin, fig.o, 1 );
        }
        Polyhedron & operator += ( const Vector3d & v )
        {
            for012 ( vertex ) += v;
            for012 ( facet ) += v;
            return *this;
        }
        template <class T> Polyhedron & operator *= ( const T & t )
        {
            for012 ( vertex ) *= t;
            for012 ( facet ) *= t;
            return *this;
        }
        Polyhedron & operator *= ( const Conform3d & conf )
        {
            return *this *= Similar3d ( conf );
        }
        Polyhedron & operator *= ( const Spin3d & spin )
        {
            return *this *= Ortho3d ( spin );
        }
        // Пустой многогранник
        Polyhedron & makeVoid ()  
        {
            vertex.resize ( 0 ); facet.resize ( 0 ); return *this;
        }
        // Тетраэдр ( r - макс. значение координат вершин )
        Polyhedron & makeTetrahedron ( double r ); 
        // Октаэдр  ( r - макс. значение координат вершин ) 
        Polyhedron & makeOctahedron  ( double r ); 
        // Прямоугольный параллелепипед ( x, y, z - половины сторон )
        Polyhedron & makeCuboid ( double x, double y, double z );
        // Куб ( r - половина стороны )
        Polyhedron & makeCube ( double r )
        {
            return makeCuboid ( r, r, r );
        }
        // Призма
        Polyhedron & makePrism ( CCArrRef
Функция-член linkFacets ищет соседние грани и проставляет соответствующие индексы.
 bool trianTest ( const Facet & facet, CArrRef<Vector3d> vert );Функция _swap обменивает содержимое двух многогранников. inline
void _swap ( Polyhedron & poly1, Polyhedron & poly2 )
{
    _swap ( poly1.vertex, poly2.vertex );
    _swap ( poly1.facet, poly2.facet );
}
Функция distance вычисляет расстояние от заданной точки до поверхности многогранника.
Если точка находится внутри многогранника, то расстояние будет отрицательным. 
Также выдаются индексы ближайшего к точке геометрического объекта ( vi - индекс вершины, 
ei - индекс ребра, fi - индекс грани ). Если ближайшей будет вершина,
то vi != undef_index, ei == undef_index, fi == undef_index. Если ближайшем будет ребро,
то vi == undef_index, ei != undef_index, fi != undef_index. Если ближайшей будет грань,
то vi == undef_index, ei == undef_index, fi != undef_index.
bool distance ( const Polyhedron & poly, const Vector3d & point, double & dist, 
                nat & vi, nat & ei, nat & fi );
inline bool distance ( const Polyhedron & poly, const Vector3d & point, double & dist )
{
    nat vi, ei, fi;
    return distance ( poly, point, dist, vi, ei, fi );
}
Функции normalize.. совмещают вершины и плоскости граней, если они расходятся, с минимизацией суммы квадратов сдвигов вершин.
При этом normalizeV1 не меняет нормали граней с количеством вершин больше трёх:bool normalizeV1 ( Polyhedron & poly ); bool normalizeV2 ( Polyhedron & poly ); 
Описание класса Vector3d находится здесь.
 |