33 #ifndef __VMML__VECTOR__HPP__ 34 #define __VMML__VECTOR__HPP__ 36 #include <vmmlib/enable_if.hpp> 51 template<
size_t M,
typename T >
class vector
56 typedef const T* const_iterator;
57 typedef std::reverse_iterator< iterator > reverse_iterator;
58 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
60 static const size_t DIMENSION = M;
64 explicit vector(
const T& a );
65 vector(
const T& x,
const T& y );
66 vector(
const T& x,
const T& y,
const T& z );
67 vector(
const T& x,
const T& y,
const T& z,
const T& w );
71 template<
typename TT >
72 vector(
const vector< M-1, TT >& vector_, T last_,
73 typename enable_if< M == 4, TT >::type* =
nullptr );
76 explicit vector(
const T* values );
79 template<
typename OSGVEC3 >
80 explicit vector(
const OSGVEC3& from,
81 typename enable_if< M == 3, OSGVEC3 >::type* =
nullptr );
86 template<
typename TT >
87 vector(
const vector< 3, TT >& source_,
88 typename enable_if< M == 4, TT >::type* =
nullptr );
91 template<
typename TT >
92 vector(
const vector< 4, TT >& source_,
93 typename enable_if< M == 3, TT >::type* =
nullptr );
95 template<
typename U > vector(
const vector< M, U >& source_ );
98 inline iterator begin();
99 inline iterator end();
100 inline const_iterator begin()
const;
101 inline const_iterator end()
const;
102 inline reverse_iterator rbegin();
103 inline reverse_iterator rend();
104 inline const_reverse_iterator rbegin()
const;
105 inline const_reverse_iterator rend()
const;
108 inline operator T*();
109 inline operator const T*()
const;
111 inline T& operator()(
size_t index );
112 inline const T& operator()(
size_t index )
const;
114 inline T& at(
size_t index );
115 inline const T& at(
size_t index )
const;
122 inline const T& x()
const;
123 inline const T& y()
const;
124 inline const T& z()
const;
125 inline const T& w()
const;
132 inline const T& r()
const;
133 inline const T& g()
const;
134 inline const T& b()
const;
135 inline const T& a()
const;
137 bool operator==(
const vector& other )
const;
138 bool operator!=(
const vector& other )
const;
139 bool equals(
const vector& other,
140 T tolerance = std::numeric_limits< T >::epsilon( ))
const;
141 bool operator<(
const vector& other )
const;
144 T operator=( T filler );
146 vector& operator=(
const vector& other );
149 template<
typename U >
void operator=(
const vector< M, U >& other );
151 vector operator*(
const vector& other )
const;
152 vector operator/(
const vector& other )
const;
153 vector operator+(
const vector& other )
const;
154 vector operator-(
const vector& other )
const;
156 void operator*=(
const vector& other );
157 void operator/=(
const vector& other );
158 void operator+=(
const vector& other );
159 void operator-=(
const vector& other );
161 vector operator*(
const T other )
const;
162 vector operator/(
const T other )
const;
163 vector operator+(
const T other )
const;
164 vector operator-(
const T other )
const;
166 void operator*=(
const T other );
167 void operator/=(
const T other );
168 void operator+=(
const T other );
169 void operator-=(
const T other );
171 vector operator-()
const;
173 const vector& negate();
177 void set(
const vector< N, T >& v );
180 void set( T x, T y );
181 void set( T x, T y, T z );
182 void set( T x, T y, T z, T w );
184 template<
typename input_iterator_t >
185 void iter_set( input_iterator_t begin_, input_iterator_t end_ );
190 template<
typename TT >
191 vector< M, T >& cross(
const vector< M, TT >& b,
192 typename enable_if< M == 3, TT >::type* =
nullptr );
197 inline T dot(
const vector& other )
const;
202 inline T normalize();
208 void set_random(
int seed = -1 );
210 inline T length()
const;
211 inline T squared_length()
const;
213 inline T distance(
const vector& other )
const;
214 inline T squared_distance(
const vector& other )
const;
219 template<
typename TT >
221 typename enable_if< M == 3, TT >::type* =
nullptr );
224 template<
size_t N,
size_t O > vector< N, T >
225 get_sub_vector(
typename enable_if< M >= N+O >::type* =
nullptr )
const;
228 template<
size_t N,
size_t O >
230 typename enable_if< M >= N+O >::type* =
nullptr );
233 template<
typename TT >
235 const vector< 3, TT >& point,
236 typename enable_if< M == 4, TT >::type* =
nullptr )
const;
239 template<
typename TT >
240 inline T distance_to_sphere(
const vector< 3, TT >& point,
241 typename enable_if< M == 4, TT >::type* =
nullptr )
const;
244 template<
typename TT >
245 inline T distance_to_plane(
const vector< 3, TT >& point,
246 typename enable_if< M == 4, TT >::type* =
nullptr )
const;
248 template<
typename TT >
250 const vector< 3, TT >& point,
251 typename enable_if< M == 4, TT >::type* =
nullptr )
const;
254 size_t find_min_index()
const;
255 size_t find_max_index()
const;
260 const T& find_min()
const;
261 const T& find_max()
const;
263 void clamp(
const T& min = 0.0,
const T& max = 1.0 );
265 inline static size_t size();
267 bool is_unit_vector()
const;
270 void perturb( T perturbation = 0.0001 );
272 void sqrt_elementwise();
280 void reciprocal_safe();
282 template<
typename TT >
283 void cast_from(
const vector< M, TT >& other );
287 friend std::ostream& operator<< ( std::ostream& os,
const vector& vector_ )
290 for(
size_t index = 0; index < M; ++index )
291 os << vector_.at( index ) <<
" ";
297 static vector< M, T > zero();
298 static vector< M, T > forward();
299 static vector< M, T > backward();
300 static vector< M, T > up();
301 static vector< M, T > down();
302 static vector< M, T > left();
303 static vector< M, T > right();
304 static vector< M, T > unitX();
305 static vector< M, T > unitY();
306 static vector< M, T > unitZ();
316 template<
size_t M,
typename T >
319 return a.equals( b );
323 template<
size_t M,
typename T >
326 return vector_ * factor;
329 template<
size_t M,
typename T >
332 return first.dot( second );
335 template<
size_t M,
typename T >
341 template<
size_t M,
typename T >
353 template<
typename T >
357 return vec.rotate( theta, axis );
361 template<
size_t M,
typename T >
368 template<
typename T >
378 plane.w() = -plane.x() * a.x() - plane.y() * a.y() - plane.z() * a.z();
382 template<
size_t M,
typename T >
385 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
391 template<
size_t M,
typename T >
398 template<
size_t M,
typename T >
406 template<
size_t M,
typename T >
415 template<
size_t M,
typename T >
418 memcpy(
array, values, M *
sizeof( T ));
422 template<
size_t M,
typename T >
423 template<
typename OSGVEC3 >
425 typename enable_if< M == 3, OSGVEC3 >::type* )
427 array[ 0 ] = from.x();
428 array[ 1 ] = from.y();
429 array[ 2 ] = from.z();
434 template<
size_t M,
typename T >
template<
typename TT >
437 typename enable_if< M == 4, TT >::type* )
439 array[0] = vector_.array[0];
440 array[1] = vector_.array[1];
441 array[2] = vector_.array[2];
447 template<
size_t M,
typename T >
template<
typename TT >
449 typename enable_if< M == 4, TT >::type* )
451 std::copy( source_.begin(), source_.end(), begin() );
452 at( M - 1 ) =
static_cast< T
>( 1.0 );
456 template<
size_t M,
typename T >
template<
typename TT >
458 typename enable_if< M == 3, TT >::type* )
460 const T w_reci =
static_cast< T
>( 1.0 ) / source_( M );
461 iterator it = begin(), it_end = end();
462 for(
size_t index = 0; it != it_end; ++it, ++index )
463 *it = source_( index ) * w_reci;
466 template<
size_t M,
typename T >
467 template<
typename U >
475 template<
size_t M,
typename T >
477 typename enable_if< M == 3 >::type* =
nullptr )
482 template<
size_t M,
typename T >
484 typename enable_if< M == 4 >::type* =
nullptr )
492 return _createVector< M, T >( 0, 0, 0 );
497 return _createVector< M, T >( 0, 0, -1 );
502 return _createVector< M, T >( 0, 0, 1 );
507 return _createVector< M, T >( 0, 1, 0 );
512 return _createVector< M, T >( 0, -1, 0 );
517 return _createVector< M, T >( -1, 0, 0 );
522 return _createVector< M, T >( 1, 0, 0 );
527 return _createVector< M, T >( 1, 0, 0 );
532 return _createVector< M, T >( 0, 1, 0 );
537 return _createVector< M, T >( 0, 0, 1 );
542 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
546 template<
size_t M,
typename T >
template<
size_t N >
550 if (N < M) minimum = N;
551 memcpy(
array, v.array,
sizeof( T ) * minimum );
554 template<
size_t M,
typename T >
561 template<
size_t M,
typename T >
569 template<
size_t M,
typename T >
578 template<
size_t M,
typename T >
585 template<
size_t M,
typename T >
592 template<
size_t M,
typename T >
597 throw std::runtime_error(
"at() - index out of bounds" );
598 return array[ index ];
601 template<
size_t M,
typename T >
606 throw std::runtime_error(
"at() - index out of bounds" );
607 return array[ index ];
610 template<
size_t M,
typename T >
616 template<
size_t M,
typename T >
622 template<
size_t M,
typename T >
627 for(
size_t index = 0; index < M; ++index )
628 result.at( index ) = at( index ) * other.at( index );
632 template<
size_t M,
typename T >
637 for(
size_t index = 0; index < M; ++index )
638 result.at( index ) = at( index ) / other.at( index );
642 template<
size_t M,
typename T >
647 for(
size_t index = 0; index < M; ++index )
648 result.at( index ) = at( index ) + other.at( index );
652 template<
size_t M,
typename T >
657 for(
size_t index = 0; index < M; ++index )
658 result.at( index ) = at( index ) - other.at( index );
662 template<
size_t M,
typename T >
666 for(
size_t index = 0; index < M; ++index )
667 at( index ) *= other.at( index );
670 template<
size_t M,
typename T >
674 for(
size_t index = 0; index < M; ++index )
675 at( index ) /= other.at( index );
678 template<
size_t M,
typename T >
682 for(
size_t index = 0; index < M; ++index )
683 at( index ) += other.at( index );
686 template<
size_t M,
typename T >
690 for(
size_t index = 0; index < M; ++index )
691 at( index ) -= other.at( index );
694 template<
size_t M,
typename T >
699 for(
size_t index = 0; index < M; ++index )
700 result.at( index ) = at( index ) * other;
704 template<
size_t M,
typename T >
709 for(
size_t index = 0; index < M; ++index )
710 result.at( index ) = at( index ) / other;
714 template<
size_t M,
typename T >
719 for(
size_t index = 0; index < M; ++index )
720 result.at( index ) = at( index ) + other;
724 template<
size_t M,
typename T >
729 for(
size_t index = 0; index < M; ++index )
730 result.at( index ) = at( index ) - other;
734 template<
size_t M,
typename T >
738 for(
size_t index = 0; index < M; ++index )
739 at( index ) *= other;
742 template<
size_t M,
typename T >
746 for(
size_t index = 0; index < M; ++index )
747 at( index ) /= other;
750 template<
size_t M,
typename T >
754 for(
size_t index = 0; index < M; ++index )
755 at( index ) += other;
758 template<
size_t M,
typename T >
762 for(
size_t index = 0; index < M; ++index )
763 at( index ) -= other;
766 template<
size_t M,
typename T >
774 template<
size_t M,
typename T >
778 for(
size_t index = 0; index < M; ++index )
783 template<
size_t M,
typename T >
790 template<
size_t M,
typename T >
797 template<
size_t M,
typename T >
804 template<
size_t M,
typename T >
811 template<
size_t M,
typename T >
818 template<
size_t M,
typename T >
825 template<
size_t M,
typename T >
832 template<
size_t M,
typename T >
839 template<
size_t M,
typename T >
846 template<
size_t M,
typename T >
853 template<
size_t M,
typename T >
860 template<
size_t M,
typename T >
867 template<
size_t M,
typename T >
874 template<
size_t M,
typename T >
881 template<
size_t M,
typename T >
888 template<
size_t M,
typename T >
895 template<
size_t M,
typename T >
template<
typename TT >
897 typename enable_if< M == 3, TT >::type* )
899 const T x_ = y() * rhs.z() - z() * rhs.y();
900 const T y_ = z() * rhs.x() - x() * rhs.z();
901 const T z_ = x() * rhs.y() - y() * rhs.x();
908 template<
size_t M,
typename T >
912 for(
size_t index = 0; index < M; ++index )
913 tmp += at( index ) * other.at( index );
920 const T len = length();
921 if ( len <= std::numeric_limits< T >::epsilon( ))
924 const T tmp = 1.0 / len;
929 template<
size_t M,
typename T >
932 return std::sqrt( squared_length() );
935 template<
size_t M,
typename T >
938 T _squared_length = 0.0;
939 for( const_iterator it = begin(), it_end = end(); it != it_end; ++it )
940 _squared_length += (*it) * (*it);
942 return _squared_length;
945 template<
size_t M,
typename T >
949 return std::sqrt( squared_distance( other ) );
952 template<
size_t M,
typename T >
957 return tmp.squared_length();
963 for(
size_t i = 1; i < M; ++i )
968 template<
size_t M,
typename T >
template<
typename TT >
970 typename enable_if< M==3, TT >::type* )
972 const T costheta = std::cos( theta );
973 const T sintheta = std::sin( theta );
977 (costheta + ( 1 - costheta ) * axis.x() * axis.x() ) * x() +
978 (( 1 - costheta ) * axis.x() * axis.y() - axis.z() * sintheta ) * y() +
979 (( 1 - costheta ) * axis.x() * axis.z() + axis.y() * sintheta ) * z(),
981 (( 1 - costheta ) * axis.x() * axis.y() + axis.z() * sintheta ) * x() +
982 ( costheta + ( 1 - costheta ) * axis.y() * axis.y() ) * y() +
983 (( 1 - costheta ) * axis.y() * axis.z() - axis.x() * sintheta ) * z(),
985 (( 1 - costheta ) * axis.x() * axis.z() - axis.y() * sintheta ) * x() +
986 (( 1 - costheta ) * axis.y() * axis.z() + axis.x() * sintheta ) * y() +
987 ( costheta + ( 1 - costheta ) * axis.z() * axis.z() ) * z( ));
991 template<
size_t M,
typename T >
template<
typename TT >
inline vector< 3, T > 993 typename enable_if< M == 4, TT >::type* )
const 998 projected_point -= center_;
999 projected_point.normalize();
1000 projected_point *= w();
1001 return center_ + projected_point;
1005 template<
size_t M,
typename T >
template<
typename TT >
inline T
1007 typename enable_if< M == 4, TT >::type* )
1011 return ( point - center_ ).length() - w();
1014 template<
size_t M,
typename T >
template<
size_t N,
size_t O >
1021 template<
size_t M,
typename T >
template<
size_t N,
size_t O >
1025 ::memcpy(
array + O, sub.array, N *
sizeof( T ));
1029 template<
size_t M,
typename T >
template<
typename TT >
1031 typename enable_if< M == 4, TT >::type* )
const 1034 return normal.dot( point ) + w();
1038 template<
size_t M,
typename T >
template<
typename TT >
vector< 3, T > 1040 typename enable_if< M == 4, TT >::type* )
const 1043 return point - ( normal * distance_to_plane( point ) );
1046 template<
size_t M,
typename T >
1049 return memcmp(
array, other.array,
sizeof(
array )) == 0;
1052 template<
size_t M,
typename T >
1055 return ! this->operator==( other );
1058 template<
size_t M,
typename T >
1061 for(
size_t index = 0; index < M; ++index )
1062 if( fabs( at( index ) - other( index ) ) >= tolerance )
1068 template<
size_t M,
typename T >
1072 for(
size_t index = 0; index < M; ++index )
1074 if (at( index ) < other.at( index ))
return true;
1075 if (other.at( index ) < at( index ))
return false;
1080 template<
size_t M,
typename T >
1083 for(
size_t index = 0; index < M; ++index )
1084 at( index ) = filler_value;
1085 return filler_value;
1088 template<
size_t M,
typename T >
1091 if(
this != &other )
1092 memcpy(
array, other.array, M *
sizeof( T ) );
1097 template<
size_t M,
typename T >
template<
typename U >
1100 typedef typename vector< M, U >::const_iterator u_c_iter;
1101 u_c_iter it = source_.begin(), it_end = source_.end();
1102 for( iterator my_it = begin(); it != it_end; ++it, ++my_it )
1103 *my_it = static_cast< T >( *it );
1106 template<
size_t M,
typename T >
1107 template<
typename input_iterator_t >
1111 input_iterator_t in_it = begin_;
1112 iterator it = begin(), it_end = end();
1113 for( ; it != it_end && in_it != end_; ++it, ++in_it )
1114 (*it) =
static_cast< T
>( *in_it );
1117 template<
size_t M,
typename T >
1120 for(
size_t i = 0; i < M; ++i )
1122 if(
array[i] < min )
1124 if(
array[i] > max )
1129 template<
size_t M,
typename T >
1136 template<
size_t M,
typename T >
1140 return std::min_element( begin(), end() ) - begin();
1143 template<
size_t M,
typename T >
1147 return std::max_element( begin(), end() ) - begin();
1150 template<
size_t M,
typename T >
1154 return *std::min_element( begin(), end() );
1157 template<
size_t M,
typename T >
1161 return *std::min_element( begin(), end() );
1164 template<
size_t M,
typename T >
1168 return *std::max_element( begin(), end() );
1171 template<
size_t M,
typename T >
1175 return *std::max_element( begin(), end() );
1178 template<
size_t M,
typename T >
1179 inline typename vector< M, T >::iterator
1185 template<
size_t M,
typename T >
1186 inline typename vector< M, T >::iterator
1192 template<
size_t M,
typename T >
1193 inline typename vector< M, T >::const_iterator
1199 template<
size_t M,
typename T >
1200 inline typename vector< M, T >::const_iterator
1206 template<
size_t M,
typename T >
1207 inline typename vector< M, T >::reverse_iterator
1210 return array + M - 1;
1213 template<
size_t M,
typename T >
1214 inline typename vector< M, T >::reverse_iterator
1220 template<
size_t M,
typename T >
1221 inline typename vector< M, T >::const_reverse_iterator
1224 return array + M - 1;
1227 template<
size_t M,
typename T >
1228 inline typename vector< M, T >::const_reverse_iterator
1234 template<
size_t M,
typename T >
1238 const_iterator it = begin(), it_end = end();
1240 for( ; it != it_end; ++it )
1248 else if ( *it != 0.0 )
1256 template<
size_t M,
typename T >
1260 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1262 (*it) += ( rand() & 1u ) ? perturbation : -perturbation;
1267 template<
size_t M,
typename T >
1271 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1273 (*it) = std::sqrt(*it);
1279 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1280 (*it) =
static_cast< T
>( 1 ) / (*it);
1285 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1290 v = std::numeric_limits< T >::max();
1292 v =
static_cast< T
>( 1 ) / v;
1296 template<
size_t M,
typename T >
1297 template<
typename TT >
1302 typedef typename vector_tt_type::const_iterator tt_const_iterator;
1304 iterator it = begin(), it_end = end();
1305 tt_const_iterator other_it = other.begin();
1306 for( ; it != it_end; ++it, ++other_it )
1308 *it =
static_cast< T
>( *other_it );
1312 template<
size_t M,
typename T >
1318 const_iterator it = begin(),
1320 for( ; it != it_end; ++it)
1330 template<
size_t M,
typename T >
1334 double norm_v = 0.0;
1336 const_iterator it = begin(), it_end = end();
1337 for( ; it != it_end; ++it )
1339 norm_v += *it * *it;
1342 return std::sqrt(norm_v);
1345 template<
size_t M,
typename T >
1352 for(
size_t i = 0; i < M; ++i )
1354 const double fillValue = double( rand( )) / double( RAND_MAX );
1355 at( i ) = -1.0 + 2.0 * fillValue;
vector< N, T > get_sub_vector(typename enable_if< M >=N+O >::type *=nullptr) const
void set_sub_vector(const vector< N, T > &sub, typename enable_if< M >=N+O >::type *=nullptr)
Set the sub vector of the given length at the given offset.
heavily inspired by boost::enable_if http://www.boost.org, file: boost/utility/enable_if.hpp, Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine