904 lines
17 KiB
C
904 lines
17 KiB
C
|
//
|
|||
|
// This source code is property of the Computer Graphics and Visualization
|
|||
|
// chair of the TU Dresden. Do not distribute in modified or unmodified form!
|
|||
|
// Copyright (C) 2015 CGV TU Dresden - All Rights Reserved
|
|||
|
//
|
|||
|
/*************************************************************************
|
|||
|
Template class for vectors.
|
|||
|
This template class defines small vectors of a defined dimension with
|
|||
|
an arbitrary data type. Basic operations such as addition of vectors and
|
|||
|
multiplication of a vector and a scalar are supported via operator
|
|||
|
overloading. Also more advanced functions such as normalization and
|
|||
|
iterating through the elements are implemented.
|
|||
|
At the end of this file the data types "point2d", "point3d" and
|
|||
|
"point4d" are specified as a tinyvec of doubles with the according dimension.
|
|||
|
*************************************************************************/
|
|||
|
|
|||
|
#pragma once
|
|||
|
|
|||
|
#include <iostream>
|
|||
|
#include <algorithm>
|
|||
|
|
|||
|
#pragma warning( disable : 4996 )
|
|||
|
|
|||
|
|
|||
|
template <typename T,int N>
|
|||
|
class tiny_vec
|
|||
|
{
|
|||
|
|
|||
|
T _data[N];
|
|||
|
|
|||
|
public:
|
|||
|
typedef T value_type;
|
|||
|
typedef T& reference;
|
|||
|
typedef const T& const_reference;
|
|||
|
typedef std::size_t size_type;
|
|||
|
typedef std::ptrdiff_t difference_type;
|
|||
|
typedef T* pointer;
|
|||
|
typedef const T* const_pointer;
|
|||
|
typedef T* iterator;
|
|||
|
typedef const T* const_iterator;
|
|||
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
|||
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
|||
|
|
|||
|
tiny_vec();
|
|||
|
|
|||
|
template <typename InputIterator>
|
|||
|
tiny_vec(InputIterator first,InputIterator last)
|
|||
|
{
|
|||
|
std::copy(first,last,begin());
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
tiny_vec(size_t n, const T* marray);
|
|||
|
|
|||
|
~tiny_vec();
|
|||
|
|
|||
|
tiny_vec(const T&x,const T&y);
|
|||
|
|
|||
|
tiny_vec(const T&x,const T&y, const T&z);
|
|||
|
|
|||
|
tiny_vec(const T&x, const T&y, const T&z,const T& w);
|
|||
|
|
|||
|
int size() const;
|
|||
|
|
|||
|
operator T*();
|
|||
|
|
|||
|
operator const T*() const;
|
|||
|
|
|||
|
void set(const T& x);
|
|||
|
|
|||
|
void set(const T& x, const T& y);
|
|||
|
|
|||
|
void set(const T& x, const T& y,const T& z);
|
|||
|
|
|||
|
void set(const T& x, const T& y,const T& z, const T& w);
|
|||
|
|
|||
|
tiny_vec& operator=(const T &s);
|
|||
|
|
|||
|
tiny_vec& operator=(int s);
|
|||
|
|
|||
|
tiny_vec& operator=(const tiny_vec & v);
|
|||
|
|
|||
|
void fill(const T& s);
|
|||
|
|
|||
|
void zeros(size_t m);
|
|||
|
|
|||
|
void zeros();
|
|||
|
|
|||
|
void ones();
|
|||
|
|
|||
|
void ones(size_t m);
|
|||
|
|
|||
|
iterator begin();
|
|||
|
|
|||
|
iterator end();
|
|||
|
|
|||
|
const_iterator begin() const;
|
|||
|
|
|||
|
const_iterator end() const;
|
|||
|
|
|||
|
reverse_iterator rbegin();
|
|||
|
|
|||
|
reverse_iterator rend();
|
|||
|
|
|||
|
const_reverse_iterator rbegin() const;
|
|||
|
|
|||
|
const_reverse_iterator rend() const;
|
|||
|
|
|||
|
bool operator==(const tiny_vec& v) const;
|
|||
|
|
|||
|
bool operator!=(const tiny_vec& v) const;
|
|||
|
|
|||
|
tiny_vec operator-() const;
|
|||
|
|
|||
|
tiny_vec& operator+=(const T& s);
|
|||
|
|
|||
|
tiny_vec& operator+=(int s);
|
|||
|
|
|||
|
tiny_vec operator+(const T& s) const;
|
|||
|
|
|||
|
tiny_vec operator+(int s) const;
|
|||
|
|
|||
|
tiny_vec& operator-=(const T& s);
|
|||
|
|
|||
|
tiny_vec& operator-=(int s);
|
|||
|
|
|||
|
tiny_vec operator-(const T& s) const;
|
|||
|
|
|||
|
tiny_vec operator-(int s) const;
|
|||
|
|
|||
|
tiny_vec& operator*=(const T& s);
|
|||
|
|
|||
|
tiny_vec& operator*=(int s);
|
|||
|
|
|||
|
tiny_vec operator*(const T& s) const;
|
|||
|
|
|||
|
tiny_vec operator*(int s) const;
|
|||
|
|
|||
|
tiny_vec& operator/=(const T& s);
|
|||
|
|
|||
|
tiny_vec& operator/=(int s);
|
|||
|
|
|||
|
tiny_vec operator/(const T& s) const;
|
|||
|
|
|||
|
tiny_vec operator/(int s) const;
|
|||
|
|
|||
|
tiny_vec& operator+=(const tiny_vec& v);
|
|||
|
|
|||
|
tiny_vec operator+(const tiny_vec& v) const;
|
|||
|
|
|||
|
tiny_vec& operator-=(const tiny_vec& v);
|
|||
|
|
|||
|
tiny_vec operator-(const tiny_vec& v) const;
|
|||
|
|
|||
|
tiny_vec& operator*=(const tiny_vec& v);
|
|||
|
|
|||
|
tiny_vec operator*(const tiny_vec& v) const;
|
|||
|
|
|||
|
tiny_vec& operator/=(const tiny_vec& v);
|
|||
|
|
|||
|
tiny_vec operator/(const tiny_vec& v) const;
|
|||
|
|
|||
|
T& operator()(size_t i);
|
|||
|
|
|||
|
T operator()(size_t i) const;
|
|||
|
|
|||
|
T& x() {return _data[0];};
|
|||
|
T& y() {return _data[1];};
|
|||
|
T& z() {return _data[2];};
|
|||
|
|
|||
|
T x() const {return _data[0];};
|
|||
|
T y() const {return _data[1];};
|
|||
|
T z() const {return _data[2];};
|
|||
|
|
|||
|
|
|||
|
void sort();
|
|||
|
|
|||
|
void random_shuffle();
|
|||
|
|
|||
|
T& min_elem();
|
|||
|
|
|||
|
size_t min_index();
|
|||
|
|
|||
|
T& max_elem();
|
|||
|
|
|||
|
size_t max_index();
|
|||
|
|
|||
|
T& median_elem();
|
|||
|
|
|||
|
size_t median_index();
|
|||
|
|
|||
|
T sqr_length();
|
|||
|
|
|||
|
T length();
|
|||
|
|
|||
|
void normalize();
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::tiny_vec(){}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::tiny_vec(size_t n, const T* marray)
|
|||
|
{
|
|||
|
std::copy(marray,marray+_size,begin());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::~tiny_vec(){}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::tiny_vec(const T&x,const T&y)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
_data[1]=y;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::tiny_vec(const T&x,const T&y, const T&z)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
_data[1]=y;
|
|||
|
_data[2]=z;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::tiny_vec(const T&x, const T&y, const T&z,const T& w)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
_data[1]=y;
|
|||
|
_data[2]=z;
|
|||
|
_data[3]=w;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::set(const T& x)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::set(const T& x, const T& y)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
_data[1]=y;
|
|||
|
|
|||
|
}
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::set(const T& x, const T& y,const T& z)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
_data[1]=y;
|
|||
|
_data[2]=z;
|
|||
|
|
|||
|
}
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::set(const T& x, const T& y,const T& z, const T& w)
|
|||
|
{
|
|||
|
_data[0]=x;
|
|||
|
_data[1]=y;
|
|||
|
_data[2]=z;
|
|||
|
_data[3]=w;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
int tiny_vec<T,N>::size() const
|
|||
|
{
|
|||
|
return N;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::operator T*()
|
|||
|
{
|
|||
|
return _data;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>::operator const T*() const
|
|||
|
{
|
|||
|
return _data;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator=(const T &s)
|
|||
|
{
|
|||
|
for(int i=0;i < N;i++)
|
|||
|
_data[i]=s;
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator=(int s)
|
|||
|
{
|
|||
|
for(int i=0;i<N;i++)
|
|||
|
_data[i]=(T)s;
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator=(const tiny_vec & v)
|
|||
|
{
|
|||
|
if(&v== this) return *this;
|
|||
|
|
|||
|
std::copy(v.begin(),v.end(),begin());
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::fill(const T& s)
|
|||
|
{
|
|||
|
std::fill(begin(),end(),s);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::zeros(size_t m)
|
|||
|
{
|
|||
|
T zero;
|
|||
|
zero=0;
|
|||
|
std::fill(begin(), end(), zero);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::zeros()
|
|||
|
{
|
|||
|
T zero;
|
|||
|
zero=0;
|
|||
|
std::fill(begin(), end(), zero);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::ones()
|
|||
|
{
|
|||
|
T one;
|
|||
|
one = 1;
|
|||
|
std::fill(begin(), end(), one);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::ones(size_t m)
|
|||
|
{
|
|||
|
resize(m);
|
|||
|
T one;
|
|||
|
one = 1;
|
|||
|
std::fill(begin(), end(), one);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::iterator tiny_vec<T,N>::begin()
|
|||
|
{
|
|||
|
return _data;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::const_iterator tiny_vec<T,N>::begin() const
|
|||
|
{
|
|||
|
return _data;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::iterator tiny_vec<T,N>::end()
|
|||
|
{
|
|||
|
return _data + N;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::const_iterator tiny_vec<T,N>::end() const
|
|||
|
{
|
|||
|
return _data +N;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::reverse_iterator tiny_vec<T,N>::rbegin()
|
|||
|
{
|
|||
|
return reverse_iterator(end());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::reverse_iterator tiny_vec<T,N>::rend()
|
|||
|
{
|
|||
|
return reverse_iterator(begin());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::const_reverse_iterator tiny_vec<T,N>::rbegin() const
|
|||
|
{
|
|||
|
return const_reverse_iterator(end());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
typename tiny_vec<T,N>::const_reverse_iterator tiny_vec<T,N>:: rend() const
|
|||
|
{
|
|||
|
return const_reverse_iterator(begin());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
bool tiny_vec<T,N>::operator==(const tiny_vec<T,N>& v) const
|
|||
|
{
|
|||
|
|
|||
|
return std::equal(begin(),end(),v.begin());
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
bool tiny_vec<T,N>::operator!=(const tiny_vec<T,N>& v) const
|
|||
|
{
|
|||
|
return !(*this == v);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator-() const
|
|||
|
{
|
|||
|
return (T)-1* *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator+=(const T& s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem+=s;});
|
|||
|
#else
|
|||
|
for(int i=0;i<size();i++)
|
|||
|
_data[i]+=s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator+=(int s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem+=(T)s;});
|
|||
|
#else
|
|||
|
for(int i=0;i<size();i++)
|
|||
|
_data[i]+=s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator+(const T& s) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r += s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator+(int s) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r += s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator-=(const T& s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem-=s;});
|
|||
|
#else
|
|||
|
for(int i=0; i < N;i++)
|
|||
|
_data[i]-=s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator-=(int s)
|
|||
|
{
|
|||
|
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem-=(T)s;});
|
|||
|
#else
|
|||
|
for(int i=0;i<N;i++)
|
|||
|
_data[i]-=(T)s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator-(const T& s) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r -= s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator-(int s) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r -= (T)s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator*=(const T& s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem *= s;});
|
|||
|
#else
|
|||
|
for(int i=0;i < N;i++)
|
|||
|
_data[i]*=s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator*=(int s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem *= (T)s;});
|
|||
|
#else
|
|||
|
for(int i=0; i <N; i++)
|
|||
|
_data[i]*=(T)s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator*(const T& s) const
|
|||
|
{
|
|||
|
tiny_vec<T,N> r = *this;
|
|||
|
r *= s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator*(int s) const
|
|||
|
{
|
|||
|
tiny_vec<T,N> r = *this;
|
|||
|
r *= (T)s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator/=(const T& s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem/=s;});
|
|||
|
#else
|
|||
|
for(int i=0; i <N; i++)
|
|||
|
_data[i]/=s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator/=(int s)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(begin(),end(),[&s](T& elem){elem/=(T)s;});
|
|||
|
#else
|
|||
|
for(int i=0;i <N; i++)
|
|||
|
_data[i]/=(T)s;
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator/(const T& s) const
|
|||
|
{
|
|||
|
tiny_vec<T,N> r = *this;
|
|||
|
r /= s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator/(int s) const
|
|||
|
{
|
|||
|
tiny_vec<T,N> r = *this;
|
|||
|
r /= (T)s;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator+=(const tiny_vec& v)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
const_iterator vit=v.begin();
|
|||
|
std::for_each(begin(),end(),[&vit](T& elem){elem+=*vit++;});
|
|||
|
#else
|
|||
|
for(int i=0; i <N;i++)
|
|||
|
_data[i] += v[i];
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator+(const tiny_vec& v) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r += v;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator-=(const tiny_vec& v)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
const_iterator vit=v.begin();
|
|||
|
std::for_each(begin(),end(),[&vit](T& elem){elem-=*vit++;});
|
|||
|
#else
|
|||
|
for(int i =0; i < N; i++)
|
|||
|
_data[i]-= v[i];
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator-(const tiny_vec& v) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r -= v;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator*=(const tiny_vec& v)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
auto vit=v.begin();
|
|||
|
std::for_each(begin(),end(),[&vit](T& elem){elem*=*vit++;});
|
|||
|
#else
|
|||
|
for(int i=0; i < N; i++)
|
|||
|
_data[i]*= v[i];
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator*(const tiny_vec& v) const
|
|||
|
{
|
|||
|
tiny_vec<T,N> r = *this;
|
|||
|
r *= v;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N>& tiny_vec<T,N>::operator/=(const tiny_vec& v)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
auto vit=v.begin();
|
|||
|
std::for_each(begin(),end(),[&vit](T& elem){elem/=*vit++;});
|
|||
|
#else
|
|||
|
for(int i = 0; i < N; i++)
|
|||
|
_data[i] /= v[i];
|
|||
|
#endif
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> tiny_vec<T,N>::operator/(const tiny_vec<T,N>& v) const
|
|||
|
{
|
|||
|
tiny_vec r = *this;
|
|||
|
r /= v;
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T& tiny_vec<T,N>::operator()(size_t i)
|
|||
|
{
|
|||
|
assert(i >= 0 && i < N);
|
|||
|
return _data[i];
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T tiny_vec<T,N>::operator()(size_t i) const
|
|||
|
{
|
|||
|
assert(i >= 0 && i < N);
|
|||
|
return _data[i];
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::sort()
|
|||
|
{
|
|||
|
std::sort(begin(),end());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::random_shuffle()
|
|||
|
{
|
|||
|
std::random_shuffle(begin(),end());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T& tiny_vec<T,N>::min_elem()
|
|||
|
{
|
|||
|
return *std::min_element(begin(),end());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
size_t tiny_vec<T,N>::min_index()
|
|||
|
{
|
|||
|
return std::distance(begin(),std::min_element(begin(),end()));
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T& tiny_vec<T,N>::max_elem()
|
|||
|
{
|
|||
|
return *std::max_element(begin(),end());
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
size_t tiny_vec<T,N>::max_index()
|
|||
|
{
|
|||
|
return std::distance(begin(),std::max_element(begin(),end()));
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T& tiny_vec<T,N>::median_elem()
|
|||
|
{
|
|||
|
iterator it= begin() + _size/2;
|
|||
|
std::nth_element(begin(),it,end());
|
|||
|
return *it;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
size_t tiny_vec<T,N>::median_index()
|
|||
|
{
|
|||
|
return begin() +_size/2;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T tiny_vec<T,N>::sqr_length()
|
|||
|
{
|
|||
|
iterator it= begin();
|
|||
|
T l = 0;
|
|||
|
while(it != end())
|
|||
|
l += (*it)*(*it++);
|
|||
|
|
|||
|
return l;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T tiny_vec<T,N>::length()
|
|||
|
{
|
|||
|
T l = sqr_length();
|
|||
|
return sqrt(l);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator+(const T& s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return v+s;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator+(int s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return v+(T)s;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator-(const T& s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return -v+s;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator-(int s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return -v+(T)s;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator*(const T& s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return v*s;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator*(int s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return v*(T)s;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator/(const T& s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return v*(T)(1.0/s);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N> operator/(int s, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
return v*(T)(1.0/s);
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
T dot(const tiny_vec<T,N>& v1, const tiny_vec<T,N>& v2)
|
|||
|
{
|
|||
|
return std::inner_product(v1.begin(),v1.end(),v2.begin(),(T)0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
template <typename T>
|
|||
|
tiny_vec<T,3> cross(const tiny_vec<T,3>& b, const tiny_vec<T,3>& c)
|
|||
|
{
|
|||
|
|
|||
|
tiny_vec<T,3> a;
|
|||
|
a[0] = b(1)*c(2) - b(2)*c(1);
|
|||
|
a[1] = b(2)*c(0) - b(0)*c(2);
|
|||
|
a[2] = b(0)*c(1) - b(1)*c(0);
|
|||
|
return a;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N+1> homog(const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
tiny_vec<T,N+1> vh;
|
|||
|
std::copy(v.begin(),v.end(),vh.begin());
|
|||
|
vh(v.size()) = (T)1;
|
|||
|
return vh;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
tiny_vec<T,N-1> unhomog(const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
tiny_vec<T,N-1> vh;
|
|||
|
T w = *(v.end()-1);
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
auto vit=v.begin();
|
|||
|
std::for_each(vh.begin(),vh.end(),[&](T& elem){elem=*vit++/w;});
|
|||
|
#else
|
|||
|
for(int i = 0; i < N-1; i++)
|
|||
|
vh[i] = v[i]/w;
|
|||
|
#endif
|
|||
|
return vh;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
std::ostream& operator<<(std::ostream& out, const tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
auto it = v.begin();
|
|||
|
if(it != v.end())
|
|||
|
out << *it ++;
|
|||
|
std::for_each(it, v.end(),[&out](const T& elem){ out << " " << elem;});
|
|||
|
#else
|
|||
|
if(v.size() > 0)
|
|||
|
out << v[0];
|
|||
|
for(int i = 1; i < v.size(); i++)
|
|||
|
out <<" " <<v[i];
|
|||
|
#endif
|
|||
|
return out;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
template <typename T,int N>
|
|||
|
std::istream& operator>>(std::istream& in, tiny_vec<T,N>& v)
|
|||
|
{
|
|||
|
#ifdef _HAS_CPP0X
|
|||
|
std::for_each(v.begin(), v.end(),[&in](T& elem){ in >> elem;});
|
|||
|
#else
|
|||
|
for(int i = 0; i < v.size(); i++)
|
|||
|
in >> v[i];
|
|||
|
#endif
|
|||
|
return in;
|
|||
|
}
|
|||
|
|
|||
|
template <typename T, int N>
|
|||
|
void tiny_vec<T,N>::normalize()
|
|||
|
{
|
|||
|
T l = length();
|
|||
|
if(l != 0)
|
|||
|
operator/=(l);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
typedef tiny_vec<double, 2> point2d;
|
|||
|
typedef tiny_vec<double, 3> point3d;
|
|||
|
typedef tiny_vec<double, 4> point4d;
|