cgv
qem.h
1 #pragma once
2 
3 #include "vec.h"
4 #include "mat.h"
5 #include "inv.h"
6 
7 namespace cgv {
8  namespace math {
9 
10 
12 template <typename T>
13 class qem : public vec<T>
14 {
15 public:
17  qem(int d = -1) : vec<T>((d+1)*(d+2)/2)
18  {
19  if (d>=0)
20  this->zeros();
21  }
23  qem(const vec<T>& p, const vec<T>& n) : vec<T>((p.size()+1)*(p.size()+2)/2)
24  {
25  set(n, -dot(p,n));
26  }
28  qem(const vec<T>& n, T d) : vec<T>((n.size()+1)*(n.size()+2)/2)
29  {
30  set(n,d);
31  }
33  void set(const vec<T>& n, T d)
34  {
35  this->first() = d*d;
36  unsigned int i,j,k=n.size()+1;
37  for (i=0;i<n.size(); ++i) {
38  (*this)(i+1) = d*n(i);
39  for (j=i;j<n.size(); ++j, ++k)
40  (*this)(k) = n(i)*n(j);
41  }
42  }
44  unsigned dim() const
45  {
46  return (unsigned int)sqrt(2.0*this->size())-1;
47  }
50  {
51  *static_cast<vec<T>*>(this) = v;
52  return *this;
53  }
55  const T& scalar_part() const
56  {
57  return this->first();
58  }
61  {
62  vec<T> v(dim());
63  for (unsigned int i=0; i<v.size(); ++i)
64  v(i) = (*this)(i+1);
65  return v;
66  }
69  {
70  unsigned int d = dim();
71  mat<T> m(d,d);
72  unsigned int i,j,k=d+1;
73  for (i=0; i<d; ++i)
74  for (j=i; j<d; ++j,++k)
75  m(i,j) = m(j,i) = (*this)(k);
76  return m;
77  }
79  T evaluate(const vec<T>& p) const
80  {
81  return dot(matrix_part()*p+2.0*vector_part(),p)+scalar_part();
82  }
83  static bool inside(const vec<T>& p, const vec<T>& minp, const vec<T>& maxp)
84  {
85  for (unsigned int i=0; i<p.size(); ++i) {
86  if (p(i) < minp(i))
87  return false;
88  if (p(i) > maxp(i))
89  return false;
90  }
91  return true;
92  }
98  vec<T> minarg(const vec<T>& p_ref, T relative_epsilon, T max_distance = -1, T epsilon = 1e-10) const
99  {
100  unsigned int d = p_ref.size();
101  assert(d == dim());
102  T max_distance2 = max_distance*max_distance;
103  mat<T> U,V,A = matrix_part();
104  diag_mat<T> W,iW;
105  svd(A,U,W,V);
106  U.transpose();
107  iW = inv(W);
108  vec<T> y_solve = -(inv(W)*(U*vector_part()));
109  vec<T> y_ref = transpose(V)*p_ref;
110  vec<T> y(3);
111  for (unsigned int i = d; i > 0; ) {
112  --i;
113  if (fabs(W(i)) > epsilon && fabs(W(i)*iW(0)) > relative_epsilon) {
114  unsigned int j;
115  for (j = 0; j <= i; ++j)
116  y(j) = y_solve(j);
117  for (; j < d; ++j)
118  y(j) = y_ref(j);
119  vec<T> p = V*y;
120  if (max_distance != -1 && (p-p_ref).sqr_length() <= max_distance2)
121  return p;
122  }
123  }
124  return p_ref;
125  }
127  template <typename S>
129  {
130  assert(this->size() == v.size());
131  for (unsigned i=0;i<this->size();++i) (*this)(i) += v(i); return *this;
132  }
133 
135  template <typename S>
137  {
138  assert(this->size() == v.size());
139  for (unsigned i=0;i<this->size();++i) (*this)(i) -= v(i); return *this;
140  }
141 
143  template <typename S>
144  const qem<T> operator + (const qem<S>& v) const
145  {
146  vec<T> r = *this; r += v; return r;
147  }
148 
150  template <typename S>
151  qem<T> operator - (const qem<S>& v) const
152  {
153  qem<T> r = *this; r -= v; return r;
154  }
155 
157  qem<T> operator-(void) const
158  {
159  qem<T> r=(*this);
160  r=(T)(-1)*r;
161  return r;
162  }
163 
165  qem<T> operator * (const T& s) const
166  {
167  qem<T> r = *this; r *= s; return r;
168  }
169 
170 
172  qem<T> operator / (const T& s)const
173  {
174  qem<T> r = *this;
175  r /= s;
176  return r;
177  }
178 
180  void resize(unsigned d)
181  {
182  vec<T>::resize((d+1)*(d+2)/2);
183  }
184 
186  template <typename S>
187  bool operator == (const qem<S>& v) const
188  {
189  for (unsigned i=0;i<this->size();++i)
190  if((*this)(i) != (T)v(i)) return false;
191  return true;
192  }
193 
195  template <typename S>
196  bool operator != (const qem<S>& v) const
197  {
198  for (unsigned i=0;i<this->size();++i)
199  if((*this)(i) != (T)v(i)) return true;
200  return false;
201  }
202 
203 };
204 
206 template <typename T>
207 const qem<T> operator * (const T& s, const qem<T>& v)
208 {
209  qem<T> r = v; r *= s; return r;
210 }
211 
212  }
213 }
214 
215 
cgv::math::qem::operator*
qem< T > operator*(const T &s) const
multiplication with scalar s
Definition: qem.h:165
cgv::math::qem::minarg
vec< T > minarg(const vec< T > &p_ref, T relative_epsilon, T max_distance=-1, T epsilon=1e-10) const
Definition: qem.h:98
cgv::math::vec::resize
void resize(unsigned dim)
resize the vector
Definition: vec.h:557
cgv::math::inv
diag_mat< T > inv(const diag_mat< T > &m)
returns the inverse of a diagonal matrix
Definition: inv.h:11
cgv::math::qem::qem
qem(const vec< T > &p, const vec< T > &n)
construct from point and normal
Definition: qem.h:23
cgv::math::qem::scalar_part
const T & scalar_part() const
return the scalar part of the qem
Definition: qem.h:55
cgv::math::qem::resize
void resize(unsigned d)
resize the vector
Definition: qem.h:180
cgv::math::qem::set
void set(const vec< T > &n, T d)
set from normal and distance to origin
Definition: qem.h:33
cgv::math::mat
Definition: mat.h:14
cgv::math::vec
A column vector class.
Definition: fvec.h:13
cgv::math::vec::size
unsigned size() const
number of elements
Definition: vec.h:97
cgv::math::qem::operator-
qem< T > operator-(void) const
negates the qem
Definition: qem.h:157
cgv::math::mat::transpose
void transpose()
transpose matrix
Definition: mat.h:922
cgv::math::transpose
fmat< T, N, N > transpose(const fmat< T, N, N > &m)
return the transposed of a square matrix
Definition: fmat.h:196
cgv::math::qem::matrix_part
mat< T > matrix_part() const
return matrix part
Definition: qem.h:68
cgv::math::vec::sqr_length
T sqr_length() const
square length of vector
Definition: vec.h:640
cgv::math::qem::evaluate
T evaluate(const vec< T > &p) const
evaluate the quadric error metric at given location
Definition: qem.h:79
cgv::math::qem
dimension independent implementation of quadric error metrics
Definition: qem.h:14
cgv::math::qem::qem
qem(int d=-1)
standard constructor initializes qem based on dimension
Definition: qem.h:17
cgv::math::diag_mat
Definition: diag_mat.h:16
cgv::math::qem::operator=
qem< T > & operator=(const qem< T > &v)
assignment of a vector v
Definition: qem.h:49
cgv::math::qem::operator/
qem< T > operator/(const T &s) const
divides vector by scalar s
Definition: qem.h:172
cgv::math::vec::zeros
void zeros()
fill the vector with zeros
Definition: vec.h:531
cgv::math::qem::dim
unsigned dim() const
number of elements
Definition: qem.h:44
cgv::math::qem::operator+
const qem< T > operator+(const qem< S > &v) const
qem addition
Definition: qem.h:144
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::qem::operator==
bool operator==(const qem< S > &v) const
test for equality
Definition: qem.h:187
cgv::math::qem::vector_part
vec< T > vector_part() const
return the vector part of the qem
Definition: qem.h:60
cgv::math::qem::operator-=
qem< T > & operator-=(const qem< S > &v)
in place qem subtraction
Definition: qem.h:136
cgv::math::qem::operator!=
bool operator!=(const qem< S > &v) const
test for inequality
Definition: qem.h:196
cgv::math::qem::operator+=
qem< T > & operator+=(const qem< S > &v)
in place qem addition
Definition: qem.h:128
cgv
the cgv namespace
Definition: vr_calib.cxx:9
cgv::math::vec::y
T & y()
element accessor for the second element
Definition: vec.h:355
cgv::math::svd
void svd(const fmat< T, N, M > &A, fmat< T, N, N > &U, fvec< T, M > &D, fmat< T, M, M > &V_t, bool ordering=true, int maxiter=30)
svd wrapper
Definition: align.h:25
cgv::math::vec::first
T & first()
element accessor for the first element
Definition: vec.h:311
cgv::math::qem::qem
qem(const vec< T > &n, T d)
construct from normal and distance to origin
Definition: qem.h:28