/** Vector type and functionality * * This file defines the Vector type which defines some * basic operations on a vector * * @file vectors.cpp * @author Valentin Gehrke * @version 0.1 * @date Friday, 11. December 2015 16:09 */ #pragma once #include #include /** Vector type for N dimensions * * This class defines the Vector type * with basic operations for vectors * * TElem must have add, subtract and multiplication defined. * * @tparam NDim dimension of the Vector * @tparam TElem type of the coordinates */ template< unsigned int NDim, typename TElem > class Vector { static_assert( NDim > 0 , "The Vector must atleast have one dimension." ); private: TElem coord[ NDim ]; public: /** Empty constructor * * This constructor just creates a Vector * that doesn't have to be initialized * */ Vector() {} /** Constructor for one value * * This constructor takes one value and * initializes all coordinates with it * * @param initialElement Value for initialization */ Vector(const TElem initialElement) { for( unsigned int i = 0; i < NDim; i++ ) { this->coord[ i ] = initialElement; } } /** constructor for initialization with array * * This constructor initializes the coordinates with the * contents of an array * * @tparam template parameter * @param parameter * @return return value */ Vector( const TElem initialData[ NDim ] ) { for( unsigned int i = 0; i < NDim; i++ ) { this->coord[ i ] = initialData[ i ]; } } /** constructor for brace enclosed initializer list * * this constructor initializes the coordinates with a * brace enclosed initializer list which enables the object * to be initialized like the following code example * * @code * Vector<3,int> v{1,2,3}; * @end-code * * @tparam template parameter * @param parameter * @return return value */ Vector( std::initializer_list initialData ) { assert( initialData.size() == NDim ); std::copy( initialData.begin(), initialData.end(), this->coord ); } /** return the length of the vector * * This method calculates the length of the vector using * the Pythagorean Theorem * * @return length of the vector */ auto length( ) const -> decltype( sqrt( coord[0] ) ) { TElem len = 0; for( unsigned int index = 0; index < NDim; index++ ) { len += this->coord[ index ] * this->coord[ index ]; } return sqrt( len ); } /** vector normalization * * This method normalizes the vector by dividing its * coordinates by the length of the vector * * @return normalized vector */ auto normalize( ) const -> Vector { return (*this) / this->length(); } template< typename TElemOther > auto operator=( Vector const & other ) -> Vector< NDim, TElem >& { for(unsigned int index = 0; index < NDim; index++) { this->coord[ index ] = (TElem) other[ index ]; } return *this; } /** division by scalar * * This method divides the coordinates of the vector * by a scalar elementwise * * @param other divisor * @return vector divided by divisor */ template< typename TFactor > auto operator/( const TFactor other ) const -> Vector { Vector< NDim, decltype( coord[0]/other ) > result; for( unsigned int index = 0; index < NDim; index++ ) { result[ index ] = this->coord[ index ] / other; } return result; } /** + operator for Vector * * This operator adds 2 vectors together * by adding their coordinates elementwise * * @param other Vector which is added to this vector * @return A new Vector containing the result */ template< typename TElemOther > auto operator+ ( const Vector other ) const -> Vector { Vector< NDim, decltype( coord[0] + other[0] ) > result; for( unsigned int i = 0 ; i < NDim ; i++ ) { result[ i ] = this->coord[ i ] + other[ i ]; } return result; } /** += operator for Vector * * This operator adds another vector to the current * vector without creating a new vector * * @param other The vector to be added * @return The current vector after the addition */ template< typename TElemOther > auto operator+= ( const Vector< NDim, TElemOther >& other ) -> Vector& { for( unsigned int i = 0; i < NDim; i++ ) { this->coord[ i ] = ( TElem )( this->coord[ i ] + other[ i ] ); } return *this; } /** - operator for Vector * * This operator subtract another vector from the * current vector resulting in a new Vector object * * @param other The vector to subtract * @return A new vector containing the result */ template< typename TElemOther > auto operator- ( const Vector other ) const -> Vector< NDim, decltype( coord[0] - other[0] ) > { Vector< NDim, decltype( coord[0] - other[0] ) > result; for(unsigned int i = 0; i < NDim; i++) { result[ i ] = this->coord[ i ] - other[ i ]; } return result; } /** negation operator for Vector * * This operator negates the current vector and * returns the result as a new Vector * * @return A new vector containing the result */ auto operator- ( ) const -> Vector< NDim, TElem > { Vector< NDim , TElem > result; for( unsigned int i = 0; i < NDim; i++ ) { result[i] = - this->coord[ i ]; } return result; } /** multiplication operator for multiplication with a scalar * * This operator multiplys every coordinate with a factor * * @param factor factor used for the multiplication * @return A new vector containing the result */ template< typename TFactor > auto operator*( TFactor factor ) const -> Vector< NDim, decltype( factor * coord[0] ) > { Vector< NDim , decltype( factor * coord[0] ) > result; for( unsigned int i = 0; i < NDim; i++ ) { result[i] = this->coord[ i ] * factor; } return result; } /** subscript operator * * This operator is used to read or write single coordinates * of the vector * * @param index The index of the coordinate to be read or written * @return A reference to the coordinate specified by index */ TElem& operator[]( const unsigned int index ) { assert( index >= 0 && index <= NDim ); return this->coord[ index ]; } /** subscript operator for constant use * * This operator is used to read a single coordinate as a constant value * * @param index The index of the coordinate to be read * @return The value of the coordinate specified by index */ const TElem operator[]( const unsigned int index ) const { assert( index >= 0 && index <= NDim ); return this->coord[ index ]; } }; /** reverse definition for multiplikation with a scalar * * This function defines the multiplication operator * for TElem * Vector as the same as * Vector * TElem * * @tparam template parameter * @param parameter * @return return value */ template< unsigned int NDim, typename TElem, typename TFactor > Vector< NDim, TElem > operator*( const TFactor factor, const Vector vector ) { return vector.operator*( factor ); }