33 #ifndef __VMML__VECTOR__HPP__ 34 #define __VMML__VECTOR__HPP__ 45 #include <type_traits> 50 template <
size_t M,
typename T>
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;
67 explicit vector(
const T& a);
68 vector(
const T& x,
const T& y);
69 vector(
const T& x,
const T& y,
const T& z);
70 vector(
const T& x,
const T& y,
const T& z,
const T& w);
74 template <
typename TT>
75 vector(
const vector<M - 1, TT>& vector_, T last_,
76 typename std::enable_if<M == 4, TT>::type* =
nullptr);
79 explicit vector(
const T* values);
82 template <
typename OSGVEC3>
83 explicit vector(
const OSGVEC3& from,
84 typename std::enable_if<M == 3, OSGVEC3>::type* =
nullptr);
89 template <
typename TT>
90 vector(
const vector<3, TT>& source_,
91 typename std::enable_if<M == 4, TT>::type* =
nullptr);
94 template <
typename TT>
95 vector(
const vector<4, TT>& source_,
96 typename std::enable_if<M == 3, TT>::type* =
nullptr);
99 vector(
const vector<M, U>& source_);
102 inline iterator begin();
103 inline iterator end();
104 inline const_iterator begin()
const;
105 inline const_iterator end()
const;
106 inline reverse_iterator rbegin();
107 inline reverse_iterator rend();
108 inline const_reverse_iterator rbegin()
const;
109 inline const_reverse_iterator rend()
const;
112 inline operator T*();
113 inline operator const T*()
const;
115 inline T& operator()(
size_t index);
116 inline const T& operator()(
size_t index)
const;
118 inline T& at(
size_t index);
119 inline const T& at(
size_t index)
const;
126 inline const T& x()
const;
127 inline const T& y()
const;
128 inline const T& z()
const;
129 inline const T& w()
const;
136 inline const T& r()
const;
137 inline const T& g()
const;
138 inline const T& b()
const;
139 inline const T& a()
const;
141 bool operator==(
const vector& other)
const;
142 bool operator!=(
const vector& other)
const;
143 bool equals(
const vector& other,
144 T tolerance = std::numeric_limits<T>::epsilon())
const;
145 bool operator<(
const vector& other)
const;
148 T operator=(T filler);
150 vector& operator=(
const vector& other);
153 template <
typename U>
154 void operator=(
const vector<M, U>& other);
156 vector operator*(
const vector& other)
const;
157 vector operator/(
const vector& other)
const;
158 vector operator+(
const vector& other)
const;
159 vector operator-(
const vector& other)
const;
161 void operator*=(
const vector& other);
162 void operator/=(
const vector& other);
163 void operator+=(
const vector& other);
164 void operator-=(
const vector& other);
166 vector operator*(
const T other)
const;
167 vector operator/(
const T other)
const;
168 vector operator+(
const T other)
const;
169 vector operator-(
const T other)
const;
171 void operator*=(
const T other);
172 void operator/=(
const T other);
173 void operator+=(
const T other);
174 void operator-=(
const T other);
176 vector operator-()
const;
178 const vector& negate();
182 void set(
const vector<N, T>& v);
186 void set(T x, T y, T z);
187 void set(T x, T y, T z, T w);
189 template <
typename input_iterator_t>
190 void iter_set(input_iterator_t begin_, input_iterator_t end_);
195 template <
typename TT>
196 vector<M, T>& cross(
const vector<M, TT>& b,
197 typename std::enable_if<M == 3, TT>::type* =
nullptr);
202 inline T dot(
const vector& other)
const;
207 inline T normalize();
213 void set_random(
int seed = -1);
215 inline T length()
const;
216 inline T squared_length()
const;
218 inline T distance(
const vector& other)
const;
219 inline T squared_distance(
const vector& other)
const;
224 template <
typename TT>
225 vector<3, T>& rotate(T theta, vector<M, TT> axis,
226 typename std::enable_if<M == 3, TT>::type* =
nullptr);
229 template <
size_t N,
size_t O>
231 typename std::enable_if<M >= N + O>::type* =
nullptr)
const;
234 template <
size_t N,
size_t O>
236 typename std::enable_if<M >= N + O>::type* =
nullptr);
239 template <
typename TT>
240 inline vector<3, T> project_point_onto_sphere(
241 const vector<3, TT>& point,
242 typename std::enable_if<M == 4, TT>::type* =
nullptr)
const;
245 template <
typename TT>
246 inline T distance_to_sphere(
247 const vector<3, TT>& point,
248 typename std::enable_if<M == 4, TT>::type* =
nullptr)
const;
251 template <
typename TT>
252 inline T distance_to_plane(
253 const vector<3, TT>& point,
254 typename std::enable_if<M == 4, TT>::type* =
nullptr)
const;
256 template <
typename TT>
257 inline vector<3, T> project_point_onto_plane(
258 const vector<3, TT>& point,
259 typename std::enable_if<M == 4, TT>::type* =
nullptr)
const;
262 size_t find_min_index()
const;
263 size_t find_max_index()
const;
268 const T& find_min()
const;
269 const T& find_max()
const;
271 void clamp(
const T& min = 0.0,
const T& max = 1.0);
273 inline static size_t size();
275 bool is_unit_vector()
const;
278 void perturb(T perturbation = 0.0001);
280 void sqrt_elementwise();
288 void reciprocal_safe();
290 template <
typename TT>
291 void cast_from(
const vector<M, TT>& other);
295 friend std::ostream& operator<<(std::ostream& os,
const vector& vector_)
298 for (
size_t index = 0; index < M; ++index)
299 os << vector_.at(index) <<
" ";
305 static vector<M, T> zero();
306 static vector<M, T> forward();
307 static vector<M, T> backward();
308 static vector<M, T> up();
309 static vector<M, T> down();
310 static vector<M, T> left();
311 static vector<M, T> right();
312 static vector<M, T> unitX();
313 static vector<M, T> unitY();
314 static vector<M, T> unitZ();
324 template <
size_t M,
typename T>
331 template <
size_t M,
typename T>
334 return vector_ * factor;
337 template <
size_t M,
typename T>
340 return first.dot(second);
343 template <
size_t M,
typename T>
349 template <
size_t M,
typename T>
361 template <
typename T>
364 return vec.rotate(theta, axis);
367 template <
size_t M,
typename T>
374 template <
typename T>
383 plane.w() = -plane.x() * a.x() - plane.y() * a.y() - plane.z() * a.z();
387 template <
size_t M,
typename T>
390 for (iterator it = begin(), it_end = end(); it != it_end; ++it)
396 template <
size_t M,
typename T>
403 template <
size_t M,
typename T>
411 template <
size_t M,
typename T>
420 template <
size_t M,
typename T>
423 memcpy(
array, values, M *
sizeof(T));
427 template <
size_t M,
typename T>
428 template <
typename OSGVEC3>
430 typename std::enable_if<M == 3, OSGVEC3>::type*)
439 template <
size_t M,
typename T>
440 template <
typename TT>
443 typename std::enable_if<M == 4, TT>::type*)
445 array[0] = vector_.array[0];
446 array[1] = vector_.array[1];
447 array[2] = vector_.array[2];
453 template <
size_t M,
typename T>
454 template <
typename TT>
456 typename std::enable_if<M == 4, TT>::type*)
458 std::copy(source_.begin(), source_.end(), begin());
459 at(M - 1) =
static_cast<T
>(1.0);
463 template <
size_t M,
typename T>
464 template <
typename TT>
466 typename std::enable_if<M == 3, TT>::type*)
468 const T w_reci =
static_cast<T
>(1.0) / source_(M);
469 iterator it = begin(), it_end = end();
470 for (
size_t index = 0; it != it_end; ++it, ++index)
471 *it = source_(index) * w_reci;
474 template <
size_t M,
typename T>
475 template <
typename U>
483 template <
size_t M,
typename T>
484 vector<M, T> _createVector(
const T x,
const T y,
const T z,
485 typename std::enable_if<M == 3>::type* =
nullptr)
490 template <
size_t M,
typename T>
491 vector<M, T> _createVector(
const T x,
const T y,
const T z,
492 typename std::enable_if<M == 4>::type* =
nullptr)
498 template <
size_t M,
typename T>
501 return _createVector<M, T>(0, 0, 0);
504 template <
size_t M,
typename T>
507 return _createVector<M, T>(0, 0, -1);
510 template <
size_t M,
typename T>
513 return _createVector<M, T>(0, 0, 1);
516 template <
size_t M,
typename T>
519 return _createVector<M, T>(0, 1, 0);
522 template <
size_t M,
typename T>
525 return _createVector<M, T>(0, -1, 0);
528 template <
size_t M,
typename T>
531 return _createVector<M, T>(-1, 0, 0);
534 template <
size_t M,
typename T>
537 return _createVector<M, T>(1, 0, 0);
540 template <
size_t M,
typename T>
543 return _createVector<M, T>(1, 0, 0);
546 template <
size_t M,
typename T>
549 return _createVector<M, T>(0, 1, 0);
552 template <
size_t M,
typename T>
555 return _createVector<M, T>(0, 0, 1);
558 template <
size_t M,
typename T>
561 for (iterator it = begin(), it_end = end(); it != it_end; ++it)
565 template <
size_t M,
typename T>
572 memcpy(
array, v.array,
sizeof(T) * minimum);
575 template <
size_t M,
typename T>
582 template <
size_t M,
typename T>
590 template <
size_t M,
typename T>
599 template <
size_t M,
typename T>
605 template <
size_t M,
typename T>
611 template <
size_t M,
typename T>
615 throw std::runtime_error(
"at() - index out of bounds");
619 template <
size_t M,
typename T>
623 throw std::runtime_error(
"at() - index out of bounds");
627 template <
size_t M,
typename T>
633 template <
size_t M,
typename T>
639 template <
size_t M,
typename T>
643 for (
size_t index = 0; index < M; ++index)
644 result.at(index) = at(index) * other.at(index);
648 template <
size_t M,
typename T>
652 for (
size_t index = 0; index < M; ++index)
653 result.at(index) = at(index) / other.at(index);
657 template <
size_t M,
typename T>
661 for (
size_t index = 0; index < M; ++index)
662 result.at(index) = at(index) + other.at(index);
666 template <
size_t M,
typename T>
670 for (
size_t index = 0; index < M; ++index)
671 result.at(index) = at(index) - other.at(index);
675 template <
size_t M,
typename T>
678 for (
size_t index = 0; index < M; ++index)
679 at(index) *= other.at(index);
682 template <
size_t M,
typename T>
685 for (
size_t index = 0; index < M; ++index)
686 at(index) /= other.at(index);
689 template <
size_t M,
typename T>
692 for (
size_t index = 0; index < M; ++index)
693 at(index) += other.at(index);
696 template <
size_t M,
typename T>
699 for (
size_t index = 0; index < M; ++index)
700 at(index) -= other.at(index);
703 template <
size_t M,
typename T>
707 for (
size_t index = 0; index < M; ++index)
708 result.at(index) = at(index) * other;
712 template <
size_t M,
typename T>
716 for (
size_t index = 0; index < M; ++index)
717 result.at(index) = at(index) / other;
721 template <
size_t M,
typename T>
725 for (
size_t index = 0; index < M; ++index)
726 result.at(index) = at(index) + other;
730 template <
size_t M,
typename T>
734 for (
size_t index = 0; index < M; ++index)
735 result.at(index) = at(index) - other;
739 template <
size_t M,
typename T>
742 for (
size_t index = 0; index < M; ++index)
746 template <
size_t M,
typename T>
749 for (
size_t index = 0; index < M; ++index)
753 template <
size_t M,
typename T>
756 for (
size_t index = 0; index < M; ++index)
760 template <
size_t M,
typename T>
763 for (
size_t index = 0; index < M; ++index)
767 template <
size_t M,
typename T>
774 template <
size_t M,
typename T>
777 for (
size_t index = 0; index < M; ++index)
782 template <
size_t M,
typename T>
788 template <
size_t M,
typename T>
794 template <
size_t M,
typename T>
800 template <
size_t M,
typename T>
806 template <
size_t M,
typename T>
812 template <
size_t M,
typename T>
818 template <
size_t M,
typename T>
824 template <
size_t M,
typename T>
830 template <
size_t M,
typename T>
836 template <
size_t M,
typename T>
842 template <
size_t M,
typename T>
848 template <
size_t M,
typename T>
854 template <
size_t M,
typename T>
860 template <
size_t M,
typename T>
866 template <
size_t M,
typename T>
872 template <
size_t M,
typename T>
878 template <
size_t M,
typename T>
879 template <
typename TT>
881 typename std::enable_if<M == 3, TT>::type*)
883 const T x_ = y() * rhs.z() - z() * rhs.y();
884 const T y_ = z() * rhs.x() - x() * rhs.z();
885 const T z_ = x() * rhs.y() - y() * rhs.x();
892 template <
size_t M,
typename T>
896 for (
size_t index = 0; index < M; ++index)
897 tmp += at(index) * other.at(index);
902 template <
size_t M,
typename T>
905 const T len = length();
906 if (len <= std::numeric_limits<T>::epsilon())
909 const T tmp = 1.0 / len;
914 template <
size_t M,
typename T>
917 return std::sqrt(squared_length());
920 template <
size_t M,
typename T>
923 T _squared_length = 0.0;
924 for (const_iterator it = begin(), it_end = end(); it != it_end; ++it)
925 _squared_length += (*it) * (*it);
927 return _squared_length;
930 template <
size_t M,
typename T>
933 return std::sqrt(squared_distance(other));
936 template <
size_t M,
typename T>
941 return tmp.squared_length();
944 template <
size_t M,
typename T>
948 for (
size_t i = 1; i < M; ++i)
953 template <
size_t M,
typename T>
954 template <
typename TT>
956 typename std::enable_if<M == 3, TT>::type*)
958 const T costheta = std::cos(theta);
959 const T sintheta = std::sin(theta);
963 (costheta + (1 - costheta) * axis.x() * axis.x()) * x() +
964 ((1 - costheta) * axis.x() * axis.y() -
965 axis.z() * sintheta) *
967 ((1 - costheta) * axis.x() * axis.z() +
968 axis.y() * sintheta) *
971 ((1 - costheta) * axis.x() * axis.y() + axis.z() * sintheta) *
973 (costheta + (1 - costheta) * axis.y() * axis.y()) * y() +
974 ((1 - costheta) * axis.y() * axis.z() -
975 axis.x() * sintheta) *
978 ((1 - costheta) * axis.x() * axis.z() - axis.y() * sintheta) *
980 ((1 - costheta) * axis.y() * axis.z() +
981 axis.x() * sintheta) *
983 (costheta + (1 - costheta) * axis.z() * axis.z()) * z());
987 template <
size_t M,
typename T>
988 template <
typename TT>
991 typename std::enable_if<M == 4, TT>::type*)
const 996 projected_point -= center_;
997 projected_point.normalize();
998 projected_point *= w();
999 return center_ + projected_point;
1003 template <
size_t M,
typename T>
1004 template <
typename TT>
1007 typename std::enable_if<M == 4, TT>::type*)
const 1010 return (point - center_).length() - w();
1013 template <
size_t M,
typename T>
1014 template <
size_t N,
size_t O>
1016 typename std::enable_if<M >= N + O>::type*)
const 1021 template <
size_t M,
typename T>
1022 template <
size_t N,
size_t O>
1024 typename std::enable_if<M >= N + O>::type*)
1026 ::memcpy(
array + O, sub.array, N *
sizeof(T));
1030 template <
size_t M,
typename T>
1031 template <
typename TT>
1034 typename std::enable_if<M == 4, TT>::type*)
const 1037 return normal.dot(point) + w();
1041 template <
size_t M,
typename T>
1042 template <
typename TT>
1045 typename std::enable_if<M == 4, TT>::type*)
const 1048 return point - (normal * distance_to_plane(point));
1051 template <
size_t M,
typename T>
1054 return memcmp(
array, other.array,
sizeof(
array)) == 0;
1057 template <
size_t M,
typename T>
1060 return !this->operator==(other);
1063 template <
size_t M,
typename T>
1066 for (
size_t index = 0; index < M; ++index)
1067 if (fabs(at(index) - other(index)) >= tolerance)
1072 template <
size_t M,
typename T>
1075 for (
size_t index = 0; index < M; ++index)
1077 if (at(index) < other.at(index))
1079 if (other.at(index) < at(index))
1085 template <
size_t M,
typename T>
1088 for (
size_t index = 0; index < M; ++index)
1089 at(index) = filler_value;
1090 return filler_value;
1093 template <
size_t M,
typename T>
1097 memcpy(
array, other.array, M *
sizeof(T));
1102 template <
size_t M,
typename T>
1103 template <
typename U>
1106 typedef typename vector<M, U>::const_iterator u_c_iter;
1107 u_c_iter it = source_.begin(), it_end = source_.end();
1108 for (iterator my_it = begin(); it != it_end; ++it, ++my_it)
1109 *my_it = static_cast<T>(*it);
1112 template <
size_t M,
typename T>
1113 template <
typename input_iterator_t>
1116 input_iterator_t in_it = begin_;
1117 iterator it = begin(), it_end = end();
1118 for (; it != it_end && in_it != end_; ++it, ++in_it)
1119 (*it) =
static_cast<T
>(*in_it);
1122 template <
size_t M,
typename T>
1125 for (
size_t i = 0; i < M; ++i)
1134 template <
size_t M,
typename T>
1140 template <
size_t M,
typename T>
1143 return std::min_element(begin(), end()) - begin();
1146 template <
size_t M,
typename T>
1149 return std::max_element(begin(), end()) - begin();
1152 template <
size_t M,
typename T>
1155 return *std::min_element(begin(), end());
1158 template <
size_t M,
typename T>
1161 return *std::min_element(begin(), end());
1164 template <
size_t M,
typename T>
1167 return *std::max_element(begin(), end());
1170 template <
size_t M,
typename T>
1173 return *std::max_element(begin(), end());
1176 template <
size_t M,
typename T>
1182 template <
size_t M,
typename T>
1189 template <
size_t M,
typename T>
1195 template <
size_t M,
typename T>
1202 template <
size_t M,
typename T>
1205 return array + M - 1;
1208 template <
size_t M,
typename T>
1214 template <
size_t M,
typename T>
1218 return array + M - 1;
1221 template <
size_t M,
typename T>
1227 template <
size_t M,
typename T>
1230 const_iterator it = begin(), it_end = end();
1232 for (; it != it_end; ++it)
1240 else if (*it != 0.0)
1248 template <
size_t M,
typename T>
1251 for (iterator it = begin(), it_end = end(); it != it_end; ++it)
1253 (*it) += (rand() & 1u) ? perturbation : -perturbation;
1257 template <
size_t M,
typename T>
1260 for (iterator it = begin(), it_end = end(); it != it_end; ++it)
1262 (*it) = std::sqrt(*it);
1266 template <
size_t M,
typename T>
1269 for (iterator it = begin(), it_end = end(); it != it_end; ++it)
1270 (*it) =
static_cast<T
>(1) / (*it);
1273 template <
size_t M,
typename T>
1276 for (iterator it = begin(), it_end = end(); it != it_end; ++it)
1281 v = std::numeric_limits<T>::max();
1283 v =
static_cast<T
>(1) / v;
1287 template <
size_t M,
typename T>
1288 template <
typename TT>
1292 typedef typename vector_tt_type::const_iterator tt_const_iterator;
1294 iterator it = begin(), it_end = end();
1295 tt_const_iterator other_it = other.begin();
1296 for (; it != it_end; ++it, ++other_it)
1298 *it =
static_cast<T
>(*other_it);
1302 template <
size_t M,
typename T>
1307 const_iterator it = begin(), it_end = end();
1308 for (; it != it_end; ++it)
1319 template <
size_t M,
typename T>
1322 double norm_v = 0.0;
1324 const_iterator it = begin(), it_end = end();
1325 for (; it != it_end; ++it)
1327 norm_v += *it * *it;
1330 return std::sqrt(norm_v);
1333 template <
size_t M,
typename T>
1339 for (
size_t i = 0; i < M; ++i)
1341 const double fillValue = double(rand()) / double(RAND_MAX);
1342 at(i) = -1.0 + 2.0 * fillValue;
void set_sub_vector(const vector< N, T > &sub, typename std::enable_if< M >=N+O >::type *=nullptr)
Set the sub vector of the given length at the given offset.
vector< N, T > get_sub_vector(typename std::enable_if< M >=N+O >::type *=nullptr) const