|
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 находится здесь.
|