905577a744
- C3d aggiornamento delle librerie.
845 lines
45 KiB
C++
845 lines
45 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
\file
|
|
\brief \ru Габаритный куб геометрического объекта.
|
|
\en The bounding box (cube) of a geometric object. \~
|
|
|
|
*/
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef __MB_CUBE_H
|
|
#define __MB_CUBE_H
|
|
|
|
|
|
#include <mb_cart_point3d.h>
|
|
#include <mb_cube_tree.h>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
|
|
c3d_constexpr size_t CUBE_CONTROL_POINTS_COUNT = 26; ///< \ru Количество характерных точек куба. \en The number of control points of cube.
|
|
c3d_constexpr size_t CUBE_VERTEX_COUNT = 8; ///< \ru Количество вершин куба. \en The number of cube vertices.
|
|
c3d_constexpr size_t CUBE_EDGES_COUNT = 12; ///< \ru Количество рёбер куба. \en The number of cube edges.
|
|
c3d_constexpr size_t CUBE_FACES_COUNT = 6; ///< \ru Количество граней куба. \en The number of cube faces.
|
|
|
|
|
|
class MATH_CLASS MbRect;
|
|
class MATH_CLASS MbCube;
|
|
class MATH_CLASS MbPlacement3D;
|
|
class MATH_CLASS MbCurve3D;
|
|
class MATH_CLASS MbSurface;
|
|
|
|
namespace c3d // namespace C3D
|
|
{
|
|
typedef std::pair<MbCube *, size_t> CubePtrIndex; ///< \ru Габаритный куб и индекс. \en Bounding box and index.
|
|
typedef std::pair<const MbCube *, size_t> ConstCubePtrIndex; ///< \ru Габаритный куб и индекс. \en Bounding box and index.
|
|
typedef std::vector<CubePtrIndex> CubesPtrIndices; ///< \ru Вектор габаритных кубов и индексов. \en Vector of bounding boxes and indices.
|
|
typedef std::vector<ConstCubePtrIndex> ConstCubesPtrIndices; ///< \ru Вектор габаритных кубов и индексов. \en Vector of bounding boxes and indices.
|
|
typedef std::vector<MbCube> CubesVector; ///< \ru Вектор габаритных кубов. \en Vector of bounding boxes.
|
|
typedef MbCubeTree<MbCube, MbCube, MbCartPoint3D> CubesTree; ///< \ru Дерево габаритных кубов. \en Tree of bounding boxes.
|
|
} // namespace C3D
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Габаритный параллелепипед.
|
|
\en The bounding box. \~
|
|
\details \ru Габаритный параллелепипед - это область 3D-пространства, ограниченная
|
|
прямым параллелепипедом, грани которого параллельным плоскостям системы координат.\n
|
|
Используется для быстрой оценки близости или непересечения трёхмерных объектов,
|
|
содержащихся в параллелепипеде. Габаритный параллелепипед описывается парой точек,
|
|
расположенных на главной диагонали куба.
|
|
\en The bounding box is a domain (block) of 3D-space bounded by parallelepiped
|
|
with edges parallel to the axes of coordinate system.\n
|
|
It is used for quick estimation of the proximity or non-intersection of three-dimensional objects,
|
|
which are contained in the "cube". Faces of "cube" are parallel to planes of coordinate system.
|
|
The bounding box is described by a pair of points which are located on the main diagonal of a box. \~
|
|
\ingroup Mathematic_Base_3D
|
|
*/
|
|
// ---
|
|
class MATH_CLASS MbCube {
|
|
public :
|
|
MbCartPoint3D pmin; ///< \ru Точка диагонали параллелепипеда с минимальными координатами. \en A point of a box diagonal with minimal coordinates.
|
|
MbCartPoint3D pmax; ///< \ru Точка диагонали параллелепипеда с максимальными координатами. \en A point of a box diagonal with maximal coordinates.
|
|
|
|
public :
|
|
/// \ru Пустой конструктор. \en The empty constructor.
|
|
MbCube() { SetEmpty(); }
|
|
/// \ru Конструктор копирования. \en Copy constructor.
|
|
MbCube( const MbCube & init ) : pmin( init.pmin ), pmax( init.pmax ) {}
|
|
/// \ru Конструктор по координатам \en The constructor by coordinates
|
|
/**
|
|
\param[in] xmin, ymin, zmin - \ru Координаты точки угла куба с минимальными координатами.
|
|
\en Coordinates of a box corner point with minimal coordinates. \~
|
|
\param[in] xmax, ymax, zmax - \ru Координаты точки угла куба с максимальными координатами.
|
|
\en Coordinates of a box corner point with maximal coordinates. \~
|
|
\param[in] normalize - \ru Нормализовать себя.
|
|
\en Normalize itself. \~
|
|
*/
|
|
MbCube( double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, bool normalize = false ) : pmin( xmin, ymin, zmin ), pmax( xmax, ymax, zmax ) { if ( normalize ) Normalize(); }
|
|
/// \ru Конструктор по двум точкам. \en The constructor by two points.
|
|
/**
|
|
\param[in] p0 - \ru Точка угла куба с минимальными координатами.
|
|
\en A point of a box corner with minimal coordinates. \~
|
|
\param[in] p1 - \ru Точка угла куба с максимальными координатами.
|
|
\en A point of a box corner with maximal coordinates. \~
|
|
\param[in] normalize - \ru Нормализовать себя.
|
|
\en Normalize itself. \~
|
|
*/
|
|
MbCube( const MbCartPoint3D & p0, const MbCartPoint3D & p1, bool normalize = false ) : pmin( p0 ), pmax( p1 ) { if ( normalize ) Normalize(); }
|
|
|
|
/**
|
|
\brief \ru Проверка на пустоту. \en The check for emptiness.
|
|
\details \ru Габаритный параллелепипед считается пустым, если он не содержит ни одной точки 3D-пространства.
|
|
\en A bounding box is empty if it doesn't contain any points of 3D-space \~
|
|
*/
|
|
bool IsEmpty() const;
|
|
/// \ru Установить пустым ("вывернутым"). \en Set empty ("reverted").
|
|
void SetEmpty();
|
|
|
|
/// \ru Инициализировать по координатам. \en Initialize by coordinates.
|
|
/**
|
|
\param[in] xmin, ymin, zmin - \ru Координаты точки угла куба с минимальными координатами.
|
|
\en Coordinates of a box corner point with minimal coordinates. \~
|
|
\param[in] xmax, ymax, zmax - \ru Координаты точки угла куба с максимальными координатами.
|
|
\en Coordinates of a box corner point with maximal coordinates. \~
|
|
\param[in] normalize - \ru Нормализовать себя.
|
|
\en Normalize itself. \~
|
|
*/
|
|
void Set( double xmin, double ymin, double zmin,
|
|
double xmax, double ymax, double zmax,
|
|
bool normalize = false );
|
|
/// \ru Инициализировать по двум точкам. \en Initialize by two points.
|
|
/**
|
|
\param[in] p0 - \ru Точка угла куба с минимальными координатами.
|
|
\en A point of a box corner with minimal coordinates. \~
|
|
\param[in] p1 - \ru Точка угла куба с максимальными координатами.
|
|
\en A point of a box corner with maximal coordinates. \~
|
|
\param[in] normalize - \ru Нормализовать себя.
|
|
\en Normalize itself. \~
|
|
*/
|
|
void Set( const MbCartPoint3D & p0, const MbCartPoint3D & p1, bool normalize = false );
|
|
|
|
/**
|
|
\ru \name Функции доступа к полям
|
|
\en \name Functions for access to fields.
|
|
\{ */
|
|
/// \ru Установить минимальную координату по X. \en Set the minimal coordinate by X.
|
|
void SetXMin( double s ) { pmin.x = s; }
|
|
/// \ru Установить минимальную координату по Y. \en Set the minimal coordinate by Y.
|
|
void SetYMin( double s ) { pmin.y = s; }
|
|
/// \ru Установить минимальную координату по Z. \en Set the minimal coordinate by Z.
|
|
void SetZMin( double s ) { pmin.z = s; }
|
|
/// \ru Установить максимальную координату по X. \en Set the maximal coordinate by X.
|
|
void SetXMax( double s ) { pmax.x = s; }
|
|
/// \ru Установить максимальную координату по Y. \en Set the maximal coordinate by Y.
|
|
void SetYMax( double s ) { pmax.y = s; }
|
|
/// \ru Установить максимальную координату по Z. \en Set the maximal coordinate by Z.
|
|
void SetZMax( double s ) { pmax.z = s; }
|
|
|
|
/// \ru Дать минимальную координату по X. \en Give the minimal coordinate by X.
|
|
double GetXMin() const { return pmin.x; }
|
|
/// \ru Дать минимальную координату по Y. \en Give the minimal coordinate by Y.
|
|
double GetYMin() const { return pmin.y; }
|
|
/// \ru Дать минимальную координату по Z. \en Give the minimal coordinate by Z.
|
|
double GetZMin() const { return pmin.z; }
|
|
/// \ru Дать максимальную координату по X. \en Give the maximal coordinate by X.
|
|
double GetXMax() const { return pmax.x; }
|
|
/// \ru Дать максимальную координату по Y. \en Give the maximal coordinate by Y.
|
|
double GetYMax() const { return pmax.y; }
|
|
/// \ru Дать максимальную координату по Z. \en Give the maximal coordinate by Z.
|
|
double GetZMax() const { return pmax.z; }
|
|
/** \} */
|
|
|
|
/// \ru Инициализировать по другому габариту. \en Initialize by another bounding box.
|
|
void Init( const MbCube & init ) { Set( init.pmin, init.pmax, false ); }
|
|
/**
|
|
\brief \ru Инициализировать по двум точкам.
|
|
\en Initialize by two points. \~
|
|
\details \ru Инициализированный куб нормализуется.
|
|
\en Initialized box is normalized. \~
|
|
\param[in] p0 - \ru Точка угла куба с минимальными координатами.
|
|
\en A point of a box corner with minimal coordinates. \~
|
|
\param[in] p1 - \ru Точка угла куба с максимальными координатами.
|
|
\en A point of a box corner with maximal coordinates. \~
|
|
*/
|
|
void Init( const MbCartPoint3D & p0, const MbCartPoint3D & p1 ) { Set( p0, p1, true ); }
|
|
/**
|
|
\brief \ru Добавить габарит.
|
|
\en Add bounding box. \~
|
|
\details \ru Габарит добавляется в локальной системе координат исходного куба.
|
|
\en A bounding box is added in the local coordinate system of the initial box. \~
|
|
\param[in] r - \ru Габарит.
|
|
\en A bounding box. \~
|
|
\param[in] place - \ru Локальная система координат.
|
|
\en A local coordinate system. \~
|
|
*/
|
|
void AddRect( const MbRect & r, const MbPlacement3D & place );
|
|
/**
|
|
\brief \ru Проекция на плейсмент.
|
|
\en A projection onto the placement. \~
|
|
\details \ru Вычисляет прямоугольник, охватывающий проекцию куба на плейсмент.
|
|
\en Calculates a rectangle covering a projection of box onto the placement. \~
|
|
\param[in] place - \ru Локальная система координат.
|
|
\en A local coordinate system. \~
|
|
\param[out] rect - \ru Прямоугольник, охватывающий искомую проекцию.
|
|
\en A rectangle covering a required projection. \~
|
|
*/
|
|
void ProjectionRect( const MbPlacement3D & place, MbRect & rect ) const;
|
|
|
|
/**
|
|
\ru \name Перегрузка логических операций.
|
|
\en \name Overload of logical operations.
|
|
\{ */
|
|
/// \ru Присвоить значение. \en Assign a value.
|
|
void operator = ( const MbCube & );
|
|
/// \ru Включить в себя точку. \en Enclose a point.
|
|
template <class Point>
|
|
MbCube & operator |= ( const Point & );
|
|
/// \ru Включить в себя габаритный куб. \en Enclose a bounding box.
|
|
MbCube & operator |= ( const MbCube & );
|
|
/// \ru Оператор равенства. \en The equality operator.
|
|
bool operator == ( const MbCube & ) const;
|
|
/// \ru Оператор неравенства. \en The inequality operator.
|
|
bool operator != ( const MbCube & ) const;
|
|
/** \} */
|
|
|
|
/// \ru Нормализовать себя. \en Normalize itself.
|
|
void Normalize ();
|
|
|
|
/**
|
|
\brief \ru Определить положение куба относительно плоскости.
|
|
\en Define the box position relative to the plane. \~
|
|
\details \ru Определить положение куба относительно плоскости XY локальной системы координат, направление оси Z локальной системы координат при этом не учитывается.
|
|
\en Define the box position relative to the plane XY of a local coordinate system, the Z axis of the local coordinate system is not taken into account here. \~
|
|
\param[in] pl - \ru Локальная система координат, задающая плоскость.
|
|
\en A local coordinate system which defines a plane. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru iloc_OnItem - куб пересекает плоскость XY локальной системы координат,\n
|
|
iloc_InItem - куб расположен над плоскостью XY локальной системы координат,\n
|
|
iloc_OutOfItem - куб расположен под плоскостью XY локальной системы координат.
|
|
\en Iloc_OnItem - box intersects the XY plane of a local coordinate system,\n
|
|
iloc_InItem - box is located over the XY plane of a local coordinate system,\n
|
|
iloc_OutOfItem - box is located under the XY plane of a local coordinate system. \~
|
|
*/
|
|
MbeItemLocation GetLocation( const MbPlacement3D & pl, double eps ) const;
|
|
|
|
/**
|
|
\brief \ru Определить положение куба относительно трубы.
|
|
\en Define the box position relative to the tube. \~
|
|
\details \ru Определить, расположен ли куб внутри трубы прямоугольного сечения,
|
|
заданного прямоугольником в плоскости XY локальной системы координат.
|
|
\en Determine whether the box is inside the tube of rectangular section,
|
|
given by a rectangle in the XY plane of a local coordinate system. \~
|
|
\param[in] place - \ru Локальная система координат, в в плоскости XY которой лежит сечение трубы.
|
|
\en A local coordinate system in the XY plane of which a tube section is located. \~
|
|
\param[in] rect - \ru Прямоугольник, задающая сечение трубы.
|
|
\en A rectangle which defines a tube section. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если куб расположен внутри трубы.
|
|
\en Returns true if the box is inside the tube. \~
|
|
*/
|
|
bool InsideLocation( const MbPlacement3D & place, MbRect & rect, double eps ) const;
|
|
|
|
/// \ru Включить в себя точку, заданную как XYZ. \en Enclose a point specified as XYZ.
|
|
/**
|
|
\param[in] x, y, z - \ru Координаты точки, которую требуется включить в габарит.
|
|
\en Coordinates of a point which has to be included in the box. \~
|
|
*/
|
|
void Include( double x, double y, double z );
|
|
|
|
/// \ru Включить в себя точку. \en Enclose a point.
|
|
template <class Point>
|
|
void Include( const Point & );
|
|
|
|
/**
|
|
\ru \name Булевы операции куба с точкой, линией, плоскостью и другим кубом.
|
|
\en \name The boolean operations of a box with a point, line, plane and another box.
|
|
\{ */
|
|
|
|
|
|
/// \ru Проверить, лежит ли точка внутри габаритного параллелепипеда. \en Check whether a point is inside the box or not.
|
|
/**
|
|
\return \ru true, если лежит.
|
|
\en Returns true if it is inside. \~
|
|
*/
|
|
template <class Point>
|
|
bool Contains( const Point & ) const;
|
|
|
|
/// \ru Проверить, лежит ли точка внутри габаритного параллелепипеда. \en Check whether a point is inside the box or not.
|
|
/**
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если лежит.
|
|
\en Returns true if it is inside. \~
|
|
*/
|
|
template <class Point>
|
|
bool Contains( const Point &, double eps ) const;
|
|
|
|
/// \ru Проверить, содержит ли один параллелепипед другой. \en Check whether a box is inside another box or not.
|
|
/**
|
|
\return \ru true, если данный габаритный параллелепипед содержит другой.
|
|
\en Returns true if a box contains another. \~
|
|
*/
|
|
bool Contains( const MbCube & ) const;
|
|
|
|
/// \ru Пересекается ли габаритный параллелепипед с другим параллелепипедом. \en Whether the box intersects another box or not.
|
|
/**
|
|
\param[in] other - \ru Другой параллелепипед.
|
|
\en Another box. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если пересекается.
|
|
\en Returns true if it intersects. \~
|
|
*/
|
|
bool Intersect( const MbCube & other, double eps = (c3d::MIN_RADIUS + c3d::MIN_RADIUS) ) const;
|
|
|
|
/// \ru Пересекается ли куб с плоскостью XY локальной системы координат. \en Whether the box intersects the XY plane of a local coordinate system or not.
|
|
/**
|
|
\param[in] pl - \ru Плейсмент, задающий плоскость.
|
|
\en A placement which defines a plane. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если пересекается.
|
|
\en Returns true if it intersects. \~
|
|
*/
|
|
bool Intersect( const MbPlacement3D & pl, double eps = c3d::MIN_RADIUS ) const;
|
|
|
|
/**
|
|
\brief \ru Пересекается ли куб с линией.
|
|
\en Whether the box intersects the line or not. \~
|
|
\details \ru Линия задается точкой и вектором.
|
|
\en A line is given by a point and vector. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если пересекается.
|
|
\en Returns true if it intersects. \~
|
|
*/
|
|
bool Intersect( const MbCartPoint3D &, const MbVector3D &, double eps = Math::metricRegion ) const;
|
|
|
|
/// \ru Найти пересечение прямой с "поверхностью" куба. \en Find an intersection of a line with the box "surface".
|
|
/**
|
|
\param[in] p - \ru Точка на прямой.
|
|
\en The point on the line. \~
|
|
\param[in] axis - \ru Вектор, задающий направление прямой.
|
|
\en A vector which defines the direction of the line. \~
|
|
\param[out] param - \ru Точки пересечения.
|
|
\en Intersection points. \~
|
|
\param[in] delta - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если пересечение есть, \n false в противном случае.
|
|
\en Returns true if intersection exists, \n false otherwise. \~
|
|
*/
|
|
bool Intersect( const MbCartPoint3D & p,
|
|
const MbVector3D & axis,
|
|
SArray<double> & param,
|
|
double delta = Math::metricRegion ) const;
|
|
|
|
/// \ru Пересечение куба и окружности. \en The intersection of the box with a circle.
|
|
/**
|
|
\param[in] placement - \ru Плейсмент окружности.
|
|
\en A circle placement. \~
|
|
\param[in] radius - \ru Радиус окружности.
|
|
\en The circle radius. \~
|
|
\param[out] param - \ru Точки пересечения.
|
|
\en Intersection points. \~
|
|
\param[in] delta - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если пересечение есть, \n false в противном случае.
|
|
\en Returns true if intersection exists, \n false otherwise. \~
|
|
*/
|
|
bool Intersect( const MbPlacement3D & placement,
|
|
double radius,
|
|
SArray<double> & param,
|
|
double delta = Math::metricRegion ) const;
|
|
|
|
/// \ru Куб пересечения двух кубов. \en A box of intersection of two boxes.
|
|
/**
|
|
\param[in] cube1, cube2 - \ru Исходные кубы.
|
|
\en Input boxes. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru true, если пересечение есть, \n false в противном случае.
|
|
\en Returns true if intersection exists, \n false otherwise. \~
|
|
*/
|
|
bool Intersection( const MbCube & cube1, const MbCube & cube2, double eps = c3d::MIN_RADIUS );
|
|
|
|
/// \ru Куб объединения двух кубов. \en A box of union of two boxes.
|
|
/**
|
|
\param[in] cube1, cube2 - \ru Исходные кубы.
|
|
\en Input boxes. \~
|
|
\return \ru false, если итоговый куб пуст, \n true в противном случае.
|
|
\en Returns false if the result box is empty, \n true otherwise. \~
|
|
*/
|
|
bool Union ( const MbCube & cube1, const MbCube & cube2 );
|
|
/** \} */
|
|
|
|
/// \ru Дать объем куба. \en Give the volume of a box.
|
|
double GetVolume ( double eps = Math::metricRegion ) const;
|
|
/// \ru Дать половину площади граней куба. \en Give half of the area of the cube faces.
|
|
double GetSquare ( double eps = Math::metricRegion ) const;
|
|
/// \ru Дать размер стороны X куба. \en Give the size of the X side of a box.
|
|
double GetLengthX() const { return pmax.x - pmin.x; }
|
|
/// \ru Дать размер стороны Y куба. \en Give the size of the Y side of a box.
|
|
double GetLengthY() const { return pmax.y - pmin.y; }
|
|
/// \ru Дать размер стороны Z куба. \en Give the size of the Z side of a box.
|
|
double GetLengthZ() const { return pmax.z - pmin.z; }
|
|
/// \ru Дать размер диагонали куба. \en Give the size of box diagonal.
|
|
double GetDiagonal() const;
|
|
|
|
/** \brief \ru Вычислить расстояние до ближайшей грани габаритного суба.
|
|
\en Calculate the distance to the nearest boundary of the bounding box. \~
|
|
\details \ru Найденное расстояние до ближайшей границы имеет отрицательное значение, если точка находится внутри, и положительное - если снаружи.
|
|
\en The calculated distance is negative if the point is inside, and is positive if it is outside. \~
|
|
\param[in] point - \ru Исследуемая точка.
|
|
\en The investigated point. \~
|
|
\return \ru Возвращает расстояние до границы.
|
|
\en Returns the distance to the boundary. \~
|
|
*/
|
|
double DistanceToPoint( const MbCartPoint3D & point ) const;
|
|
|
|
/** \brief \ru Вычислить расстояние до куба.
|
|
\en Calculate the distance to the cube. \~
|
|
\details \ru Возвращается ноль, если кубы пересекаются или один содержится в другом.
|
|
\en It returns zero if the cubes intersect or one is contained in the other. \~
|
|
\param[in] cube - \ru Другой куб.
|
|
\en Other cube. \~
|
|
\param[in] eps - \ru Метрическая точность.
|
|
\en A metric tolerance. \~
|
|
\return \ru Возвращает расстояние до границы.
|
|
\en Returns the distance to the boundary. \~
|
|
*/
|
|
double DistanceToCube( const MbCube & cube, double eps = Math::metricRegion ) const;
|
|
|
|
/// \ru Расширить куб во все стороны на величину delta. \en Expand the box in all directions on a "delta" amount.
|
|
void Enlarge ( double delta );
|
|
/// \ru Расширить куб во все стороны на соответствующую величину. \en Expand the box in all directions on a corresponding amount.
|
|
void Enlarge ( double dx, double dy, double dz );
|
|
/// \ru Сдвинуть вдоль вектора. \en Translate along a vector.
|
|
void Move ( const MbVector3D & to );
|
|
/// \ru Преобразовать согласно матрице. \en Transform according to the matrix.
|
|
void Transform( const MbMatrix3D & matrix );
|
|
/// \ru Масштабировать. \en Scale.
|
|
void Scale ( double sx, double sy, double sz );
|
|
/// \ru Являются ли объекты равными? \en Determine whether an object is equal?
|
|
bool IsSame( const MbCube & other, double accuracy ) const;
|
|
|
|
/// \ru Количество координат точки. \en The number of point coordinates.
|
|
static size_t GetDimension() { return 3; }
|
|
/// \ru Доступ к минимальной координате по индексу. \en Access to a coordinate by an index.
|
|
double GetMin( size_t k ) const { return k ? (--k ? pmin.z : pmin.y) : pmin.x; }
|
|
/// \ru Доступ к максимальной координате по индексу. \en Access to a coordinate by an index.
|
|
double GetMax( size_t k ) const { return k ? (--k ? pmax.z : pmax.y) : pmax.x; }
|
|
/// \ru Дать длина по стороне. \en Get side length.
|
|
double GetSideLength( size_t k ) const { return k ? (--k ? ::fabs(GetLengthZ()) : ::fabs(GetLengthY())) : ::fabs(GetLengthX()); }
|
|
|
|
/// \ru Дать себя. \en Give itself.
|
|
const MbCube & GetCube() const { return *this; }
|
|
|
|
// \ru Общая нумерация характерных точек куба: \en General numeration of box control points:
|
|
// \ru 0-7 вершины, 8-19 середины рёбер, 20-25 центры граней \en 0-7 vertices, 8-19 middles of edges, 20-25 centers of faces
|
|
// Z
|
|
// |
|
|
// 4------15------7
|
|
// /| /|
|
|
// 12| 25 14|
|
|
// / 16 20 / 19
|
|
// 5---+--13------6 |
|
|
// | 22| | 23|
|
|
// | 0------11--+---3 - Y
|
|
// 17 / 21 18 /
|
|
// | 8 24 | 10
|
|
// |/ |/
|
|
// 1-------9------2
|
|
// /
|
|
// X
|
|
// \ru Выдать характерные точки куба \en Give control points of the box
|
|
/// \ru Количество вершин. \en Number of vertices.
|
|
size_t GetVerticesCount() const { return 8; }
|
|
/// \ru Выдать вершину куба по индексу. \en Get a box vertex by an index.
|
|
/**
|
|
\param[in] index - \ru Исходный индекс. 0 <= index <= 7.
|
|
\en An initial index. 0 <= index <= 7. \~
|
|
\param[out] p - \ru Искомая вершина.
|
|
\en Required vertex. \~
|
|
*/
|
|
void GetVertex( ptrdiff_t index, MbCartPoint3D & p ) const;
|
|
/// \ru Выдать центр ребра по индексу. \en Give the center of an edge by an index.
|
|
/**
|
|
\param[in] index - \ru Исходный индекс. 0 <= index <= 12 (общий номер минус CUBE_VERTEX_COUNT).
|
|
\en An initial index. 0 <= index <= 12 ("general number" minus CUBE_VERTEX_COUNT). \~
|
|
\param[out] p - \ru Координаты центра ребра.
|
|
\en Coordinates of an edge center. \~
|
|
*/
|
|
void GetEdgeCentre( ptrdiff_t index, MbCartPoint3D & p ) const;
|
|
/// \ru Выдать центр грани по индексу. \en Give the center of a face by an index.
|
|
/**
|
|
\param[in] index - \ru Исходный индекс. 0 <= index <= 5 (общий номер минус CUBE_VERTEX_COUNT минус CUBE_EDGES_COUNT).
|
|
\en An initial index. 0 <= index <= 5 ("general number" minus CUBE_VERTEX_COUNT minus CUBE_EDGES_COUNT). \~
|
|
\param[out] p - \ru Координаты центра ребра.
|
|
\en Coordinates of an edge center. \~
|
|
*/
|
|
void GetFaceCentre( ptrdiff_t index, MbCartPoint3D & p ) const;
|
|
/// \ru Выдать центр куба. \en Give the box center.
|
|
void GetCentre( MbCartPoint3D & p ) const { p.Set( pmax, 0.5, pmin, 0.5 ); }
|
|
/// \ru Выдать центр куба. \en Give the box center.
|
|
void GetCenter( MbCartPoint3D & p ) const { p.Set( pmax, 0.5, pmin, 0.5 ); }
|
|
/// \ru Центр габарита. \en The center of bounding box.
|
|
MbCartPoint3D Centre() const;
|
|
|
|
/**
|
|
\brief \ru Дать характерную точку куба по ее номеру.
|
|
\en Give a box control point by its number. \~
|
|
\details \ru Общая нумерация характерных точек куба: 0-7 вершины, 8-19 середины рёбер, 20-25 центры граней.
|
|
\en General numeration of box control points: 0-7 vertices, 8-19 middles of edges, 20-25 centers of faces. \~
|
|
\param[in] pIndex - \ru Номер характерных точек.
|
|
\en A number of control points. \~
|
|
\param[out] p - \ru Координаты характерной точки.
|
|
\en Coordinates of control point. \~
|
|
\return \ru false, если куб пуст или индекс принимает недопустимое значение, \n true в противном случае.
|
|
\en Returns false if the box is empty or the index has an invalid value, \n true otherwise. \~
|
|
*/
|
|
bool GetControlPoint( size_t pIndex, MbCartPoint3D & p ) const;
|
|
/**
|
|
\brief \ru Выдать все характерные точки куба.
|
|
\en Give all control points of the box. \~
|
|
\details \ru Все характерные точки куба: 8 вершин, 12 середин рёбер, 6 центров граней.
|
|
\en All control points of the box: 8 vertices, 12 middles of edges, 6 centers of faces. \~
|
|
\param[out] points - \ru Характерные точки.
|
|
\en Control points. \~
|
|
\return \ru Число характерных точек. Ноль, если куб пуст.
|
|
\en The number of control points. Null if the box is empty. \~
|
|
*/
|
|
size_t GetControlPoints( SArray<MbCartPoint3D> & points ) const;
|
|
/// \ru Выдать номер ближайшей характерной точки куба. \en Give the number of the nearest control point of the box.
|
|
/**
|
|
\param[in] p - \ru Исходная точка, к которой ищется ближайшая характерная точка куба.
|
|
\en An initial point for which the nearest control point of the box is searched. \~
|
|
\return \ru Номер точки.
|
|
\en A number of a point. \~
|
|
*/
|
|
size_t GetNearestControlIndex( const MbCartPoint3D & p ) const;
|
|
/**
|
|
\brief \ru Дать номер противолежащей точки.
|
|
\en Give the number of the opposite point. \~
|
|
\details \ru Для точки куба с номером index дать номер противолежащей точки,
|
|
которая может использоваться в качестве фиксированной.
|
|
\en For a box point with the "index" number give the number of the opposite point,
|
|
which can be used as fixed. \~
|
|
\param[in] index - \ru Номер исходной точки.
|
|
\en The number of the initial point. \~
|
|
\return \ru Номер противолежащей точки.
|
|
\en A number of the opposite point. \~
|
|
*/
|
|
size_t GetFixedControlIndex ( size_t index ) const;
|
|
/**
|
|
\brief \ru Рассчитать матрицу деформации.
|
|
\en Calculate a deformation matrix. \~
|
|
\details \ru Матрица деформации рассчитывается по-новому положению point характерной точки куба с индексом pIndex.
|
|
\en A deformation matrix is calculated according to the new position of box control point "point" with the index "pIndex". \~
|
|
\param[in] pIndex - \ru Номер смещаемой точки (0-7 вершины, 8-19 середины рёбер, 20-25 центры граней).
|
|
\en A number of a moved point (0-7 vertices, 8-19 middles of edges, 20-25 centers of faces). \~
|
|
\param[in] point - \ru Точка, с которой нужно совместить точку куба с номером pIndex.
|
|
\en A point with which the box point with the "pIndex" number has to be joined. \~
|
|
\param[in] fixedPoint - \ru Неподвижная точка преобразования, используется, если useFixed = true.
|
|
\en A fixed point. It is used if useFixed = true. \~
|
|
\param[in] useFixed - \ru Использовать неподвижную точку (true), если useFixed = false, то неподвижной будет противолежащая точка куба.
|
|
\en Use a fixed point (true); if useFixed = false, then the opposite point of the box will be fixed. \~
|
|
\param[in] isotropy - \ru Одинаковые масштабы по осям (true), масштабы, пропорциональны проекциям смещения рассматриваемой точки на стороны куба (false)
|
|
\en The same scales of the axes (true); the scales are proportional to the shift projections of the considered point on the sides of the box (false) \~
|
|
\param[out] matrix - \ru Рассчитанная матрица преобразования.
|
|
\en Calculated transformation matrix. \~
|
|
\return \ru true, если искомая матрица была найдена.
|
|
\en Returns true if the matrix was found. \~
|
|
*/
|
|
bool CalculateMatrix( size_t pIndex, const MbCartPoint3D & point, const MbCartPoint3D & fixedPoint,
|
|
bool useFixed, bool isotropy, MbMatrix3D & matrix ) const;
|
|
public:
|
|
|
|
KNOWN_OBJECTS_RW_REF_OPERATORS( MbCube )
|
|
DECLARE_NEW_DELETE_CLASS( MbCube )
|
|
DECLARE_NEW_DELETE_CLASS_EX( MbCube )
|
|
};
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Центр габарита \en The center of bounding box
|
|
//---
|
|
inline MbCartPoint3D MbCube::Centre() const
|
|
{
|
|
return MbCartPoint3D().Set( pmax, 0.5, pmin, 0.5 );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Установить пустым ("вывернутым") \en Set empty ("reverted")
|
|
// ---
|
|
inline void MbCube::SetEmpty()
|
|
{
|
|
pmin.x = pmin.y = pmin.z = MB_MAXDOUBLE;
|
|
pmax.x = pmax.y = pmax.z = -MB_MAXDOUBLE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Проверка на пустоту \en The check for emptiness.
|
|
// ---
|
|
inline bool MbCube::IsEmpty() const {
|
|
return ( pmin.x > pmax.x ) || ( pmin.y > pmax.y ) || ( pmin.z > pmax.z );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Установить значения куба \en Set a box values.
|
|
// ---
|
|
inline void MbCube::Set( double xmin, double ymin, double zmin,
|
|
double xmax, double ymax, double zmax,
|
|
bool normalize )
|
|
{
|
|
if ( normalize ) {
|
|
pmin.x = std_min( xmin, xmax );
|
|
pmin.y = std_min( ymin, ymax );
|
|
pmin.z = std_min( zmin, zmax );
|
|
pmax.x = std_max( xmin, xmax );
|
|
pmax.y = std_max( ymin, ymax );
|
|
pmax.z = std_max( zmin, zmax );
|
|
}
|
|
else {
|
|
pmin.x = xmin;
|
|
pmin.y = ymin;
|
|
pmin.z = zmin;
|
|
pmax.x = xmax;
|
|
pmax.y = ymax;
|
|
pmax.z = zmax;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Установить значения куба \en Set a box values.
|
|
// ---
|
|
inline void MbCube::Set( const MbCartPoint3D & p0, const MbCartPoint3D & p1, bool normalize )
|
|
{
|
|
if ( normalize ) {
|
|
pmin.x = std_min( p0.x, p1.x );
|
|
pmin.y = std_min( p0.y, p1.y );
|
|
pmin.z = std_min( p0.z, p1.z );
|
|
pmax.x = std_max( p0.x, p1.x );
|
|
pmax.y = std_max( p0.y, p1.y );
|
|
pmax.z = std_max( p0.z, p1.z );
|
|
}
|
|
else {
|
|
pmin = p0;
|
|
pmax = p1;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Присвоение \en Assignment
|
|
// ---
|
|
inline void MbCube::operator = ( const MbCube & other ) {
|
|
pmin = other.pmin;
|
|
pmax = other.pmax;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Включить в себя точку \en Enclose a point.
|
|
// ---
|
|
template <class Point>
|
|
inline MbCube & MbCube::operator |= ( const Point & p )
|
|
{
|
|
pmin.x = std_min( pmin.x, (double)p.x );
|
|
pmin.y = std_min( pmin.y, (double)p.y );
|
|
pmin.z = std_min( pmin.z, (double)p.z );
|
|
pmax.x = std_max( pmax.x, (double)p.x );
|
|
pmax.y = std_max( pmax.y, (double)p.y );
|
|
pmax.z = std_max( pmax.z, (double)p.z );
|
|
return *this;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Включить в себя точку,заданную как XYZ \en Enclose a point specified as XYZ.
|
|
// ---
|
|
inline void MbCube::Include( double x, double y, double z )
|
|
{
|
|
pmin.x = std_min( pmin.x, x );
|
|
pmin.y = std_min( pmin.y, y );
|
|
pmin.z = std_min( pmin.z, z );
|
|
pmax.x = std_max( pmax.x, x );
|
|
pmax.y = std_max( pmax.y, y );
|
|
pmax.z = std_max( pmax.z, z );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Включить в себя точку \en Enclose a point
|
|
//---
|
|
template <class Point>
|
|
inline void MbCube::Include( const Point & pnt ) {
|
|
Include( pnt.x, pnt.y, pnt.z );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Включить в себя габаритный куб \en Enclose a bounding box.
|
|
// ---
|
|
inline MbCube & MbCube::operator |= ( const MbCube & other )
|
|
{
|
|
pmin.x = std_min( pmin.x, other.pmin.x );
|
|
pmin.y = std_min( pmin.y, other.pmin.y );
|
|
pmin.z = std_min( pmin.z, other.pmin.z );
|
|
pmax.x = std_max( pmax.x, other.pmax.x );
|
|
pmax.y = std_max( pmax.y, other.pmax.y );
|
|
pmax.z = std_max( pmax.z, other.pmax.z );
|
|
return *this;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Проверка равенства с другим габаритом. \en The check for equality with another box.
|
|
// ---
|
|
inline bool MbCube::operator == ( const MbCube & other ) const
|
|
{
|
|
return c3d::EqualPoints( pmin, other.pmin, Math::lengthEpsilon ) &&
|
|
c3d::EqualPoints( pmax, other.pmax, Math::lengthEpsilon );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Проверка неравенства с другим кубом. \en The check for inequality with another box.
|
|
// ---
|
|
inline bool MbCube::operator != ( const MbCube & other) const {
|
|
return !( other == *this );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Проверка на то, что заданная точка лежит внутри куба \en Check whether a given point is inside the box or not
|
|
// ---
|
|
template <class Point>
|
|
inline bool MbCube::Contains( const Point & p ) const
|
|
{
|
|
return ( ( (double)p.x >= pmin.x ) && ( (double)p.x <= pmax.x ) &&
|
|
( (double)p.y >= pmin.y ) && ( (double)p.y <= pmax.y ) &&
|
|
( (double)p.z >= pmin.z ) && ( (double)p.z <= pmax.z ) );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
// \ru Проверка на то, что заданная точка лежит внутри габарита. \en Check whether a given point is inside the box or not.
|
|
// ---
|
|
template <class Point>
|
|
inline bool MbCube::Contains( const Point & p, double eps ) const
|
|
{
|
|
return ( ((double)p.x > (pmin.x - eps)) && ((double)p.x < (pmax.x + eps)) &&
|
|
((double)p.y > (pmin.y - eps)) && ((double)p.y < (pmax.y + eps)) &&
|
|
((double)p.z > (pmin.z - eps)) && ((double)p.z < (pmax.z + eps)) );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// \ru Проверить, содержит ли один параллелепипед другой. \en Check whether a box is inside another box or not.
|
|
//---
|
|
inline bool MbCube::Contains( const MbCube & box ) const
|
|
{
|
|
return Contains( box.pmin ) && Contains( box.pmax );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Нормализовать себя \en Normalize itself
|
|
// ---
|
|
inline void MbCube::Normalize()
|
|
{
|
|
double tmp;
|
|
if ( pmin.x > pmax.x )
|
|
{ tmp = pmin.x; pmin.x = pmax.x; pmax.x = tmp; }
|
|
if ( pmin.y > pmax.y )
|
|
{ tmp = pmin.y; pmin.y = pmax.y; pmax.y = tmp; }
|
|
if ( pmin.z > pmax.z )
|
|
{ tmp = pmin.z; pmin.z = pmax.z; pmax.z = tmp; }
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Расширить куб во все стороны \en Expand the box in all directions
|
|
// ---
|
|
inline void MbCube::Enlarge( double delta )
|
|
{
|
|
pmin.x -= delta;
|
|
pmin.y -= delta;
|
|
pmin.z -= delta;
|
|
|
|
pmax.x += delta;
|
|
pmax.y += delta;
|
|
pmax.z += delta;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Расширить куб во все стороны. \en Expand the box in all directions
|
|
// ---
|
|
inline void MbCube::Enlarge( double dx, double dy, double dz )
|
|
{
|
|
pmin.x -= dx;
|
|
pmin.y -= dy;
|
|
pmin.z -= dz;
|
|
|
|
pmax.x += dx;
|
|
pmax.y += dy;
|
|
pmax.z += dz;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Сдвиг \en Translation
|
|
// ---
|
|
inline void MbCube::Move( const MbVector3D & to )
|
|
{
|
|
if ( !IsEmpty() ) {
|
|
pmin.Move( to );
|
|
pmax.Move( to );
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Расстояние до точки \en The distance to a point
|
|
// ---
|
|
inline double MbCube::DistanceToPoint( const MbCartPoint3D & pnt ) const
|
|
{
|
|
double dx = std_max( pmin.x - pnt.x, pnt.x - pmax.x );
|
|
double dy = std_max( pmin.y - pnt.y, pnt.y - pmax.y );
|
|
double dz = std_max( pmin.z - pnt.z, pnt.z - pmax.z );
|
|
double dd = std_max( dx, dy );
|
|
return std_max( dd, dz );
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// \ru Чтение куба из потока \en Reading of the box from a stream
|
|
// ---
|
|
inline reader & CALL_DECLARATION operator >> ( reader & in, MbCube & obj )
|
|
{
|
|
in >> obj.pmin;
|
|
in >> obj.pmax;
|
|
return in;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// \ru Запись куба в поток \en Writing of the box into the stream
|
|
// ---
|
|
inline writer & CALL_DECLARATION operator << ( writer & out, const MbCube & obj )
|
|
{
|
|
out << obj.pmin;
|
|
out << obj.pmax;
|
|
return out;
|
|
}
|
|
|
|
|
|
#endif // __MB_CUBE_H
|