Shapeworks Studio  2.1
Shape analysis software suite
math3d.h
1 #pragma once
2 #include <math.h>
3 #include <assert.h>
4 #include <vector>
5 using namespace std;
6 #define PI 3.1415926
7 #define RAD2DEG (180.0/PI)
8 #define DEG2RAD (PI/180.0)
9 
10 //-----------------------------------------------------------------------------
11 // class vec2d defines a 2D vector
12 class vec2d
13 {
14 public:
15  vec2d() { x = y = 0.0; }
16  vec2d(double X, double Y) { x = X; y = Y; }
17 
18  vec2d operator - () { return vec2d(-x, -y); }
19 
20  vec2d operator - (const vec2d& r) { return vec2d(x - r.x, y - r.y); }
21  vec2d operator + (const vec2d& r) { return vec2d(x + r.x, y + r.y); }
22  vec2d operator * (double g) { return vec2d(x*g, y*g); }
23 
24  double operator * (const vec2d& r) { return (x*r.x + y*r.y); }
25 
26  double norm() { return sqrt(x*x + y*y); }
27  double unit() { double R = sqrt(x*x + y*y); if (R != 0) {x /= R; y/= R; }; return R; }
28 
29  bool operator == (const vec2d& r) const { return (x==r.x)&&(y==r.y); }
30 
31 public:
32  double x, y;
33 };
34 
35 //-----------------------------------------------------------------------------
36 // class vec3d defines a 3D vector
37 //
38 class vec3d
39 {
40 public:
41  vec3d() { x = y = z = 0; }
42  vec3d(double rx, double ry, double rz) { x = rx; y = ry; z = rz; }
43  vec3d(const vec2d& r) { x = r.x; y = r.y; z = 0; }
44 
45  vec3d operator + (const vec3d& v) const { return vec3d( x + v.x, y + v.y, z + v.z); }
46  vec3d operator - (const vec3d& v) const { return vec3d( x - v.x, y - v.y, z - v.z); }
47  vec3d operator ^ (const vec3d& v) const
48  {
49  return vec3d( y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x);
50  }
51 
52  double operator * (const vec3d& v) const { return (x*v.x + y*v.y + z*v.z); }
53 
54  vec3d operator * (const double g) const { return vec3d(x*g, y*g, z*g); }
55  vec3d operator / (const double g) const { return vec3d(x/g, y/g, z/g); }
56 
57  const vec3d& operator += (const vec3d& v) { x += v.x; y += v.y; z += v.z; return (*this); }
58  const vec3d& operator -= (const vec3d& v) { x -= v.x; y -= v.y; z -= v.z; return (*this); }
59  const vec3d& operator /= (const double f) { x /= f; y /= f; z /= f; return (*this); }
60  const vec3d& operator /= (const int n) { x /= n; y /= n; z /= n; return (*this); }
61  const vec3d& operator *= (const double f) { x*=f; y*=f; z*=f; return (*this); }
62 
63  vec3d operator - () const { return vec3d(-x, -y, -z); }
64 
65  double Length() const { return (double) sqrt(x*x + y*y + z*z); }
66  double SqrLength() const { return x*x + y*y + z*z; }
67 
68  vec3d& Normalize()
69  {
70  double L = Length();
71  if (L != 0) { x /= L; y /= L; z /= L; }
72 
73  return (*this);
74  }
75 
76 public:
77  double x, y, z;
78 };
79 
81 // vec6d
82 
83 class vec6d
84 {
85 public:
86  vec6d() { x = y = z = xy = yz = xz = 0; }
87 
88 public:
89  double x, y, z;
90  double xy, yz, xz;
91 };
92 
93 
95 // mat3d
96 
97 class mat3d
98 {
99 public:
100  mat3d()
101  {
102  zero();
103  }
104 
105  mat3d(double a00, double a01, double a02, double a10, double a11, double a12, double a20, double a21, double a22);
106 
107  double* operator [] (int i) { return m_data[i]; }
108  double& operator () (int i, int j) { return m_data[i][j]; }
109 
110  mat3d operator * (mat3d& m)
111  {
112  mat3d a;
113 
114  int k;
115  for (k=0; k<3; k++)
116  {
117  a[0][0] += m_data[0][k]*m[k][0]; a[0][1] += m_data[0][k]*m[k][1]; a[0][2] += m_data[0][k]*m[k][2];
118  a[1][0] += m_data[1][k]*m[k][0]; a[1][1] += m_data[1][k]*m[k][1]; a[1][2] += m_data[1][k]*m[k][2];
119  a[2][0] += m_data[2][k]*m[k][0]; a[2][1] += m_data[2][k]*m[k][1]; a[2][2] += m_data[2][k]*m[k][2];
120  }
121 
122  return a;
123  }
124 
125  mat3d& operator *=(mat3d& m)
126  {
127  mat3d a;
128 
129  int k;
130  for (k=0; k<3; k++)
131  {
132  a[0][0] += m_data[0][k]*m[k][0]; a[0][1] += m_data[0][k]*m[k][1]; a[0][2] += m_data[0][k]*m[k][2];
133  a[1][0] += m_data[1][k]*m[k][0]; a[1][1] += m_data[1][k]*m[k][1]; a[1][2] += m_data[1][k]*m[k][2];
134  a[2][0] += m_data[2][k]*m[k][0]; a[2][1] += m_data[2][k]*m[k][1]; a[2][2] += m_data[2][k]*m[k][2];
135  }
136 
137  m_data[0][0] = a.m_data[0][0]; m_data[0][1] = a.m_data[0][1]; m_data[0][2] = a.m_data[0][2];
138  m_data[1][0] = a.m_data[1][0]; m_data[1][1] = a.m_data[1][1]; m_data[1][2] = a.m_data[1][2];
139  m_data[2][0] = a.m_data[2][0]; m_data[2][1] = a.m_data[2][1]; m_data[2][2] = a.m_data[2][2];
140 
141  return (*this);
142  }
143 
144  mat3d& operator +=(mat3d& m)
145  {
146  m_data[0][0] += m[0][0]; m_data[0][1] += m[0][1]; m_data[0][2] += m[0][2];
147  m_data[1][0] += m[1][0]; m_data[1][1] += m[1][1]; m_data[1][2] += m[1][2];
148  m_data[2][0] += m[2][0]; m_data[2][1] += m[2][1]; m_data[2][2] += m[2][2];
149 
150  return (*this);
151  }
152  mat3d& operator -=(mat3d& m)
153  {
154  m_data[0][0] -= m[0][0]; m_data[0][1] -= m[0][1]; m_data[0][2] -= m[0][2];
155  m_data[1][0] -= m[1][0]; m_data[1][1] -= m[1][1]; m_data[1][2] -= m[1][2];
156  m_data[2][0] -= m[2][0]; m_data[2][1] -= m[2][1]; m_data[2][2] -= m[2][2];
157 
158  return (*this);
159  }
160 
161  mat3d& operator /=(const double f)
162  {
163  m_data[0][0] /= f; m_data[0][1] /= f; m_data[0][2] /= f;
164  m_data[1][0] /= f; m_data[1][1] /= f; m_data[1][2] /= f;
165  m_data[2][0] /= f; m_data[2][1] /= f; m_data[2][2] /= f;
166 
167  return (*this);
168  }
169 
170  vec3d operator * (vec3d b)
171  {
172  vec3d r;
173  r.x = m_data[0][0]*b.x + m_data[0][1]*b.y + m_data[0][2]*b.z;
174  r.y = m_data[1][0]*b.x + m_data[1][1]*b.y + m_data[1][2]*b.z;
175  r.z = m_data[2][0]*b.x + m_data[2][1]*b.y + m_data[2][2]*b.z;
176 
177  return r;
178  }
179 
180  double det()
181  {
182  double det = 0;
183  det += m_data[0][0]*m_data[1][1]*m_data[2][2];
184  det += m_data[0][1]*m_data[1][2]*m_data[2][0];
185  det += m_data[0][2]*m_data[1][0]*m_data[2][1];
186  det -= m_data[0][2]*m_data[1][1]*m_data[2][0];
187  det -= m_data[0][1]*m_data[1][0]*m_data[2][2];
188  det -= m_data[0][0]*m_data[1][2]*m_data[2][1];
189  return det;
190  }
191 
192  double Invert();
193 
194  void zero()
195  {
196  m_data[0][0] = m_data[0][1] = m_data[0][2] = 0;
197  m_data[1][0] = m_data[1][1] = m_data[1][2] = 0;
198  m_data[2][0] = m_data[2][1] = m_data[2][2] = 0;
199  }
200 
201  void unit()
202  {
203  m_data[0][0] = m_data[1][1] = m_data[2][2] = 1;
204  m_data[0][1] = m_data[0][2] = m_data[1][2] = 0;
205  m_data[1][0] = m_data[2][0] = m_data[2][1] = 0;
206  }
207 
208  mat3d transpose();
209 
210 protected:
211  double m_data[3][3];
212 };
213 
214 
215 
217 // matrix
218 
219 class matrix
220 {
221 public:
222  matrix(int r, int c);
223  ~matrix() { delete [] d; }
224 
225  void zero();
226 
227  double* operator [] (int i) { return d + i*m_nc; }
228  double& operator () (int i, int j) { return d[i*m_nc + j]; }
229 
230  bool solve(vector<double>& x, vector<double>& b);
231 
232  bool lsq_solve(vector<double>& x, vector<double>& b);
233  bool eigen_vectors(matrix& Eigen,vector<double>& eigen_values);
234  int Rows() { return m_nr; }
235 
236  void mult_transpose(vector<double>& x, vector<double>& y);
237 
238  void mult_transpose_self(matrix& AAt);
239 
240 private:
241  double* d;
242  int m_nr, m_nc;
243  int m_ne;
244 };
245 
246 
248 // quatd
249 
250 class quatd
251 {
252 public:
253  // constructors
254  quatd () { x = y = z = 0; w = 1; }
255 
256  quatd( const double angle, vec3d v)
257  {
258  w = (double) cos(angle * 0.5);
259 
260  double sina = (double) sin(angle * 0.5);
261 
262  v.Normalize();
263 
264  x = v.x*sina;
265  y = v.y*sina;
266  z = v.z*sina;
267  }
268 
269  quatd (vec3d v1, vec3d v2)
270  {
271  vec3d n = v1^v2;
272  n.Normalize();
273 
274  double d = v1*v2;
275 
276  double sina = (double) sqrt((1.0-d)*0.5);
277  double cosa = (double) sqrt((1.0+d)*0.5);
278 
279  w = cosa;
280 
281  x = n.x*sina;
282  y = n.y*sina;
283  z = n.z*sina;
284 
285  }
286 
287  quatd(const double qx, const double qy, const double qz, const double qw = 1.0)
288  {
289  w = qw;
290  x = qx;
291  y = qy;
292  z = qz;
293  }
294 
295  bool operator != (const quatd& q) { return ((x!=q.x) || (y!=q.y) || (z!=q.z) || (w!=q.w)); }
296 
297  quatd operator - () { return quatd(-x, -y, -z, -w); }
298 
299  // addition and substraction
300 
301  quatd operator + (const quatd& q) const
302  {
303  return quatd(x + q.x, y + q.y, z + q.z, w + q.w);
304  }
305 
306  quatd operator - (const quatd& q) const
307  {
308  return quatd(x - q.x, y - q.y, z - q.z, w - q.w);
309  }
310 
311  quatd& operator += (const quatd& q)
312  {
313  x += q.x;
314  y += q.y;
315  z += q.z;
316  w += q.w;
317 
318  return *this;
319  }
320 
321  quatd& operator -= (const quatd& q)
322  {
323  x -= q.x;
324  y -= q.y;
325  z -= q.z;
326  w -= q.w;
327 
328  return *this;
329  }
330 
331 
332  // multiplication
333 
334  quatd operator * (const quatd& q) const
335  {
336  double qw = w*q.w - x*q.x - y*q.y - z*q.z;
337  double qx = w*q.x + x*q.w + y*q.z - z*q.y;
338  double qy = w*q.y + y*q.w + z*q.x - x*q.z;
339  double qz = w*q.z + z*q.w + x*q.y - y*q.x;
340 
341  return quatd(qx, qy, qz, qw);
342  }
343 
344  quatd& operator *= (const quatd& q)
345  {
346  double qw = w*q.w - x*q.x - y*q.y - z*q.z;
347  double qx = w*q.x + x*q.w + y*q.z - z*q.y;
348  double qy = w*q.y + y*q.w + z*q.x - x*q.z;
349  double qz = w*q.z + z*q.w + x*q.y - y*q.x;
350 
351  x = qx;
352  y = qy;
353  z = qz;
354  w = qw;
355 
356  return *this;
357  }
358 
359  quatd operator*(const double a) const
360  {
361  return quatd(x*a, y*a, z*a, w*a);
362  }
363 
364  // division
365 
366  quatd operator / (const double a) const
367  {
368  return quatd(x/a, y/a, z/a, w/a);
369  }
370 
371  quatd& operator /= (const double a)
372  {
373  x /= a;
374  y /= a;
375  z /= a;
376  w /= a;
377 
378  return *this;
379  }
380 
381  // Special ops
382 
383  quatd Conjugate() const { return quatd(-x, -y, -z, w); }
384 
385  double Norm() const { return w*w + x*x + y*y + z*z; }
386 
387  void MakeUnit()
388  {
389  double N = (double) sqrt(w*w + x*x + y*y + z*z);
390 
391  if (N != 0)
392  {
393  x /= N;
394  y /= N;
395  z /= N;
396  w /= N;
397  }
398  else w = 1.f;
399  }
400 
401  quatd Inverse() const
402  {
403  double N = w*w + x*x + y*y + z*z;
404 
405  return quatd(-x/N, -y/N, -z/N, w/N);
406  }
407 
408  double DotProduct(const quatd& q) const
409  {
410  return w*q.w + x*q.x + y*q.y + z*q.z;
411  }
412 
413  vec3d GetVector() const
414  {
415  return vec3d(x, y, z).Normalize();
416  }
417 
418  double GetAngle() const
419  {
420  return (double)(acos(w)*2.0);
421  }
422 
423 /* quatd& MultiplyAngle(double fa)
424  {
425  double angle = fa*acos(w)*2.0;
426 
427  w = cos(angle * 0.5);
428 
429  double sina = sin(angle * 0.5);
430 
431  x *= sina;
432  y *= sina;
433  z *= sina;
434  }
435 */
436 
437 
438  // use only when *this is unit vector
439  void RotateVector(vec3d& v) const
440  {
441  if ((w == 0) || ((x==0) && (y==0) && (z==0))) return;
442 
443  // v*q^-1
444  double qw = v.x*x + v.y*y + v.z*z;
445  double qx = v.x*w - v.y*z + v.z*y;
446  double qy = v.y*w - v.z*x + v.x*z;
447  double qz = v.z*w - v.x*y + v.y*x;
448 
449  // q* (v* q^-1)
450  v.x = (double) (w*qx + x*qw + y*qz - z*qy);
451  v.y = (double) (w*qy + y*qw + z*qx - x*qz);
452  v.z = (double) (w*qz + z*qw + x*qy - y*qx);
453  }
454 
455  // use only when *this is unit vector
456  vec3d operator * (const vec3d& r)
457  {
458  vec3d n = r;
459 
460  // v*q^-1
461  double qw = n.x*x + n.y*y + n.z*z;
462  double qx = n.x*w - n.y*z + n.z*y;
463  double qy = n.y*w - n.z*x + n.x*z;
464  double qz = n.z*w - n.x*y + n.y*x;
465 
466  // q* (v* q^-1)
467  n.x = (w*qx + x*qw + y*qz - z*qy);
468  n.y = (w*qy + y*qw + z*qx - x*qz);
469  n.z = (w*qz + z*qw + x*qy - y*qx);
470 
471  return n;
472  }
473 
474  mat3d operator * (mat3d m)
475  {
476  mat3d a;
477  double qw, qx, qy, qz;
478  for (int i=0; i<3; ++i)
479  {
480  // v*q^-1
481  qw = m[0][i]*x + m[1][i]*y + m[2][i]*z;
482  qx = m[0][i]*w - m[1][i]*z + m[2][i]*y;
483  qy = m[1][i]*w - m[2][i]*x + m[0][i]*z;
484  qz = m[2][i]*w - m[0][i]*y + m[1][i]*x;
485 
486  // q* (v* q^-1)
487  a[0][i] = (w*qx + x*qw + y*qz - z*qy);
488  a[1][i] = (w*qy + y*qw + z*qx - x*qz);
489  a[2][i] = (w*qz + z*qw + x*qy - y*qx);
490  }
491 
492  return a;
493  }
494 
495  void RotateVectorP(double* v, double* r) const
496  {
497  static double fx, fy, fz, fw;
498  static double qw, qx, qy, qz;
499 
500  fx = (double) x;
501  fy = (double) y;
502  fz = (double) z;
503  fw = (double) w;
504 
505  qw = v[0]*fx + v[1]*fy + v[2]*fz;
506  qx = v[0]*fw - v[1]*fz + v[2]*fy;
507  qy = v[1]*fw - v[2]*fx + v[0]*fz;
508  qz = v[2]*fw - v[0]*fy + v[1]*fx;
509 
510  r[0] = (double) (fw*qx + fx*qw + fy*qz - fz*qy);
511  r[1] = (double) (fw*qy + fy*qw + fz*qx - fx*qz);
512  r[2] = (double) (fw*qz + fz*qw + fx*qy - fy*qx);
513  }
514 
515  static double dot(quatd &q1, quatd &q2)
516  { return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; }
517 
518  static quatd lerp(quatd &q1, quatd &q2, double t)
519  { quatd q = (q1*(1-t) + q2*t); q.MakeUnit(); return q; }
520 
521  static quatd slerp(quatd &q1, quatd &q2, double t) ;
522 
523 public:
524  double x, y, z;
525  double w;
526 };
527 
528 inline quatd operator * (const double a, const quatd& q)
529 {
530  return q*a;
531 }
532 
533 typedef unsigned char uchar;
534 
535 class GLCOLOR
536 {
537 public:
538  uchar a, b, g, r;
539 
540 public:
541  GLCOLOR() : a(255), b(0), g(0), r(0){}
542  GLCOLOR(uchar ur, uchar ug, uchar ub, uchar ua = 255)
543  {
544  r = ur; g = ug; b = ub; a = ua;
545  }
546 
547  GLCOLOR operator * (double f)
548  {
549  return GLCOLOR((uchar) (r*f), (uchar) (g*f), (uchar) (b*f));
550  }
551 
552  GLCOLOR operator + (GLCOLOR& c)
553  {
554  return GLCOLOR(r+c.r, g+c.g, b+c.b);
555  }
556 };
Definition: math3d.h:219
Definition: math3d.h:250
Definition: StdDeque.h:58
Definition: math3d.h:97
Definition: math3d.h:38
Definition: LDLT.h:16
Definition: math3d.h:12
Definition: math3d.h:83