Files
SaraP 86f4bb48be Extern :
- C3d aggiornamento delle librerie ( 117960).
2023-10-12 08:53:50 +02:00

774 lines
42 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru Вектор в трехмерном пространстве.
\en Vector in three-dimensional space. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __MB_VECTOR3D_H
#define __MB_VECTOR3D_H
#include <io_base.h>
#include <mb_enum.h>
class MATH_CLASS MbVector;
class MATH_CLASS MbCartPoint3D;
class MATH_CLASS MbHomogeneous3D;
class MATH_CLASS MbFloatVector3D;
class MATH_CLASS MbAxis3D;
class MATH_CLASS MbPlacement3D;
class MATH_CLASS MbMatrix3D;
class MATH_CLASS MbProperties;
//------------------------------------------------------------------------------
/** \brief \ru Вектор в трехмерном пространстве.
\en Vector in three-dimensional space. \~
\details \ru Вектор описывает перемещение или направление в трёхмерном пространстве
и определяется тремя компонентами x, y, z в декартовой системе координат. \n
Вектор не привязан к точкам пространства и поэтому не имеет метода,
перемещающего его в пространстве. \n
\en Vector describes translation or direction in three-dimensional space
and is defined by three coordinates x, y, z in the Cartesian coordinate system. \n
Vector is not binded to space points and therefore has not method
for translating it in space. \n \~
\ingroup Mathematic_Base_3D
*/
// ---
class MATH_CLASS MbVector3D {
public :
double x; ///< \ru Первая компонента вектора. \en First component of vector.
double y; ///< \ru Вторая компонента вектора. \en Second component of vector.
double z; ///< \ru Третья компонента вектора. \en Third component of vector.
static const MbVector3D zero; ///< \ru Нулевой вектор. \en Zero vector.
static const MbVector3D xAxis; ///< \ru Вектор "X" стандартного базиса. \en "X" vector of standard basis.
static const MbVector3D yAxis; ///< \ru Вектор "Y" стандартного базиса. \en "Y" vector of standard basis.
static const MbVector3D zAxis; ///< \ru Вектор "Z" стандартного базиса. \en "Z" vector of standard basis.
public :
/// \ru Конструктор без параметров, вектор нулевой. \en Constructor without parameters, vector is zero.
MbVector3D () : x( 0.0 ), y( 0.0 ), z( 0.0 ) {}
/// \ru Конструктор по координатам. \en The constructor by coordinates.
MbVector3D ( double a, double b, double c ) : x( a ), y( b ), z( c ) {}
/// \ru Конструктор-копия. \en Copy constructor.
MbVector3D ( const MbVector3D & v ) : x( v.x ), y( v.y ), z( v.z ) {}
/// \ru Конструктор копирования. \en Copy-constructor.
MbVector3D ( const MbFloatVector3D & );
/// \ru Конструктор по точке. \en Constructor by point.
MbVector3D ( const MbCartPoint3D & p );
/// \ru Конструктор по двум точкам. \en Constructor by two points.
MbVector3D ( const MbCartPoint3D & p1, const MbCartPoint3D & p2 ) { Init( p1, p2 ); }
/// \ru Конструктор по двумерному вектору в плоскости XOY локальной системы координат place. \en Constructor by two-dimensional vector in XOY plane of local coordinate system 'place'.
MbVector3D ( const MbVector & v2d, const MbPlacement3D & place ) { Init( v2d, place ); }
/// \ru Конструктор по двумерному вектору в плоскости XOY локальной системы координат place. \en Constructor by two-dimensional vector in XOY plane of local coordinate system 'place'.
MbVector3D( const MbVector & v2d ) { InitXY( v2d ); }
/// \ru Инициализировать по двумерному вектору в плоскости XOY локальной системы координат place. \en Initialize by two-dimensional vector in XOY plane of local coordinate system 'place'.
void Init( const MbVector &, const MbPlacement3D & );
/// \ru Инициализировать по двумерному вектору. \en Initialize by two-dimensional vector.
void InitXY( const MbVector & );
/// \ru Инициализировать по координатам. \en Initialize by coordinates.
void Init( double a, double b, double c ) { x = a; y = b; z = c; }
/// \ru Инициализировать по другому вектору. \en Initialize by another vector.
template <class Vector>
void Init( const Vector & v ) { x = v.x; y = v.y; z = v.z; }
/// \ru Инициализировать по двум точкам. \en Initialize by two points.
void Init( const MbCartPoint3D & p1, const MbCartPoint3D & p2 );
/// \ru Увеличить координаты на заданные величины. \en Increase coordinates by given values.
void Add ( double a, double b, double c ) { x += a; y += b; z += c; }
/// \ru Увеличить координаты на значение координат заданного вектора. \en Increase coordinates by values of given vector.
void Add ( const MbVector3D & v ) { x += v.x; y += v.y; z += v.z; }
/// \ru Обнулить координаты вектора. \en Set coordinates of vector to zero.
void SetZero() { x = y = z = 0.0; }
/// \ru Является ли вектор нулевым? \en Check if vector is zero.
bool IsZero ( double eps = Math::lengthEpsilon ) const;
/// \ru Преобразовать согласно матрице. Матрица действует на вектор справа. \en Transform according to the matrix. A matrix acts on a vector from the right.
MbVector3D & Transform( const MbMatrix3D & matr );
/// \ru Повернуть вокруг оси на заданный угол. \en Rotate at given angle around axis.
MbVector3D & Rotate( const MbVector3D & axis, double angle );
/// \ru Повернуть вокруг оси на заданный угол. \en Rotate at given angle around axis.
MbVector3D & Rotate( const MbAxis3D & axis, double angle );
/// \ru Повернуть вокруг оси (по её номеру) на заданный угол ( 0 - ось X, 1 - ось Y, 2 - ось Z ). \en Rotate around the axis (by its number) at a given angle ( 0 - X-axis, 1 - Y-axis, 2 - Z-axis ).
MbVector3D & RotateXYZ( int number, double angle );
/// \ru Проверить вектор на вырожденность. \en Check vector for degeneracy.
bool IsDegenerate( double comEps = Math::region ) const;
/// \ru Проверить вектор на нормированность. \en Check if vector is normalized.
bool IsNormalized( double eps = Math::lengthEpsilon ) const;
/// \ru Проверить коллинеарность векторов с заданной точностью (по косинусу угла между векторами). \en Check if vectors are colinear with given tolerance (by cosine of angle between vectors).
bool RoundColinear( const MbVector3D & with, double eps = Math::paramNear ) const;
/// \ru Проверить коллинеарность векторов с заданной точностью (по синусу угла между векторами). \en Check if vectors are colinear with given tolerance (by sine of angle between vectors).
bool Colinear ( const MbVector3D & with, double eps = Math::angleRegion ) const;
/// \ru Проверить ортогональность векторов с заданной точностью. \en Check if vectors are orthogonal with given tolerance.
bool Orthogonal( const MbVector3D & with, double eps = Math::angleRegion ) const;
/// \ru Рассчитать длину вектора. \en Calculate vector length.
double Length() const;
/// \ru Рассчитать квадрат длины вектора. \en Calculate vector length square
double Length2() const;
/// \ru Рассчитать угол между векторами. \en Calculate angle between vectors.
double Angle( const MbVector3D & with ) const;
/// \ru Нормализовать вектор. \en Normalize a vector.
bool Normalize();
/// \ru Вернуть нормализованную копию вектора. \en Return normalized copy of vector.
MbVector3D GetNormalized() const;
/// \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite.
MbVector3D& Invert();
/// \ru Вернуть составляющую часть вектора, параллельную вектору v. \en Get parallel to vector v part of vector.
MbVector3D TangentComponent( const MbVector3D & v ) const;
/// \ru Вернуть составляющую часть вектора, ортогональную вектору v. \en Get orthogonal to vector v part of vector.
MbVector3D NormalComponent ( const MbVector3D & v ) const;
/// \ru Учесть перспективу для первой производной. \en Perspective for first derivative is to be considered.
void PspDerivative ( double, const MbCartPoint3D & );
/// \ru Учесть перспективу для производной второго порядка. \en Perspective for second derivative is to be considered.
void PspDerivative2 ( double, const MbCartPoint3D &, const MbVector3D & );
/// \ru Учесть перспективу для смешанной производной второго порядка. \en Perspective for second order mixed derivative is to be considered.
void PspDerivative2Mix ( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D & );
/// \ru Учесть перспективу для производной третьего порядка. \en Perspective for third derivative is to be considered.
void PspDerivative3 ( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D & );
/// \ru Учесть перспективу для смешанной производной третьего порядка. \en Perspective for third order mixed derivative is to be considered.
void PspDerivative3Mix ( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D &,
const MbVector3D &, const MbVector3D & );
/// \ru Учесть перспективу для нормали. \en Perspective for normal is to be considered.
void PspNormal ( double, const MbCartPoint3D & );
/// \ru Учесть перспективу для производной нормали. \en Perspective for derivative of normal is to be considered.
void PspNormalDerivative( double, const MbCartPoint3D &, const MbVector3D &, const MbVector3D & );
/// \ru Проверить на равенство. \en Check for equality.
bool operator == ( const MbVector3D & ) const;
/// \ru Проверить на неравенство. \en Check for inequality.
bool operator != ( const MbVector3D & ) const;
/// \ru Сложить векторы. \en Sum up two vectors.
MbVector3D operator + ( const MbVector3D & ) const;
/// \ru Найти разность векторов. \en Find the difference of vectors.
MbVector3D operator - ( const MbVector3D & ) const;
/// \ru Сложить вектор с точкой. \en Sum up vector and point.
MbVector3D operator + ( const MbCartPoint3D & ) const;
/// \ru Вычесть из вектора точку. \en Subtract point from vector.
MbVector3D operator - ( const MbCartPoint3D & ) const;
/// \ru Унарный минус. \en Unary minus.
MbVector3D operator - () const;
/// \ru Сложить векторы. \en Sum up two vectors.
MbVector3D & operator += ( const MbVector3D & );
/// \ru Вычесть из вектора точку. \en Subtract point from vector.
MbVector3D & operator -= ( const MbVector3D & );
/// \ru Умножить вектор на число. \en Multiply vector by number.
MbVector3D & operator *= ( double );
/// \ru Разделить вектор на число. \en Divide vector by number.
MbVector3D & operator /= ( double );
/// \ru Вычислить скалярное произведение двух векторов. \en Calculate dot product of two vectors.
double operator * ( const MbVector3D & ) const;
/// \ru Вычислить векторное произведение двух векторов. \en Calculate vector product of two vectors.
MbVector3D operator | ( const MbVector3D & ) const;
/// \ru Вычислить прямое произведение двух векторов. \en Calculate direct product of two vectors.
MbMatrix3D operator & ( const MbVector3D & ) const;
/// \ru Вычислить вектор как копию данного вектора, преобразованную матрицей. \en Calculate the vector as this copy transformed by the matrix.
MbVector3D operator * ( const MbMatrix3D & ) const;
/// \ru Присвоить вектору значения координат точки. \en Assign point coordinate values to vector.
MbVector3D & operator = ( const MbCartPoint3D & );
/// \ru Присвоить вектору значения однородных координат точки. \en Assign uniform point coordinate values to vector.
MbVector3D & operator = ( const MbHomogeneous3D & );
/// \ru Присвоить вектору координаты другого вектора. \en Assign coordinates of another vector to the vector.
MbVector3D & operator = ( const MbFloatVector3D & );
/// \ru Присвоить вектору значения другого вектора. \en Assign the value of another vector to the vector.
MbVector3D & operator = ( const MbVector3D & );
/// \ru Получить доступ к координате по индексу. \en Access to coordinate by an index.
double & operator [] ( size_t i ) { return i ? (--i ? z : y) : x; };
/// \ru Получить значение координаты по индексу. \en Get coordinate value by an index.
double operator [] ( size_t i ) const { return i ? (--i ? z : y) : x; };
/// \ru Получить количество координат точки. \en Get point coordinates count.
static size_t GetDimension() { return 3; }
/// \ru Приравнять вектору вектор v1, умноженный на t1. \en Equate vector with vector v1 multiplied by t1.
void Set( const MbVector3D & v1, double t1 );
/// \ru Приравнять вектору сумму векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector with sum of vectors v1 and v2 multiplied with t1 and t2 correspondingly.
void Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 );
/// \ru Приравнять вектору сумму векторов v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector with sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly.
void Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3 );
/// \ru Приравнять вектору сумму векторов v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector with sum of vectors v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly.
void Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 );
/// \ru Приравнять координаты вектора координатам точки v1, умноженных на t1. \en Equate coordinates of vector with coordinates of point v1 multiplied by t1.
void Set( const MbCartPoint3D & v1, double t1 );
/// \ru Приравнять координаты вектора координатам суммы точек v1 и v2, умноженных на t1 и t2 соответственно. \en Equate vector coordinates with sum of points v1 and v2 multiplied with t1 and t2 correspondingly.
void Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 );
/// \ru Приравнять координаты вектора координатам суммы точек v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Equate vector coordinates with coordinates of sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly.
void Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2,
const MbCartPoint3D & v3, double t3 );
/// \ru Приравнять координаты вектора координатам суммы точек v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Equate vector coordinates with coordinates of sum of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly.
void Set( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2,
const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 );
/// \ru Прибавить к вектору вектор v1, умноженный на t1. \en Add vector v1 multiplied by t1 to a vector.
void Add( const MbVector3D & v1, double t1 );
/// \ru Прибавить к вектору сумму векторов v1 и v2, умноженных на t1 и t2 соответственно. \en Add sum of vectors v1 and v2 multiplied with t1 and t2 correspondingly to a vector.
void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 );
/// \ru Прибавить к вектору сумму векторов v1, v2 и v3, умноженных на t1, t2 и t3 соответственно. \en Add sum of vectors v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly to a vector.
void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3 );
/// \ru Прибавить к вектору сумму векторов v1, v2, v3 и v4, умноженных на t1, t2, t3 и t4 соответственно. \en Add sum of vectors v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly to a vector.
void Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 );
/// \ru Прибавить к координатам вектора координаты точки v1, умноженных на t1. \en Add coordinates of point v1 multiplied by t1 to coordinates of vector.
void Add( const MbCartPoint3D & v1, double t1 );
/// \ru Прибавить к координатам вектора координаты точек v1 и v2, умноженных на числа t1 и t2, соответственно. \en Add sum of coordinates of points v1 and v2 multiplied with t1 and t2 correspondingly to coordinates of vector.
void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2 );
/// \ru Прибавить к координатам вектора координаты точек v1, v2 и v3, умноженных на числа t1, t2 и t3, соответственно. \en Add sum of coordinates of points v1, v2 and v3 multiplied with t1, t2 and t3 correspondingly to coordinates of vector.
void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2,
const MbCartPoint3D & v3, double t3 );
/// \ru Прибавить к координатам вектора координаты точек v1, v2, v3 и v4, умноженных на числа t1, t2, t3 и t4, соответственно. \en Add sum of coordinates of points v1, v2, v3 and v4 multiplied with t1, t2, t3 and t4 correspondingly to coordinates of vector.
void Add( const MbCartPoint3D & v1, double t1, const MbCartPoint3D & v2, double t2,
const MbCartPoint3D & v3, double t3, const MbCartPoint3D & v4, double t4 );
/// \ru Задать векторное произведение двух заданных векторов. \en Set vector product of two given vectors.
void SetVecM( const MbVector3D & vF, const MbVector3D & vS );
/// \ru Задать векторное произведение двух заданных векторов, умноженное на mulKoef. \en Set vector product of two given vectors multiplied by mulKoef.
void SetVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef );
/// \ru Добавить к вектору векторное произведение двух заданных векторов. \en Add vector product of two given vectors to vector.
void AddVecM( const MbVector3D & vF, const MbVector3D & vS );
/// \ru Добавить к вектору векторное произведение двух заданных векторов, умноженное на mulKoef. \en Add vector product of two given vectors multiplied by mulKoef to vector.
void AddVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef );
/// \ru Найти максимальную по модулю компоненту вектора. \en Find the largest absolute value of a vector.
double MaxFactor() const;
/// \ru Масштабировать компоненты. \en Scale components.
void Scale( double sx, double sy, double sz ) { x *= sx, y *= sy, z *= sz; }
/// \ru Масштабировать компоненты. \en Scale components.
void Scale( double s ) { x *= s, y *= s, z *= s; }
/// \ru Округлить компоненты вектора. \en Round components of vector.
bool SetRoundedValue( bool total, double eps );
/// \ru Выдать свойства объекта. \en Get properties of the object.
void GetProperties( MbProperties & );
/// \ru Записать свойства объекта. \en Set properties of the object.
void SetProperties( const MbProperties & );
/// \ru Являются ли объекты равными? \en Are the objects equal?
bool IsSame( const MbVector3D & other, double accuracy ) const;
KNOWN_OBJECTS_RW_REF_OPERATORS_EX_BASE( MbVector3D, MATH_FUNC_EX ) // \ru Для работы со ссылками и объектами класса \en For working with references and objects of the class.
DECLARE_NEW_DELETE_CLASS( MbVector3D )
DECLARE_NEW_DELETE_CLASS_EX( MbVector3D )
}; // MbVector3D
//------------------------------------------------------------------------------
// \ru Сложить два вектора; результат - вектор. \en Sum up two vectors; result is vector.
// ---
inline MbVector3D MbVector3D::operator + ( const MbVector3D & vector ) const
{
return MbVector3D( x + vector.x, y + vector.y, z + vector.z );
}
//------------------------------------------------------------------------------
// \ru Вычесть из вектора вектор; результат - вектор. \en Subtract vector from vector; result is vector.
// ---
inline MbVector3D MbVector3D::operator - ( const MbVector3D & v2 ) const
{
return MbVector3D ( x - v2.x, y - v2.y, z - v2.z );
}
//------------------------------------------------------------------------------
// \ru Унарный минус. \en Unary minus.
// ---
inline MbVector3D MbVector3D::operator - () const
{
return MbVector3D ( - x, - y, - z );
}
//------------------------------------------------------------------------------
// \ru Сложить два вектора. \en Sum up two vectors.
// ---
inline MbVector3D & MbVector3D::operator += ( const MbVector3D & vector )
{
x += vector.x;
y += vector.y;
z += vector.z;
return *this;
}
//------------------------------------------------------------------------------
// \ru Вычесть из вектора вектор. \en Subtract vector from vector.
// ---
inline MbVector3D & MbVector3D::operator -= ( const MbVector3D & vector )
{
x -= vector.x;
y -= vector.y;
z -= vector.z;
return *this;
}
//------------------------------------------------------------------------------
// \ru Умножить вектор на число. \en Multiply vector by number.
// ---
inline MbVector3D & MbVector3D::operator *= ( double factor )
{
x *= factor;
y *= factor;
z *= factor;
return *this;
}
//------------------------------------------------------------------------------
// \ru Разделить вектор на число. \en Divide vector by number.
// ---
inline MbVector3D & MbVector3D::operator /= ( double factor )
{
// \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division 5.7 times slower than multiplication
C3D_ASSERT( factor != 0.0 ); //-V550
double invFactor = ( 1.0 / factor );
x *= invFactor;
y *= invFactor;
z *= invFactor;
return *this;
}
//------------------------------------------------------------------------------
// \ru Вычислить скалярное произведение двух векторов. \en Calculate dot product of two vectors.
// ---
inline double MbVector3D::operator * ( const MbVector3D & vector ) const
{
return ( x * vector.x + y * vector.y + z * vector.z );
}
//------------------------------------------------------------------------------
// \ru Вычислить векторное произведение двух векторов. \en Calculate vector product of two vectors.
// ---
inline MbVector3D MbVector3D::operator | ( const MbVector3D & vect2 ) const
{
return MbVector3D( y * vect2.z - z * vect2.y,
z * vect2.x - x * vect2.z,
x * vect2.y - y * vect2.x );
}
//------------------------------------------------------------------------------
// \ru Проверить на равенство. \en Check for equality.
// ---
inline bool MbVector3D::operator == ( const MbVector3D & with ) const
{
return ( ::fabs( x - with.x ) < Math::region &&
::fabs( y - with.y ) < Math::region &&
::fabs( z - with.z ) < Math::region );
}
//------------------------------------------------------------------------------
// \ru Присвоить вектору значения другого вектора. \en Assign the value of another vector to the vector.
// ---
inline MbVector3D & MbVector3D::operator = ( const MbVector3D & v )
{
x = v.x; // SKIP_SA
y = v.y;
z = v.z;
return *this;
}
//------------------------------------------------------------------------------
// \ru Проверить на неравенство. \en Check for inequality.
// ---
inline bool MbVector3D::operator != ( const MbVector3D & with ) const
{
return !( *this == with );
}
//------------------------------------------------------------------------------
// \ru Проверить на вырожденность. \en Check for degeneracy.
// ---
inline bool MbVector3D::IsDegenerate( double comEps ) const
{
return ( ::fabs( x ) < comEps &&
::fabs( y ) < comEps &&
::fabs( z ) < comEps );
}
//------------------------------------------------------------------------------
// \ru Проверить, является ли вектор нормированным. \en Check if vector is normalized.
// ---
inline bool MbVector3D::IsNormalized( double eps ) const
{
return ( ::fabs( Length() - 1.0) < eps );
}
//------------------------------------------------------------------------------
// \ru Проверить, является ли вектор нулевым. \en Check if vector is zero.
// ---
inline bool MbVector3D::IsZero( double eps ) const
{
return ( ::fabs(x) < eps &&
::fabs(y) < eps &&
::fabs(z) < eps );
}
//------------------------------------------------------------------------------
// \ru Сменить направление вектора на противоположное. \en Change vector direction to opposite.
// ---
inline MbVector3D & MbVector3D::Invert()
{
x = - x;
y = - y;
z = - z;
return *this;
}
//------------------------------------------------------------------------------
// \ru Найти длину вектора. \en Find vector length.
// ---
inline double MbVector3D::Length() const
{
return ::sqrt( x * x + y * y + z * z );
}
//------------------------------------------------------------------------------
// \ru Найти квадрат длины вектора. \en Find vector length square.
// ---
inline double MbVector3D::Length2() const
{
return ( x * x + y * y + z * z );
}
//------------------------------------------------------------------------------
// \ru Нормализовать вектор. \en Normalize a vector.
// ---
inline bool MbVector3D::Normalize()
{
double len = Length();
// C3D_ASSERT( len > LENGTH_EPSILON || len < NULL_EPSILON );
bool res = ( len >= NULL_EPSILON );
if ( res && ::fabs(len - 1.0) > NULL_EPSILON ) {
double one_len = 1.0 / len;
x *= one_len;
y *= one_len;
z *= one_len;
C3D_ASSERT( ::fabs(Length() - 1.0) < LENGTH_EPSILON );
}
return res;
}
//------------------------------------------------------------------------------
// \ru Вернуть нормализованную копию вектора. \en Return normalized copy of vector.
// ---
inline MbVector3D MbVector3D::GetNormalized() const
{
double len = Length();
if ( len >= NULL_EPSILON && ::fabs(len - 1.0) > NULL_EPSILON )
len = 1.0 / len;
MbVector3D res( x * len, y * len, z * len );
return res;
}
//------------------------------------------------------------------------------
// \ru Выдать компоненту вектора в направлении vector. \en Give part of vector coincident to direction 'vector'.
// ---
inline MbVector3D MbVector3D::TangentComponent( const MbVector3D & vector ) const
{
MbVector3D res( vector );
res.Normalize();
res *= res * (*this);
return res;
}
//------------------------------------------------------------------------------
// \ru Выдать компоненту вектора в направлении ортогональном vector. \en Give part of vector in direction orthogonal to 'vector'.
// ---
inline MbVector3D MbVector3D::NormalComponent( const MbVector3D & vector ) const
{
MbVector3D res( vector );
res.Normalize();
res *= res * (*this);
res.Init( x-res.x, y-res.y, z-res.z );
return res;
}
//------------------------------------------------------------------------------
// \ru Присвоить вектору значения. \en Assign values to vector.
// ---
inline void MbVector3D::Set( const MbVector3D & v1, double t1 )
{
x = v1.x * t1;
y = v1.y * t1;
z = v1.z * t1;
}
//------------------------------------------------------------------------------
// \ru Присвоить вектору значения. \en Assign values to vector.
// ---
inline void MbVector3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 )
{
x = v1.x * t1 + v2.x * t2;
y = v1.y * t1 + v2.y * t2;
z = v1.z * t1 + v2.z * t2;
}
//------------------------------------------------------------------------------
// \ru Присвоить вектору значения. \en Assign values to vector.
// ---
inline void MbVector3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3 )
{
x = v1.x * t1 + v2.x * t2 + v3.x * t3;
y = v1.y * t1 + v2.y * t2 + v3.y * t3;
z = v1.z * t1 + v2.z * t2 + v3.z * t3;
}
//------------------------------------------------------------------------------
// \ru Присвоить вектору значения. \en Assign values to vector.
// ---
inline void MbVector3D::Set( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 )
{
x = v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4;
y = v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4;
z = v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4;
}
//------------------------------------------------------------------------------
// \ru Добавить к вектору значения. \en Add values to vector.
// ---
inline void MbVector3D::Add( const MbVector3D & v1, double t1 )
{
x += v1.x * t1;
y += v1.y * t1;
z += v1.z * t1;
}
//------------------------------------------------------------------------------
// \ru Добавить к вектору значения. \en Add values to vector.
// ---
inline void MbVector3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2 )
{
x += v1.x * t1 + v2.x * t2;
y += v1.y * t1 + v2.y * t2;
z += v1.z * t1 + v2.z * t2;
}
//------------------------------------------------------------------------------
// \ru Добавить к вектору значения. \en Add values to vector.
// ---
inline void MbVector3D::Add( const MbVector3D & v1, double t1,
const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3 )
{
x += v1.x * t1 + v2.x * t2 + v3.x * t3;
y += v1.y * t1 + v2.y * t2 + v3.y * t3;
z += v1.z * t1 + v2.z * t2 + v3.z * t3;
}
//------------------------------------------------------------------------------
// \ru Добавить к вектору значения. \en Add values to vector.
// ---
inline void MbVector3D::Add( const MbVector3D & v1, double t1, const MbVector3D & v2, double t2,
const MbVector3D & v3, double t3, const MbVector3D & v4, double t4 )
{
x += v1.x * t1 + v2.x * t2 + v3.x * t3 + v4.x * t4;
y += v1.y * t1 + v2.y * t2 + v3.y * t3 + v4.y * t4;
z += v1.z * t1 + v2.z * t2 + v3.z * t3 + v4.z * t4;
}
//------------------------------------------------------------------------------
/// \ru Умножить вектор на число. \en Multiply vector by number.
// ---
inline MbVector3D operator * ( const MbVector3D & vector, double factor )
{
return MbVector3D( vector.x * factor, vector.y * factor, vector.z * factor );
}
//------------------------------------------------------------------------------
/// \ru Разделить вектор на число. \en Divide vector by number.
// ---
inline MbVector3D operator / ( const MbVector3D & vector, double factor )
{
// \ru Операция деления занимает 40 циклов процессора, а умножения 7, т.е. (/) 5.7 раза медленней (*) \en Division operation takes 40 CPU cycles and multiplication takes only 7, i.e. division 5.7 times slower than multiplication
C3D_ASSERT( factor != 0.0 ); //-V550
double invFactor = ( 1.0 / factor );
return MbVector3D( vector.x * invFactor, vector.y * invFactor, vector.z * invFactor );
}
//------------------------------------------------------------------------------
/// \ru Умножить вектор на число. \en Multiply vector by number.
// ---
inline MbVector3D operator * ( double factor, const MbVector3D & vector )
{
return vector * factor;
}
//------------------------------------------------------------------------------
// \ru Вычислить векторное произведение векторов. \en Calculate vector product of vectors.
// ---
inline void MbVector3D::SetVecM( const MbVector3D & vF, const MbVector3D & vS )
{
Init( vF.y * vS.z - vF.z * vS.y,
vF.z * vS.x - vF.x * vS.z,
vF.x * vS.y - vF.y * vS.x );
}
//------------------------------------------------------------------------------
// \ru Вычислить векторное произведение векторов, умноженное на число. \en Calculate vector product of vectors multiplied by number.
// ---
inline void MbVector3D::SetVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef )
{
Init( ( vF.y * vS.z - vF.z * vS.y ) * mulKoef,
( vF.z * vS.x - vF.x * vS.z ) * mulKoef,
( vF.x * vS.y - vF.y * vS.x ) * mulKoef );
}
//------------------------------------------------------------------------------
// \ru Добавить к вектору векторное произведение векторов. \en Add vector product of vectors to vector.
// ---
inline void MbVector3D::AddVecM( const MbVector3D & vF, const MbVector3D & vS )
{
Init ( x + vF.y * vS.z - vF.z * vS.y,
y + vF.z * vS.x - vF.x * vS.z,
z + vF.x * vS.y - vF.y * vS.x);
}
//------------------------------------------------------------------------------
// \ru Добавить к вектору векторное произведение векторов, умноженное на число. \en Add vector product of vectors multiplied by number to vector.
// ---
inline void MbVector3D::AddVecM( const MbVector3D & vF, const MbVector3D & vS, double mulKoef )
{
Init ( x + (vF.y * vS.z - vF.z * vS.y) * mulKoef,
y + (vF.z * vS.x - vF.x * vS.z) * mulKoef,
z + (vF.x * vS.y - vF.y * vS.x) * mulKoef );
}
//-------------------------------------------------------------------------------
// \ru Найти максимальную по модулю компоненту вектора. \en Find the largest absolute value of a vector.
// ---
inline double MbVector3D::MaxFactor() const
{
double ax = ::fabs( x );
double ay = ::fabs( y );
double az = ::fabs( z );
return ( ((ax > ay) && (ax > az)) ? ax : ((ay > az) ? ay : az) );
}
//------------------------------------------------------------------------------
/** \brief \ru Являются ли объекты равными?
\en Are the objects equal? \~
\details \ru Равными считаются объекты, данные которых равны с заданной точностью.
\en The objects are equal if their data are equal with a given accuracy. \~
\param[in] other - \ru Объект для сравнения.
\en The object to compare. \~
\param[in] accuracy - \ru Точность сравнения.
\en The accuracy to compare. \~
\return \ru Равны ли объекты.
\en Whether the objects are equal.
*/
inline bool MbVector3D::IsSame( const MbVector3D & other, double accuracy ) const
{
return ( (::fabs(x - other.x) < accuracy) &&
(::fabs(y - other.y) < accuracy) &&
(::fabs(z - other.z) < accuracy) );
}
////////////////////////////////////////////////////////////////////////////////
//
// \ru Глобальные функции \en Global functions
//
////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------
/// \ru Вычислить векторное произведение векторов. \en Calculate vector product of vectors.
// ---
inline
void SetVecM( MbVector3D & vVec, const MbVector3D & vF, const MbVector3D & vS )
{
vVec.Init( vF.y * vS.z - vF.z * vS.y,
vF.z * vS.x - vF.x * vS.z,
vF.x * vS.y - vF.y * vS.x );
}
//------------------------------------------------------------------------------
/// \ru Вычислить векторное произведение векторов, умноженное на число. \en Calculate vector product of vectors multiplied by number.
// ---
inline
void SetVecM( MbVector3D & vVec, const MbVector3D & vF, const MbVector3D & vS, double mulKoef )
{
vVec.Init( ( vF.y * vS.z - vF.z * vS.y ) * mulKoef,
( vF.z * vS.x - vF.x * vS.z ) * mulKoef,
( vF.x * vS.y - vF.y * vS.x ) * mulKoef );
}
namespace c3d // namespace C3D
{
//------------------------------------------------------------------------------
/** \brief \ru Проверить, что вектор ненулевой с заданной точностью.
\en Check equality of vector to zero with given tolerance. \~
\details \ru Проверка ненулевого вектора с заданной точностью.
Вектор считается ненулевым, если его координаты превосходят заданную погрешность.
\en Check equality of vector to zero with given tolerance.
Vector is nonzero if its coordinates are greater than given tolerance. \~
\param[in] vec - \ru Вектор.
\en A vector. \~
\param[in] eps - \ru Погрешность координат.
\en Coordinate tolerance. \~
\return \ru Возвращает true, если вектор ненулевой.
\en Returns true if the vector is nonzero. \~
\ingroup Mathematic_Base_3D
*/
// ---
inline
bool Nonzero( const MbVector3D & vec, double eps ) {
return ::fabs(vec.x) > eps || ::fabs(vec.y) > eps || ::fabs(vec.z) > eps;
}
} // namespace C3D
#endif // __MB_VECTOR3D_H