2019-11-01 12:02:09 +01:00
|
|
|
/*******************************************************************\
|
|
|
|
vec3.hh - This file is part of MUSIC2 -
|
|
|
|
a code to generate initial conditions for cosmological simulations
|
|
|
|
|
|
|
|
CHANGELOG (only majors, for details see repo):
|
|
|
|
06/2019 - Oliver Hahn - first implementation
|
|
|
|
\*******************************************************************/
|
2019-05-07 01:05:16 +02:00
|
|
|
#pragma once
|
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implements a simple class of 3-vectors of arbitrary scalar type
|
2019-05-07 01:05:16 +02:00
|
|
|
template< typename T >
|
|
|
|
class vec3{
|
|
|
|
private:
|
2019-11-01 04:45:34 +01:00
|
|
|
//! holds the data
|
2019-05-07 01:05:16 +02:00
|
|
|
std::array<T,3> data_;
|
2019-11-01 04:45:34 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
//! expose access to elements via references
|
2019-05-10 04:48:35 +02:00
|
|
|
T &x,&y,&z;
|
2019-11-01 04:45:34 +01:00
|
|
|
|
|
|
|
//! empty constructor
|
2019-05-10 04:48:35 +02:00
|
|
|
vec3()
|
|
|
|
: x(data_[0]),y(data_[1]),z(data_[2]){}
|
|
|
|
|
2019-11-01 04:45:34 +01:00
|
|
|
//! copy constructor
|
2019-05-10 04:48:35 +02:00
|
|
|
vec3( const vec3<T> &v)
|
|
|
|
: data_(v.data_), x(data_[0]),y(data_[1]),z(data_[2]){}
|
2019-12-01 14:34:28 +01:00
|
|
|
|
|
|
|
//! copy constructor for non-const reference, needed to avoid variadic template being called for non-const reference
|
|
|
|
vec3( vec3<T>& v)
|
|
|
|
: data_(v.data_), x(data_[0]),y(data_[1]),z(data_[2]){}
|
2019-12-01 18:52:53 +01:00
|
|
|
|
2019-11-01 04:45:34 +01:00
|
|
|
//! move constructor
|
2019-05-10 04:48:35 +02:00
|
|
|
vec3( vec3<T> &&v)
|
2019-11-01 04:45:34 +01:00
|
|
|
: data_(std::move(v.data_)), x(data_[0]), y(data_[1]), z(data_[2]){}
|
2019-05-10 04:48:35 +02:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! construct vec3 from initializer list
|
2019-11-01 04:45:34 +01:00
|
|
|
template<typename ...E>
|
|
|
|
vec3(E&&...e)
|
2019-12-01 14:34:28 +01:00
|
|
|
: data_{{std::forward<E>(e)...}}, x{data_[0]}, y{data_[1]}, z{data_[2]}
|
|
|
|
{}
|
|
|
|
// vec3( T a, T b, T c )
|
|
|
|
// : data_{{a,b,c}}, x(data_[0]), y(data_[1]), z(data_[2]){}
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-03 15:54:17 +01:00
|
|
|
//! bracket index access to vector components
|
2019-12-01 14:34:28 +01:00
|
|
|
T &operator[](size_t i) noexcept{ return data_[i];}
|
2019-05-07 01:05:16 +02:00
|
|
|
|
2019-11-03 15:54:17 +01:00
|
|
|
//! const bracket index access to vector components
|
2019-12-01 14:34:28 +01:00
|
|
|
const T &operator[](size_t i) const noexcept { return data_[i]; }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-05 00:29:33 +01:00
|
|
|
// assignment operator
|
2019-12-01 14:34:28 +01:00
|
|
|
vec3<T>& operator=( const vec3<T>& v ) noexcept { data_=v.data_; return *this; }
|
2019-11-05 00:29:33 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of summation of vec3
|
2019-12-01 14:34:28 +01:00
|
|
|
vec3<T> operator+( const vec3<T>& v ) const noexcept{ return vec3<T>({x+v.x,y+v.y,z+v.z}); }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of difference of vec3
|
2019-12-01 14:34:28 +01:00
|
|
|
vec3<T> operator-( const vec3<T>& v ) const noexcept{ return vec3<T>({x-v.x,y-v.y,z-v.z}); }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-12-01 18:52:53 +01:00
|
|
|
//! implementation of unary negative
|
|
|
|
vec3<T> operator-() const noexcept{ return vec3<T>({-x,-y,-z}); }
|
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of scalar multiplication
|
2019-12-01 14:34:28 +01:00
|
|
|
vec3<T> operator*( T s ) const noexcept{ return vec3<T>({x*s,y*s,z*s}); }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-05 00:29:33 +01:00
|
|
|
//! implementation of scalar division
|
2019-12-01 14:34:28 +01:00
|
|
|
vec3<T> operator/( T s ) const noexcept{ return vec3<T>({x/s,y/s,z/s}); }
|
2019-11-05 00:29:33 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of += operator
|
2019-12-04 14:26:42 +01:00
|
|
|
vec3<T>& operator+=( const vec3<T>& v ) noexcept{ x+=v.x; y+=v.y; z+=v.z; return *this; }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! implementation of -= operator
|
2019-12-04 14:26:42 +01:00
|
|
|
vec3<T>& operator-=( const vec3<T>& v ) noexcept{ x-=v.x; y-=v.y; z-=v.z; return *this; }
|
2019-11-01 04:45:34 +01:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! multiply with scalar
|
2019-12-04 14:26:42 +01:00
|
|
|
vec3<T>& operator*=( T s ) noexcept{ x*=s; y*=s; z*=s; return *this; }
|
2019-05-07 01:05:16 +02:00
|
|
|
|
2019-12-04 14:26:42 +01:00
|
|
|
//! divide by scalar
|
|
|
|
vec3<T>& operator/=( T s ) noexcept{ x/=s; y/=s; z/=s; return *this; }
|
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! compute dot product with another vector
|
2019-12-01 14:34:28 +01:00
|
|
|
T dot(const vec3<T> &a) const noexcept
|
2019-05-07 01:05:16 +02:00
|
|
|
{
|
|
|
|
return data_[0] * a.data_[0] + data_[1] * a.data_[1] + data_[2] * a.data_[2];
|
|
|
|
}
|
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! returns 2-norm squared of vector
|
2019-12-01 14:34:28 +01:00
|
|
|
T norm_squared(void) const noexcept { return this->dot(*this); }
|
2019-05-07 01:05:16 +02:00
|
|
|
|
2019-11-01 13:16:05 +01:00
|
|
|
//! returns 2-norm of vector
|
2019-12-01 14:34:28 +01:00
|
|
|
T norm(void) const noexcept { return std::sqrt( this->norm_squared() ); }
|
|
|
|
|
|
|
|
//! wrap absolute vector to box of size p
|
|
|
|
vec3<T>& wrap_abs( T p = 1.0 ) noexcept{
|
|
|
|
for( auto& x : data_ ) x = std::fmod( 2*p + x, p );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! wrap relative vector to box of size p
|
|
|
|
vec3<T>& wrap_rel( T p = 1.0 ) noexcept{
|
|
|
|
for( auto& x : data_ ) x = (x<-p/2)? x+p : (x>=p/2)? x-p : x;
|
|
|
|
return *this;
|
|
|
|
}
|
2019-12-05 05:43:49 +01:00
|
|
|
|
|
|
|
//! ordering, allows 3d sorting of vec3s
|
|
|
|
bool operator<( const vec3<T>& o ) const noexcept{
|
|
|
|
if( x!=o.x ) return x<o.x?true:false;
|
|
|
|
if( y!=o.y ) return y<o.y?true:false;
|
|
|
|
if( z!=o.z ) return z<o.z?true:false;
|
|
|
|
return false;
|
|
|
|
}
|
2019-05-07 01:05:16 +02:00
|
|
|
};
|
2019-11-01 13:16:05 +01:00
|
|
|
|
|
|
|
//! multiplication with scalar
|
|
|
|
template<typename T>
|
|
|
|
vec3<T> operator*( T s, const vec3<T>& v ){
|
|
|
|
return vec3<T>({v.x*s,v.y*s,v.z*s});
|
|
|
|
}
|