cgv
fvec.h
1 #pragma once
2 
3 #define _USE_MATH_DEFINES
4 #include <limits>
5 #include <algorithm>
6 #include <iostream>
7 #include <cmath>
8 #include <cgv/type/standard_types.h>
9 
10 namespace cgv {
11  namespace math {
12 
13 template <typename T> class vec;
14 
16 template <typename T, cgv::type::uint32_type N>
17 class fvec
18 {
19 protected:
20  //elements of vector
21  T v[N];
22 public:
23  //@name type definitions
25  typedef T value_type;
28  typedef T& reference;
30  typedef const T& const_reference;
32  typedef std::size_t size_type;
34  typedef std::ptrdiff_t difference_type;
36  typedef T* pointer;
38  typedef const T* const_pointer;
40  typedef T* iterator;
42  typedef const T* const_iterator;
44  typedef std::reverse_iterator<iterator> reverse_iterator;
46  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
48 
49  //@name iterator generation
51  iterator begin() { return v; }
54  iterator end() { return v+N; }
56  const_iterator begin() const { return v; }
58  const_iterator end() const { return v+N; }
60  reverse_iterator rbegin() { return reverse_iterator(end()); }
62  reverse_iterator rend() { return reverse_iterator(begin()); }
64  const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
66  const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
68 
69  //@name construction and assignment
71  fvec() {}
74  fvec(const T &a) { std::fill(v, v+N, a); }
76  fvec(const T &x, const T &y) { set(x,y); }
78  fvec(const T &x, const T &y, const T &z) { set(x,y,z); }
80  fvec(const T &x, const T &y, const T &z,const T &w) { set(x,y,z,w); }
82  fvec(cgv::type::uint32_type n, const T *a) {
83  cgv::type::uint32_type i, min_n = n < N ? n : N;
84  std::copy(a, a+min_n, v);
85  for (i = min_n; i < N; ++i) v[i] = T(0);
86  }
88  template <typename S>
89  fvec(cgv::type::uint32_type n, const S *a) {
90  cgv::type::uint32_type i, min_n = n < N ? n : N;
91  for (i=0; i<min_n; ++i) v[i] = (T)a[i];
92  for (; i < N; ++i) v[i] = T(0);
93  }
95  fvec(const fvec<T,N> &rhs) { if (this != &rhs) std::copy(rhs.v, rhs.v+N, v); }
97  template <typename S>
98  fvec(const fvec<S,N>& fv) { for (unsigned i=0; i<N; ++i) v[i] = (T)fv(i); }
100  template <typename S1, typename S2>
101  fvec(const fvec<S1, N - 1>& fv, S2 w) { for (unsigned i = 0; i < N - 1; ++i) v[i] = (T)fv(i); v[N - 1] = (T)w; }
103  fvec & operator = (const fvec<T,N> &rhs) { if (this != &rhs) std::copy(rhs.v, rhs.v+N, v); return *this; }
105  fvec & operator = (const T &a) { std::fill(v, v+N, a); return *this; }
107  void set(const T &x, const T &y) { v[0] = x; v[1] = y; }
109  void set(const T &x, const T &y, const T &z) { v[0] = x; v[1] = y; v[2] = z; }
111  void set(const T &x, const T &y, const T &z, const T &w) { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
113  void fill(const T& a) { std::fill(v, v+N, a); }
115  void zeros() { fill((T)0); }
117  void ones() { fill((T)1); }
119  fvec<T,N+1> lift() const { fvec<T,N+1> h_v; (fvec<T,N>&)h_v=*this; h_v(N) = 1; return h_v; }
121  vec<T> to_vec() const;
123  static fvec<T, N> from_vec(const vec<T>&);
125 
126  //@name access to components
128  T& x() { return v[0]; }
131  const T& x() const { return v[0]; }
133  T& y() { return v[1]; }
135  const T& y() const { return v[1]; }
137  T& z() { return v[2]; }
139  const T& z() const { return v[2]; }
141  T& w() { return v[3]; }
143  const T& w() const { return v[3]; }
145  T& operator()(const int i) { return v[i]; }
147  const T & operator()(const int i) const { return v[i]; }
149  static cgv::type::uint32_type size() { return N; }
151  operator T*() { return v; }
153  operator const T*() const { return v; }
155 
156  //@name operators
158  fvec<T,N>& operator += (const T& s) { for (unsigned i=0;i<N;++i) v[i] += s; return *this; }
161  fvec<T,N>& operator -= (const T& s) { for (unsigned i=0;i<N;++i) v[i] -= s; return *this; }
163  fvec<T,N>& operator *= (const T& s) { for (unsigned i=0;i<N;++i) v[i] *= s; return *this; }
165  fvec<T,N>& operator /= (const T& s) { for (unsigned i=0;i<N;++i) v[i] /= s; return *this; }
167  template <typename S>
168  fvec<T,N>& operator += (const fvec<S,N>& _v) { for (unsigned i=0; i<N;++i) v[i] += _v(i); return *this; }
170  template <typename S>
171  fvec<T,N>& operator -= (const fvec<S,N>& _v) { for (unsigned i=0; i<N;++i) v[i] -= _v(i); return *this; }
173  template <typename S>
174  fvec<T,N>& operator *= (const fvec<S,N>& _v) { for (unsigned i=0; i<N;++i) v[i] *= _v(i); return *this; }
176  template <typename S>
177  fvec<T,N>& operator /= (const fvec<S,N>& _v) { for (unsigned i=0; i<N;++i) v[i] /= _v(i); return *this; }
179  template <typename S>
180  fvec<T,N> operator + (const fvec<S,N>& v) const { fvec<T,N> r = *this; r += v; return r; }
182  fvec<T,N> operator + (const T& s) const { fvec<T,N> r = *this; r += s; return r; }
184  fvec<T,N> operator - (const T& s) const { fvec<T,N> r = *this; r -= s; return r; }
186  template <typename S>
187  fvec<T,N> operator - (const fvec<S,N>& v) const { fvec<T,N> r = *this; r -= v; return r; }
189  template <typename S>
190  fvec<T,N> operator * (const fvec<S,N>& v) const { fvec<T,N> r = *this; r *= v; return r; }
192  template <typename S>
193  fvec<T,N> operator / (const fvec<S,N>& v) const { fvec<T,N> r = *this; r /= v; return r; }
195  fvec<T,N> operator-(void) const { fvec<T,N> r; for (unsigned i=0; i<N; ++i) r(i) = -v[i]; return r; }
197  fvec<T,N> operator * (const T& s) const { fvec<T,N> r = *this; r *= s; return r; }
199  fvec<T,N> operator / (const T& s) const { fvec<T,N> r = *this; r /= s; return r; }
201  template <typename S>
202  bool operator == (const fvec<S,N>& v) const {
203  for (unsigned i=0;i<N;++i)
204  if(operator()(i) != (T)v(i)) return false;
205  return true;
206  }
208  template <typename S>
209  bool operator != (const fvec<S,N>& v) const {
210  for (unsigned i=0;i<N;++i)
211  if(operator()(i) != (T)v(i)) return true;
212  return false;
213  }
215 
216  //@name functions
218  T length() const
220  {
221  return (T)sqrt((double)sqr_length());
222  }
223 
225  void abs() {
226  if(std::numeric_limits<T>::is_signed) {
227  for(unsigned i = 0; i < N;i++)
228  v[i]=(T)std::abs((double)v[i]);
229  }
230  }
231 
233  void ceil() {
234  for(unsigned i = 0; i < N;i++)
235  v[i]=(T)::ceil((double)v[i]);
236  }
237 
239  void floor() {
240  for(unsigned i = 0; i < N;i++)
241  v[i]=(T)::floor((double)v[i]);
242  }
243 
245  void round() {
246  for(unsigned i = 0; i < N;i++)
247  v[i]=(T)::floor((double)v[i]+0.5);
248  }
249 
250 
252  T sqr_length() const {
253  T l=0;
254  for(unsigned i = 0; i!=N;i++)
255  l+= operator()(i)*operator()(i);
256  return l;
257  }
258 
260  double normalize() {
261  T l = length();
262  T inv_l = (T)1.0/l;
263  for(unsigned i = 0; i<N; i++)
264  operator()(i)=inv_l*operator()(i);
265  return l;
266  }
268 };
269 
271 template<typename T, cgv::type::uint32_type N>
272 fvec<T,N> normalize(const fvec<T,N>& v) { fvec<T,N> w(v); w.normalize(); return w; }
273 
275 template<typename T, cgv::type::uint32_type N>
276 std::ostream& operator<<(std::ostream& out, const fvec<T,N>& v)
277 {
278  for (unsigned i=0;i<N-1;++i)
279  out << v(i)<<" ";
280  out << v(N-1);
281  return out;
282 
283 }
284 
286 template<typename T, cgv::type::uint32_type N>
287 std::istream& operator>>(std::istream& in, fvec<T,N>& v)
288 {
289  for (unsigned i=0;i<N;++i)
290  in >> v(i);
291  return in;
292 }
293 
295 template <typename T, cgv::type::uint32_type N>
296 fvec<T,N> operator * (const T& s, const fvec<T,N>& v) { fvec<T,N> r = v; r *= s; return r; }
297 
299 template <typename T, cgv::type::uint32_type N>
300 inline T dot(const fvec<T,N>& v, const fvec<T,N>& w)
301 {
302  T r = 0;
303  for (unsigned i=0;i<N;++i)
304  r += v(i)*w(i);
305  return r;
306 }
307 
309 template <typename T, cgv::type::uint32_type N>
310 inline T length(const fvec<T, N>& v) { return sqrt(dot(v, v)); }
311 
313 template <typename T, cgv::type::uint32_type N>
314 inline fvec<T, N> abs(const fvec<T, N>& v) { fvec<T, N> r(v); r.abs(); return r; }
315 
317 template <typename T, cgv::type::uint32_type N>
318 inline fvec<T, N> round(const fvec<T, N>& v) { fvec<T, N> r(v); r.round(); return r; }
319 
321 template <typename T, cgv::type::uint32_type N>
322 inline fvec<T, N> floor(const fvec<T, N>& v) { fvec<T, N> r(v); r.floor(); return r; }
323 
325 template <typename T, cgv::type::uint32_type N>
326 inline fvec<T, N> ceil(const fvec<T, N>& v) { fvec<T, N> r(v); r.ceil(); return r; }
327 
329 template <typename T, cgv::type::uint32_type N>
330 inline T sqr_length(const fvec<T,N>& v)
331 {
332  return dot(v,v);
333 }
334 
335 
337 template < typename T, cgv::type::uint32_type N>
338 inline fvec<T,N> cross(const fvec<T,N>& v, const fvec<T,N>& w)
339 {
340  fvec<T,N> r(3);
341  r(0)= v(1)*w(2) - v(2)*w(1);
342  r(1)= v(2)*w(0) - v(0)*w(2);
343  r(2)= v(0)*w(1) - v(1)*w(0);
344  return r;
345 }
346 
348 template < typename T, cgv::type::uint32_type N>
349 inline fvec<T,N+1> hom(const fvec<T,N>& v)
350 {
351  fvec<T,N+1> h;
352  for (unsigned i = 0; i<N; ++i)
353  h(i) = v(i);
354  h(N) = 1;
355  return h;
356 }
357 
359 template < typename T, cgv::type::uint32_type N>
360 T min_value(const fvec<T,N> &v)
361 {
362  return *(std::min_element(&v(0),&v(N-1)+1));
363 }
364 
366 template < typename T, cgv::type::uint32_type N>
367 unsigned min_index(const fvec<T,N> &v)
368 {
369  return (unsigned) (std::min_element(&v(0),&v(N-1)+1)-&v(0));
370 }
371 
373 template < typename T, cgv::type::uint32_type N>
374 unsigned max_index(const fvec<T,N> &v)
375 {
376  return (unsigned) (std::max_element(&v(0),&v(N-1)+1)-&v(0));
377 }
378 
380 template < typename T, cgv::type::uint32_type N>
381 T max_value(const fvec<T,N> &v)
382 {
383  return *(std::max_element(&v(0),&v(N-1)+1));
384 }
385 
387 template <typename T, cgv::type::uint32_type N>
388 const fvec<T, N> lerp(const fvec<T, N>& v1, const fvec<T, N>& v2, T t)
389 {
390  return ((T)1 - t)*v1 + t * v2;
391 }
392 
394 template <typename T, cgv::type::uint32_type N>
395 const fvec<T, N> lerp(const fvec<T, N>& v1, const fvec<T, N>& v2, fvec<T, N> t)
396 {
397  return (fvec<T, N>(1) - t)*v1 + t * v2;
398 }
399 
400  }
401 }
402 
403 
404 #include "vec.h"
405 
406 namespace cgv {
407  namespace math {
408 
410 template <typename T, cgv::type::uint32_type N>
412  vec<T> r;
413  r.set_extern_data(N,const_cast<T*>(v));
414  return r;
415 }
416 
418 template <typename T, cgv::type::uint32_type N>
420 {
421  return fvec<T, N>(std::min(N, v.dim()), &v[0]);
422 }
423 
424  }
425 }
426 
427 /*
428 #include <cgv/utils/convert_string.h>
429 #include <cgv/type/info/type_name.h>
430 
431 namespace cgv {
432  namespace type {
433  namespace info {
434 
435 template <typename T, cgv::type::uint32_type N>
436 struct type_name<cgv::math::fvec<T,N> >
437 {
438  static const char* get_name() {
439  static std::string name;
440  if (name.empty()) {
441  name = "fvec<";
442  name += type_name<T>::get_name();
443  name += ',';
444  name += cgv::utils::to_string(N);
445  name += '>';
446  }
447  return name.c_str();
448  }
449 };
450  }
451  }
452 }
453 */
cgv::math::fvec::rend
const_reverse_iterator rend() const
reverse iterator pointing to the end of reverse iteration
Definition: fvec.h:66
cgv::math::fvec::operator-=
fvec< T, N > & operator-=(const T &s)
in place subtraction by scalar s
Definition: fvec.h:161
cgv::math::fvec::normalize
double normalize()
normalize the vector using the L2-Norm and return the length
Definition: fvec.h:260
cgv::math::fvec::fvec
fvec(const T &x, const T &y, const T &z)
construct and init first three coordinates to the given values
Definition: fvec.h:78
cgv::math::fvec::fvec
fvec(const fvec< T, N > &rhs)
copy constructor
Definition: fvec.h:95
cgv::math::fvec::z
const T & z() const
third element of const vector
Definition: fvec.h:139
cgv::math::fvec::length
T length() const
length of the vector L2-Norm
Definition: fvec.h:219
cgv::math::fvec::w
const T & w() const
fourth element of const vector
Definition: fvec.h:143
cgv::math::fvec::operator+=
fvec< T, N > & operator+=(const T &s)
in place addition of a scalar s
Definition: fvec.h:159
cgv::math::fvec::y
T & y()
second element
Definition: fvec.h:133
cgv::math::cross
fvec< T, N > cross(const fvec< T, N > &v, const fvec< T, N > &w)
returns the cross product of vector v and w
Definition: fvec.h:338
cgv::math::fvec::round
void round()
round componentwise
Definition: fvec.h:245
cgv::math::round
fvec< T, N > round(const fvec< T, N > &v)
apply round function component wise to vector
Definition: fvec.h:318
cgv::math::fvec::zeros
void zeros()
fill the vector with zeros
Definition: fvec.h:115
cgv::math::fvec
Definition: fvec.h:18
cgv::math::fvec::y
const T & y() const
second element of const vector
Definition: fvec.h:135
cgv::math::fvec::abs
void abs()
componentwise absolute values
Definition: fvec.h:225
cgv::math::vec::set_extern_data
void set_extern_data(unsigned dim, T *data)
set data pointer to an external data array
Definition: vec.h:232
cgv::math::fvec::floor
void floor()
floor componentwise
Definition: fvec.h:239
cgv::math::vec
A column vector class.
Definition: fvec.h:13
cgv::math::fvec::operator!=
bool operator!=(const fvec< S, N > &v) const
test for inequality
Definition: fvec.h:209
cgv::math::fvec::set
void set(const T &x, const T &y, const T &z, const T &w)
set the first four components
Definition: fvec.h:111
cgv::math::fvec::operator==
bool operator==(const fvec< S, N > &v) const
test for equality
Definition: fvec.h:202
cgv::math::fvec::operator()
T & operator()(const int i)
access i'th element
Definition: fvec.h:145
cgv::math::fvec::w
T & w()
fourth element
Definition: fvec.h:141
cgv::math::fvec::operator*=
fvec< T, N > & operator*=(const T &s)
in place multiplication with s
Definition: fvec.h:163
cgv::math::floor
fvec< T, N > floor(const fvec< T, N > &v)
apply floor function component wise to vector
Definition: fvec.h:322
cgv::math::fvec::fvec
fvec(const fvec< S1, N - 1 > &fv, S2 w)
construct from vector of one dimension less plus a scalar
Definition: fvec.h:101
cgv::math::fvec::set
void set(const T &x, const T &y)
set the first two components
Definition: fvec.h:107
cgv::math::fvec::fvec
fvec(cgv::type::uint32_type n, const T *a)
creates a vector from a n-element array a, if n < N remaining N-n elements are set to zero
Definition: fvec.h:82
cgv::math::operator<<
std::ostream & operator<<(std::ostream &out, const diag_mat< T > &m)
output of a diagonal matrix onto an ostream
Definition: diag_mat.h:442
cgv::math::fvec::fvec
fvec(const T &a)
creates a vector, where all N components are initialized to the constant value a
Definition: fvec.h:74
cgv::math::max_index
unsigned max_index(const fvec< T, N > &v)
return the index of the largest entry
Definition: fvec.h:374
cgv::math::abs
fvec< T, N > abs(const fvec< T, N > &v)
apply abs function component wise to vector
Definition: fvec.h:314
cgv::math::fvec::sqr_length
T sqr_length() const
square length of vector
Definition: fvec.h:252
cgv::math::fvec::to_vec
vec< T > to_vec() const
conversion to vector type
Definition: fvec.h:411
cgv::math::fvec::x
T & x()
first element
Definition: fvec.h:129
cgv::math::lerp
const fmat< T, N, M > lerp(const fmat< T, N, M > &m1, const fmat< T, N, M > &m2, T t)
linear interpolation returns (1-t)*m1 + t*m2
Definition: fmat.h:259
cgv::math::fvec::ceil
void ceil()
ceil componentwise
Definition: fvec.h:233
cgv::math::min_value
T min_value(const fvec< T, N > &v)
returns the minimal entry
Definition: fvec.h:360
cgv::math::fvec::x
const T & x() const
first element of const vector
Definition: fvec.h:131
cgv::math::ceil
fvec< T, N > ceil(const fvec< T, N > &v)
apply ceil function component wise to vector
Definition: fvec.h:326
cgv::math::fvec::size
static cgv::type::uint32_type size()
return number of elements
Definition: fvec.h:149
cgv::math::sqr_length
T sqr_length(const fvec< T, N > &v)
returns the squared length of vector v
Definition: fvec.h:330
cgv::math::fvec::fvec
fvec()
creates a vector not initialized
Definition: fvec.h:72
cgv::math::fvec::operator-
fvec< T, N > operator-(void) const
negates the vector
Definition: fvec.h:195
cgv::math::fvec::fill
void fill(const T &a)
fill elements of vector with scalar v
Definition: fvec.h:113
cgv::math::fvec::operator/
fvec< T, N > operator/(const fvec< S, N > &v) const
componentwise vector division
Definition: fvec.h:193
cgv::math::operator>>
std::istream & operator>>(std::istream &in, diag_mat< T > &m)
input of a diagonal matrix from an istream
Definition: diag_mat.h:453
cgv::math::max_value
T max_value(const fvec< T, N > &v)
return the value of the largest entry
Definition: fvec.h:381
cgv::type::uint32_type
unsigned int uint32_type
this type provides an 32 bit unsigned integer type
Definition: standard_types.h:20
cgv::math::fvec::from_vec
static fvec< T, N > from_vec(const vec< T > &)
conversion from vector
Definition: fvec.h:419
cgv::math::hom
fvec< T, N+1 > hom(const fvec< T, N > &v)
returns the cross product of vector v and w
Definition: fvec.h:349
cgv::math::fvec::set
void set(const T &x, const T &y, const T &z)
set the first three components
Definition: fvec.h:109
cgv::math::fvec::operator=
fvec & operator=(const fvec< T, N > &rhs)
assign vector rhs, if vector and rhs have different sizes, vector has been resized to match the size ...
Definition: fvec.h:103
cgv::math::dot
T dot(const fvec< T, N > &v, const fvec< T, N > &w)
returns the dot product of vector v and w
Definition: fvec.h:300
cgv::math::fvec::fvec
fvec(const fvec< S, N > &fv)
copies a column vector of a different type
Definition: fvec.h:98
cgv::math::fvec::ones
void ones()
fill the vector with ones
Definition: fvec.h:117
cgv::math::fvec::operator()
const T & operator()(const int i) const
access i'th element of const vector
Definition: fvec.h:147
cgv::math::fvec::operator+
fvec< T, N > operator+(const fvec< S, N > &v) const
vector addition
Definition: fvec.h:180
cgv::math::fvec::fvec
fvec(cgv::type::uint32_type n, const S *a)
creates a column vector initialized to array of a different type with zeros filled to not copied comp...
Definition: fvec.h:89
cgv::math::fvec::z
T & z()
third element
Definition: fvec.h:137
cgv::math::fvec::fvec
fvec(const T &x, const T &y, const T &z, const T &w)
construct and init first four coordinates to the given values
Definition: fvec.h:80
cgv::math::fvec::lift
fvec< T, N+1 > lift() const
convert to homogeneous version by adding a 1
Definition: fvec.h:119
cgv::math::fvec::fvec
fvec(const T &x, const T &y)
construct and init first two coordinates to the given values
Definition: fvec.h:76
cgv
the cgv namespace
Definition: vr_calib.cxx:9
cgv::math::min_index
unsigned min_index(const fvec< T, N > &v)
returns the index of the smallest value
Definition: fvec.h:367
cgv::math::normalize
fvec< T, N > normalize(const fvec< T, N > &v)
return normalized vector
Definition: fvec.h:272
cgv::math::fvec::operator*
fvec< T, N > operator*(const fvec< S, N > &v) const
componentwise vector multiplication
Definition: fvec.h:190
cgv::math::length
T length(const fvec< T, N > &v)
returns the length of vector v
Definition: fvec.h:310
cgv::math::fvec::operator/=
fvec< T, N > & operator/=(const T &s)
in place division by scalar s
Definition: fvec.h:165