//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see .
//
//! \file Vector3.h
//! \ingroup core
//! \author Klaus Iglberger
//! \author Christian Godenschwager
//! \author Martin Bauer
//! \author Florian Schornbaum
//! \brief Header file for the implementation of a 3D vector
//
//======================================================================================================================
#pragma once
#include "FPClassify.h"
#include "MathTrait.h"
#include "SqrtTrait.h"
#include "Utility.h"
#include "core/DataTypes.h"
#include "core/VectorTrait.h"
#include "core/debug/Debug.h"
#include "core/mpi/Datatype.h"
#include "core/mpi/RecvBuffer.h"
#include "core/mpi/SendBuffer.h"
#include "core/debug/CheckFunctions.h"
#include
#include
#include
#include
#include
namespace walberla {
namespace math {
//**********************************************************************************************************************
// Definitions
//**********************************************************************************************************************
//! High-order return value.
/*! Abbreviation for the evaluation of the higher-order data type in a numerical operation. */
#define HIGH typename MathTrait::High
//======================================================================================================================
//
// CLASS DEFINITION
//
//======================================================================================================================
//**********************************************************************************************************************
/*!\brief Efficient, generic implementation of a 3-dimensional vector.
// \ingroup math
//
// The Vector3 class is the representation of a 3D vector with a total of 3 statically allocated
// elements of arbitrary type. The naming convention of the elements is as follows:
\f[\left(\begin{array}{*{3}{c}}
x & y & z \\
\end{array}\right)\f]
// These elements can be accessed directly with the subscript operator. The numbering of the
// vector elements is
\f[\left(\begin{array}{*{3}{c}}
0 & 1 & 2 \\
\end{array}\right)\f]
*/
template< typename Type >
class Vector3
{
static_assert( std::is_arithmetic::value, "Vector3 only accepts arithmetic data types" );
private:
//**Friend declarations*************************************************************************
/*! \cond internal */
template< typename Other > friend class Vector3;
/*! \endcond */
//*******************************************************************************************************************
public:
//**Type definitions****************************************************************************
using Length = typename SqrtTrait::Type; //!< Vector length return type.
/*!< Return type of the Vector3::length
function. */
using value_type = Type;
//*******************************************************************************************************************
//**Constructors*****************************************************************************************************
explicit inline constexpr Vector3() = default;
explicit inline constexpr Vector3( Type init );
template< typename Other > explicit inline constexpr Vector3( Other init );
explicit inline constexpr Vector3( Type x, Type y, Type z );
explicit inline constexpr Vector3( const Type* init );
inline constexpr Vector3( const Vector3& v ) = default;
template< typename Other >
inline constexpr Vector3( const Vector3& v );
//*******************************************************************************************************************
//**Destructor*******************************************************************************************************
// No explicitly declared destructor.
//*******************************************************************************************************************
//**Operators********************************************************************************************************
/*!\name Operators */
//@{
inline Vector3& operator= ( const Vector3& v ) = default;
template< typename Other > inline Vector3& operator= ( const Vector3& v );
template< typename Other > inline bool operator==( Other rhs ) const;
template< typename Other > inline bool operator==( const Vector3& rhs ) const;
template< typename Other > inline bool operator!=( Other rhs ) const;
template< typename Other > inline bool operator!=( const Vector3& rhs ) const;
inline Type& operator[]( uint_t index );
inline const Type& operator[]( uint_t index ) const;
//@}
//*******************************************************************************************************************
//**Arithmetic operators************************************************************************
/*!\name Arithmetic operators
// \brief The return type of the arithmetic operators depends on the involved data types of
// \brief the vectors. HIGH denotes the more significant data type of the arithmetic operation
// \brief (for further detail see the MathTrait class description).
*/
//@{
inline Vector3 operator-() const;
template< typename Other > inline Vector3& operator%=( const Vector3& rhs ); //cross product
template< typename Other > inline Vector3& operator+=( const Vector3& rhs );
template< typename Other > inline Vector3& operator-=( const Vector3& rhs );
template< typename Other > inline Vector3& operator*=( Other rhs );
template< typename Other > inline Vector3& operator/=( Other rhs );
template< typename Other > inline Vector3 operator% ( const Vector3& rhs ) const; //cross product
template< typename Other > inline Vector3 operator+ ( const Vector3& rhs ) const;
template< typename Other > inline Vector3 operator- ( const Vector3& rhs ) const;
template< typename Other > inline Vector3 operator* ( Other rhs ) const;
template< typename Other > inline HIGH operator* ( const Vector3& rhs ) const;
template< typename Other > inline Vector3 operator/ ( Other rhs ) const;
//@}
//*******************************************************************************************************************
//**Utility functions***************************************************************************
/*!\name Utility functions */
//@{
inline uint_t indexOfMax( ) const;
inline uint_t indexOfMin( ) const;
inline Type max( ) const;
inline Type min( ) const;
inline void set( Type x, Type y, Type z );
inline Length length() const;
inline Type sqrLength() const;
inline Vector3 getNormalized() const;
inline Vector3 getNormalizedOrZero() const;
inline void reset();
inline Type* data() {return v_;}
inline Type const * data() const {return v_;}
//@}
//*******************************************************************************************************************
private:
//**Member variables****************************************************************************
/*!\name Member variables */
//@{
/**
* The three statically allocated vector elements.
*
* Access to the vector values is gained via the subscript operator.
* The order of the elements is
* \f[\left(\begin{array}{*{3}{c}}
* 0 & 1 & 2 \\
* \end{array}\right)\f]
**/
Type v_[3] = {Type(), Type(), Type()};
//@}
//*******************************************************************************************************************
};
static_assert( std::is_trivially_copyable>::value, "Vector3 has to be trivially copyable!");
//**********************************************************************************************************************
template
Vector3 & normalize( Vector3 & v );
//======================================================================================================================
//
// CONSTRUCTORS
//
//======================================================================================================================
//**********************************************************************************************************************
/*!\fn Vector3::Vector3( Type init )
// \brief Constructor for a homogenous initialization of all elements.
//
// \param init Initial value for all vector elements.
*/
template< typename Type >
inline constexpr Vector3::Vector3( Type init )
{
v_[0] = v_[1] = v_[2] = init;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::Vector3( Type init )
// \brief Constructor for a homogenous initialization of all elements.
//
// \param init Initial value for all vector elements.
*/
template< typename Type >
template< typename Other >
inline constexpr Vector3::Vector3( Other init )
{
static_assert( std::is_arithmetic::value, "Vector3 only accepts arithmetic data types in Vector3( Other init )");
v_[0] = v_[1] = v_[2] = numeric_cast(init);
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::Vector3( Type x, Type y, Type z )
// \brief Constructor for a direct initialization of all vector elements.
//
// \param x The initial value for the x-component.
// \param y The initial value for the y-component.
// \param z The initial value for the z-component.
*/
template< typename Type >
inline constexpr Vector3::Vector3( Type x, Type y, Type z )
{
v_[0] = x;
v_[1] = y;
v_[2] = z;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::Vector3( const Type* init )
// \brief Constructor for an array initializer.
//
// \param init Pointer to the initialization array.
//
// The array is assumed to have at least three valid elements.
*/
template< typename Type >
inline constexpr Vector3::Vector3( const Type* init )
{
v_[0] = init[0];
v_[1] = init[1];
v_[2] = init[2];
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::Vector3( const Vector3& v )
// \brief Conversion constructor from different Vector3 instances.
//
// \param v Vector to be copied.
*/
template< typename Type >
template< typename Other >
inline constexpr Vector3::Vector3( const Vector3& v )
{
v_[0] = numeric_cast( v.v_[0] );
v_[1] = numeric_cast( v.v_[1] );
v_[2] = numeric_cast( v.v_[2] );
}
//**********************************************************************************************************************
//======================================================================================================================
//
// OPERATORS
//
//======================================================================================================================
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::operator=( const Vector3& v )
// \brief Assignment operator for different Vector3 instances.
//
// \param v Vector to be copied.
// \return Reference to the assigned vector.
*/
template< typename Type >
template< typename Other >
inline Vector3& Vector3::operator=( const Vector3& v )
{
// This implementation is faster than the synthesized default copy assignment operator and
// faster than an implementation with the C library function 'memcpy' in combination with a
// protection against self-assignment. Additionally, this version goes without a protection
// against self-assignment.
v_[0] = v.v_[0];
v_[1] = v.v_[1];
v_[2] = v.v_[2];
return *this;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool Vector3::operator==( Other rhs ) const
// \brief Equality operator for the comparison of a vector and a scalar value.
//
// \param rhs The right-hand-side scalar value for the comparison.
// \return bool
//
// If all values of the vector are equal to the scalar value, the equality test returns true,
// otherwise false.
*/
template< typename Type >
template< typename Other >
inline bool Vector3::operator==( Other rhs ) const
{
// In order to compare the vector and the scalar value, the data values of the lower-order
// data type are converted to the higher-order data type within the equal function.
return equal( v_[0], rhs ) && equal( v_[1], rhs ) && equal( v_[2], rhs );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool Vector3::operator==( const Vector3& rhs ) const
// \brief Equality operator for the comparison of two vectors.
//
// \param rhs The right-hand-side vector for the comparison.
// \return bool
*/
template< typename Type >
template< typename Other >
inline bool Vector3::operator==( const Vector3& rhs ) const
{
// In order to compare the two vectors, the data values of the lower-order data
// type are converted to the higher-order data type within the equal function.
return equal( v_[0], rhs.v_[0] ) && equal( v_[1], rhs.v_[1] ) && equal( v_[2], rhs.v_[2] );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool Vector3::operator!=( Other rhs ) const
// \brief Inequality operator for the comparison of a vector and a scalar value.
//
// \param rhs The right-hand-side scalar value for the comparison.
// \return bool
//
// If one value of the vector is inequal to the scalar value, the inequality test returns true,
// otherwise false.
*/
template< typename Type >
template< typename Other >
inline bool Vector3::operator!=( Other rhs ) const
{
// In order to compare the vector and the scalar value, the data values of the lower-order
// data type are converted to the higher-order data type within the equal function.
return !(*this == rhs);
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool Vector3::operator!=( const Vector3& rhs ) const
// \brief Inequality operator for the comparison of two vectors.
//
// \param rhs The right-hand-side vector for the comparison.
// \return bool
*/
template< typename Type >
template< typename Other >
inline bool Vector3::operator!=( const Vector3& rhs ) const
{
// In order to compare the two vectors, the data values of the lower-order data
// type are converted to the higher-order data type within the equal function.
return !(*this == rhs);
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Type& Vector3::operator[]( uint_t index )
// \brief Subscript operator for the direct access to the vector elements.
//
// \param index Access index. The index has to be in the range \f$[0..2]\f$.
// \return Reference to the accessed value.
*/
template< typename Type >
inline Type& Vector3::operator[]( uint_t index )
{
WALBERLA_ASSERT_LESS( index, 3 , "Invalid vector access index" );
return v_[index];
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn const Type& Vector3::operator[]( uint_t index ) const
// \brief Subscript operator for the direct access to the vector elements.
//
// \param index Access index. The index has to be in the range \f$[0..2]\f$.
// \return Reference-to-const to the accessed value.
*/
template< typename Type >
inline const Type& Vector3::operator[]( uint_t index ) const
{
WALBERLA_ASSERT_LESS( index, 3, "Invalid vector access index" );
return v_[index];
}
//**********************************************************************************************************************
//======================================================================================================================
//
// ARITHMETIC OPERATORS
//
//======================================================================================================================
//**********************************************************************************************************************
/*!\fn Vector3 Vector3::operator-() const
// \brief Unary minus operator for the inversion of a vector (\f$ \vec{a} = -\vec{b} \f$).
//
// \return The inverse of the vector.
*/
template< typename Type >
inline Vector3 Vector3::operator-() const
{
return Vector3( -v_[0], -v_[1], -v_[2] );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3 & Vector3::operator%=( const Vector3& rhs )
// \brief Cross product (outer product) of two vectors (\f$ \vec{a}=\vec{b}\times\vec{c} \f$).
//
// \param rhs The right-hand-side vector for the cross product.
// \return The cross product.
*/
template< typename Type >
template< typename Other >
inline Vector3& Vector3::operator%=( const Vector3& rhs )
{
Type tmp0 = v_[1] * rhs.v_[2] - v_[2] * rhs.v_[1];
Type tmp1 = v_[2] * rhs.v_[0] - v_[0] * rhs.v_[2];
v_[2] = v_[0] * rhs.v_[1] - v_[1] * rhs.v_[0];
v_[1] = tmp1;
v_[0] = tmp0;
return *this;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::operator+=( const Vector3& rhs )
// \brief Addition assignment operator for the addition of two vectors (\f$ \vec{a}+=\vec{b} \f$).
//
// \param rhs The right-hand-side vector to be added to the vector.
// \return Reference to the vector.
*/
template< typename Type >
template< typename Other >
inline Vector3& Vector3::operator+=( const Vector3& rhs )
{
v_[0] += numeric_cast(rhs.v_[0]);
v_[1] += numeric_cast(rhs.v_[1]);
v_[2] += numeric_cast(rhs.v_[2]);
return *this;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::operator-=( const Vector3& rhs )
// \brief Subtraction assignment operator for the subtraction of two vectors
// \brief (\f$ \vec{a}-=\vec{b} \f$).
//
// \param rhs The right-hand-side vector to be subtracted from the vector.
// \return Reference to the vector.
*/
template< typename Type >
template< typename Other >
inline Vector3& Vector3::operator-=( const Vector3& rhs )
{
v_[0] -= numeric_cast(rhs.v_[0]);
v_[1] -= numeric_cast(rhs.v_[1]);
v_[2] -= numeric_cast(rhs.v_[2]);
return *this;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::operator*=( Other rhs )
// \brief Multiplication assignment operator for the multiplication between a vector and
// \brief a scalar value (\f$ \vec{a}*=s \f$).
//
// \param rhs The right-hand-side scalar value for the multiplication.
// \return Reference to the vector.
*/
template< typename Type >
template< typename Other >
inline Vector3& Vector3::operator*=( Other rhs )
{
v_[0] *= numeric_cast(rhs);
v_[1] *= numeric_cast(rhs);
v_[2] *= numeric_cast(rhs);
return *this;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::operator/=( Other rhs )
// \brief Division assignment operator for the division of a vector by a scalar value
// \brief (\f$ \vec{a}/=s \f$).
//
// \param rhs The right-hand-side scalar value for the division.
// \return Reference to the vector.
//
// \b Note: No check for 0 is applied.
*/
template< typename Type >
template< typename Other >
inline Vector3& Vector3::operator/=( Other rhs )
{
// Depending on the two involved data types, an integer division is applied or a
// floating point division is selected.
if( std::numeric_limits::is_integer ) {
v_[0] /= numeric_cast(rhs);
v_[1] /= numeric_cast(rhs);
v_[2] /= numeric_cast(rhs);
return *this;
}
else {
const HIGH tmp( 1/static_cast( rhs ) );
v_[0] = static_cast( static_cast( v_[0] ) * tmp );
v_[1] = static_cast( static_cast( v_[1] ) * tmp );
v_[2] = static_cast( static_cast( v_[2] ) * tmp );
return *this;
}
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3 Vector3::operator%( const Vector3& rhs ) const
// \brief Cross product (outer product) of two vectors (\f$ \vec{a}=\vec{b}\times\vec{c} \f$).
//
// \param rhs The right-hand-side vector for the cross product.
// \return The cross product.
*/
template< typename Type >
template< typename Other >
inline Vector3 Vector3::operator%( const Vector3& rhs ) const
{
return Vector3( v_[1] * rhs.v_[2] - v_[2] * rhs.v_[1],
v_[2] * rhs.v_[0] - v_[0] * rhs.v_[2],
v_[0] * rhs.v_[1] - v_[1] * rhs.v_[0] );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\brief Cross product (outer product) of two vectors (\f$ \vec{a}=\vec{b}\times\vec{c} \f$).
//
// \param lhs The left-hand-side vector for the cross product.
// \param rhs The right-hand-side vector for the cross product.
// \return The cross product.
*/
template< typename Type >
inline Vector3 cross( const Vector3& lhs, const Vector3& rhs )
{
return lhs % rhs;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3 Vector3::operator+( const Vector3& rhs ) const
// \brief Addition operator for the addition of two vectors (\f$ \vec{a}=\vec{b}+\vec{c} \f$).
//
// \param rhs The right-hand-side vector to be added to the vector.
// \return The sum of the two vectors.
//
// The operator returns a vector of the higher-order data type of the two involved vector
// data types (in fact the two template arguments \a Type and \a Other ).
*/
template< typename Type >
template< typename Other >
inline Vector3 Vector3::operator+( const Vector3& rhs ) const
{
return Vector3( v_[0]+numeric_cast(rhs.v_[0]), v_[1]+numeric_cast(rhs.v_[1]), v_[2]+numeric_cast(rhs.v_[2]) );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3 Vector3::operator-( const Vector3& rhs ) const
// \brief Subtraction operator for the subtraction of two vectors (\f$ \vec{a}=\vec{b}-\vec{c} \f$).
//
// \param rhs The right-hand-side vector to be subtracted from the vector.
// \return The difference of the two vectors.
//
// The operator returns a vector of the higher-order data type of the two involved vector
// data types (in fact the two template arguments \a Type and \a Other ).
*/
template< typename Type >
template< typename Other >
inline Vector3 Vector3::operator-( const Vector3& rhs ) const
{
return Vector3( v_[0]-numeric_cast(rhs.v_[0]), v_[1]-numeric_cast(rhs.v_[1]), v_[2]-numeric_cast(rhs.v_[2]) );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3 Vector3::operator*( Other rhs ) const
// \brief Multiplication operator for the multiplication of a vector and a scalar value
// \brief (\f$ \vec{a}=\vec{b}*s \f$).
//
// \param rhs The right-hand-side scalar value for the multiplication.
// \return The scaled result vector.
//
// The operator returns a vector of the higher-order data type of the two involved data types
// (in fact the two template arguments \a Type and \a Other ).
*/
template< typename Type >
template< typename Other >
inline Vector3 Vector3::operator*( Other rhs ) const
{
return Vector3( v_[0]*numeric_cast(rhs), v_[1]*numeric_cast(rhs), v_[2]*numeric_cast(rhs) );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn HIGH Vector3::operator*( const Vector3& rhs ) const
// \brief Multiplication operator for the scalar product (inner product) of two vectors
// \brief (\f$ s=\vec{a}*\vec{b} \f$).
//
// \param rhs The right-hand-side vector for the inner product.
// \return The scalar product.
//
// The operator returns a scalar value of the higher-order data type of the two involved data
// types (in fact the two template arguments \a Type and \a Other ).
*/
template< typename Type >
template< typename Other >
inline HIGH Vector3::operator*( const Vector3& rhs ) const
{
return ( v_[0]*numeric_cast(rhs.v_[0]) + v_[1]*numeric_cast(rhs.v_[1]) + v_[2]*numeric_cast(rhs.v_[2]) );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3 Vector3::operator/( Other rhs ) const
// \brief Division operator for the division of a vector by a scalar value
// \brief (\f$ \vec{a}=\vec{b}/s \f$).
//
// \param rhs The right-hand-side scalar value for the division.
// \return The scaled result vector.
//
// The operator returns a vector of the higher-order data type of the two involved data types
// (in fact the two template arguments \a Type and \a Other ).\n
// \b Note: No check for 0 is applied.
*/
template< typename Type >
template< typename Other >
inline Vector3 Vector3::operator/( Other rhs ) const
{
// Depending on the two involved data types, an integer division is applied or a
// floating point division is selected.
if( std::numeric_limits::is_integer ) {
return Vector3( v_[0]/rhs, v_[1]/rhs, v_[2]/rhs );
}
else {
const HIGH tmp( 1/static_cast( rhs ) );
return Vector3( v_[0]*tmp, v_[1]*tmp, v_[2]*tmp );
}
}
//**********************************************************************************************************************
template< typename Type, typename Other >
inline Vector3 operator/( Other lhs, const Vector3& rhs )
{
return Vector3( lhs/rhs[0], lhs/rhs[1], lhs/rhs[2] );
}
//**********************************************************************************************************************
//======================================================================================================================
//
// UTILITY FUNCTIONS
//
//======================================================================================================================
//**********************************************************************************************************************
/*!\fn Vector3::indexOfMax( )
// \brief Returns index of absolute maximum value
*/
template< typename Type >
inline uint_t Vector3::indexOfMax( ) const {
if(math::abs(v_[1]) > math::abs(v_[2]))
return (math::abs(v_[0]) > math::abs(v_[1])) ? 0u : 1u;
else
return (math::abs(v_[0]) > math::abs(v_[2])) ? 0u : 2u;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::indexOfMin( )
// \brief Returns index of absolute minimum value
*/
template< typename Type >
inline uint_t Vector3::indexOfMin( ) const {
if(math::abs(v_[2]) < math::abs(v_[1]))
return (math::abs(v_[2]) < math::abs(v_[0])) ? 2u : 0u;
else
return (math::abs(v_[1]) < math::abs(v_[0])) ? 1u : 0u;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::max( )
// \brief Returns maximum value
*/
template< typename Type >
inline Type Vector3::max( ) const {
return std::max(v_[0], std::max(v_[1], v_[2]));
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::min( )
// \brief Returns minimum value
*/
template< typename Type >
inline Type Vector3::min( ) const {
return std::min(v_[0], std::min(v_[1], v_[2]));
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3::set( Type x, Type y, Type z )
// \brief Set function for a direct assignment of all vector elements.
//
// \param x The initial value for the x-component.
// \param y The initial value for the y-component.
// \param z The initial value for the z-component.
*/
template< typename Type >
inline void Vector3::set( Type x, Type y, Type z )
{
v_[0] = x;
v_[1] = y;
v_[2] = z;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Length Vector3::length() const
// \brief Calculation of the vector length \f$|\vec{a}|\f$.
//
// \return The length of the vector.
//
// The return type of the length function depends on the actual type of the vector instance:
//
//
//
//
\b Type
//
\b Length
//
//
//
float
//
float
//
//
//
integral data types and double
//
double
//
//
//
long double
//
long double
//
//
*/
template< typename Type >
inline typename SqrtTrait::Type Vector3::length() const
{
return std::sqrt( static_cast::Type>( v_[0]*v_[0] + v_[1]*v_[1] + v_[2]*v_[2] ) );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Type Vector3::sqrLength() const
// \brief Calculation of the vector square length \f$|\vec{a}|^2\f$.
//
// \return The square length of the vector.
*/
template< typename Type >
inline Type Vector3::sqrLength() const
{
return ( v_[0]*v_[0] + v_[1]*v_[1] + v_[2]*v_[2] );
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::getNormalized() const
// \brief Calculation of the normalized vector (\f$|\vec{a}|=1\f$).
//
// \pre \f$|\vec{a}|\neq0\f$
//
// \return The normalized vector.
//
// The function returns the normalized vector.
*/
template< typename Type >
Vector3::Length> Vector3::getNormalized() const
{
const Length len( length() );
WALBERLA_ASSERT_FLOAT_UNEQUAL( len, Length(0) );
const Length ilen( Length(1) / len );
Vector3 result ( static_cast( v_[0] ) * ilen,
static_cast( v_[1] ) * ilen,
static_cast( v_[2] ) * ilen );
WALBERLA_ASSERT_FLOAT_EQUAL( result.sqrLength(), 1.0 );
return result;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn Vector3& Vector3::getNormalized() const
// \brief Calculation of the normalized vector (\f$|\vec{a}|=1\f$) without precondition.
//
// \return The normalized vector or the original vector if vector is too small.
*/
template< typename Type >
Vector3::Length> Vector3::getNormalizedOrZero() const
{
const Length len( length() );
if (floatIsEqual( len, Length(0) )) return *this;
const Length ilen( Length(1) / len );
Vector3 result ( static_cast( v_[0] ) * ilen,
static_cast( v_[1] ) * ilen,
static_cast( v_[2] ) * ilen );
WALBERLA_ASSERT_FLOAT_EQUAL( result.sqrLength(), 1.0, "initial vector: " << result );
return result;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn void Vector3::reset()
// \brief Sets all components of the vector to 0.
*/
template< typename Type >
void Vector3::reset()
{
v_[0] = 0;
v_[1] = 0;
v_[2] = 0;
}
//**********************************************************************************************************************
//======================================================================================================================
//
// GLOBAL OPERATORS
//
//======================================================================================================================
//**********************************************************************************************************************
/*!\name Vector3 operators */
//@{
// The following overloads of the comparison operators are necessary to disambiguate
// comparisons between a scalar value and a vector.
template< typename Type > inline bool operator==( unsigned char scalar, const Vector3& vec );
template< typename Type > inline bool operator==( char scalar, const Vector3& vec );
template< typename Type > inline bool operator==( signed char scalar, const Vector3& vec );
template< typename Type > inline bool operator==( wchar_t scalar, const Vector3& vec );
template< typename Type > inline bool operator==( unsigned short scalar, const Vector3& vec );
template< typename Type > inline bool operator==( short scalar, const Vector3& vec );
template< typename Type > inline bool operator==( unsigned int scalar, const Vector3& vec );
template< typename Type > inline bool operator==( int scalar, const Vector3& vec );
template< typename Type > inline bool operator==( unsigned long scalar, const Vector3& vec );
template< typename Type > inline bool operator==( long scalar, const Vector3& vec );
template< typename Type > inline bool operator==( float scalar, const Vector3& vec );
template< typename Type > inline bool operator==( double scalar, const Vector3& vec );
template< typename Type > inline bool operator==( long double scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( unsigned char scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( char scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( signed char scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( wchar_t scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( unsigned short scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( short scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( unsigned int scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( int scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( unsigned long scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( long scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( float scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( double scalar, const Vector3& vec );
template< typename Type > inline bool operator!=( long double scalar, const Vector3& vec );
template< typename Type >
std::ostream& operator<<( std::ostream& os, const Vector3& v );
template< typename Type >
std::istream& operator>>( std::istream& is, Vector3& v );
template< typename Type >
inline bool isnan( const Vector3& v );
template< typename Type >
inline bool isinf( const Vector3& v );
template< typename Type >
inline bool finite( const Vector3& v );
template< typename Type >
inline const Vector3 abs( const Vector3& v );
template< typename Type >
inline const Vector3 fabs( const Vector3& v );
//@}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool operator==( unsigned char scalar, const Vector3& vec )
// \brief Equality operator for the comparison of an unsigned char scalar and a vector.
//
// \param scalar The left-hand-side scalar value for the comparison.
// \param vec The right-hand-side vector for the comparison.
// \return bool
//
// If all values of the vector are equal to the scalar value, the equality test returns true,
// otherwise false.
*/
template< typename Type >
inline bool operator==( unsigned char scalar, const Vector3& vec )
{
return vec == scalar;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool operator==( char scalar, const Vector3& vec )
// \brief Equality operator for the comparison of a char scalar and a vector.
//
// \param scalar The left-hand-side scalar value for the comparison.
// \param vec The right-hand-side vector for the comparison.
// \return bool
//
// If all values of the vector are equal to the scalar value, the equality test returns true,
// otherwise false.
*/
template< typename Type >
inline bool operator==( char scalar, const Vector3& vec )
{
return vec == scalar;
}
//**********************************************************************************************************************
//**********************************************************************************************************************
/*!\fn bool operator==( signed char scalar, const Vector3& vec )
// \brief Equality operator for the comparison of a signed char scalar and a vector.
//
// \param scalar The left-hand-side scalar value for the comparison.
// \param vec The right-hand-side vector for the comparison.
// \return bool
//
// If all values of the vector are equal to the scalar value, the equality test returns true,
// otherwise false.
*/
template< typename Type >
inline bool operator==( signed char scalar, const Vector3