Класс Polyhedron


Этот класс предназначен для представления многогранника в трёхмерном пространстве. В него входят два массива - вершин и граней. Вершины представлены классом Vector3d, грани - классом Facet, в который входят: плоскость plane, к-во вершин грани nv, массив индексов index и поле info для записи дополнительной информации. Размер массива index равен 3 * nv + 1. Вначале идут индексы вершин и индекс первой вершины записывается ещё раз в конце (nv+1). Это сделано для удобства записи некоторых циклов. Затем идут индексы соседних граней для каждого ребра, а дальше номера рёбер соседних граней. Если какие-то индексы неопределены, то они равны undef_index. Функция-член initPlane вычисляет параметры плоскости, получая на вход ссылку на массив вершин.

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 & vert, double z );
        // Эллипсоид ( x, y, z - половины осей )
        Polyhedron & makeEllipsoid ( nat n, double x, double y, double z, RandVector3d & qrv );
        Polyhedron & makeEllipsoid ( double x, double y, double z, nat n = 1095 );
        Polyhedron & makeModel ( const Ellipsoid3d & fig, nat n = 1095 )
        {
            return makeEllipsoid ( fig.a, fig.b, fig.c, n ) *= Conform3d ( fig.spin, fig.o, 1 );
        }
        // Сфера ( r - радиус )
        Polyhedron & makeSphere ( double r, nat n = 1095 )
        {
            return makeEllipsoid ( r, r, r, n );
        }
        Polyhedron & makeModel ( const Sphere3d & fig, nat n = 1095 )
        {
            return makeSphere ( fig.r, n ) += fig.o;
        }
        // Цилиндр
        Polyhedron & makeModel ( const Cylinder3d & fig, nat n );
        // Конус
        Polyhedron & makeModel ( const Cone3d & fig, nat n );
        // Площадь поверхности многогранника
        double area () const;
        // Объём многогранника
        double volume () const;
        // Центр масс многогранника
        Def<Vector3d> centerOfMass () const;
    };

} // namespace Shev

Функция-член linkFacets ищет соседние грани и проставляет соответствующие индексы.
Функция-член initPlanes вычисляет значения поля plane для всех граней.
Оператор += предназначен для сдвига многогранника.
Шаблон оператора *= предназначен для преобразования многогранника при помощи объектов разных типов ( double, Similar3d, Affin3d и т.д. ). Для типов Conform3d и Spin3d сделаны специализации.
Функции-члены makeModel создают указаные фигуры. Гладкие фигуры аппроксимируются.

Функция trianTest проверяет - можно ли грань разбить на положительные треугольники.

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 совмещает вершины и плоскости граней, если они расходятся, с минимизацией суммы квадратов сдвигов вершин:
bool normalize ( Polyhedron & poly );

Описание класса Vector3d находится здесь.
Описание классов Plane3d, Sphere3d, Ellipsoid3d, Cylinder3d, Cone3d, Tetrahedron и Cuboid3d находится здесь.
Описание классов Spin3d, Ortho3d, Conform3d и Similar3d находится здесь.
Описание шаблонов классов CArrRef и DynArray находится здесь.
Исходники находятся в файле polyhedron.cpp.

Наверх