GteVector.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.1 (2016/07/08)
7 
8 #pragma once
9 
10 #include <GTEngineDEF.h>
11 #include <array>
12 #include <cmath>
13 #include <initializer_list>
14 
15 namespace gte
16 {
17 
18 template <int N, typename Real>
19 class Vector
20 {
21 public:
22  // The tuple is uninitialized.
23  Vector();
24 
25  // The tuple is fully initialized by the inputs.
26  Vector(std::array<Real, N> const& values);
27 
28  // At most N elements are copied from the initializer list, setting any
29  // remaining elements to zero. Create the zero vector using the syntax
30  // Vector<N,Real> zero{(Real)0};
31  // WARNING: The C++ 11 specification states that
32  // Vector<N,Real> zero{};
33  // will lead to a call of the default constructor, not the initializer
34  // constructor!
35  Vector(std::initializer_list<Real> values);
36 
37  // For 0 <= d < N, element d is 1 and all others are 0. If d is invalid,
38  // the zero vector is created. This is a convenience for creating the
39  // standard Euclidean basis vectors; see also MakeUnit(int) and Unit(int).
40  Vector(int d);
41 
42  // The copy constructor, destructor, and assignment operator are generated
43  // by the compiler.
44 
45  // Member access. The first operator[] returns a const reference rather
46  // than a Real value. This supports writing via standard file operations
47  // that require a const pointer to data.
48  inline int GetSize() const; // returns N
49  inline Real const& operator[](int i) const;
50  inline Real& operator[](int i);
51 
52  // Comparisons for sorted containers and geometric ordering.
53  inline bool operator==(Vector const& vec) const;
54  inline bool operator!=(Vector const& vec) const;
55  inline bool operator< (Vector const& vec) const;
56  inline bool operator<=(Vector const& vec) const;
57  inline bool operator> (Vector const& vec) const;
58  inline bool operator>=(Vector const& vec) const;
59 
60  // Special vectors.
61  void MakeZero(); // All components are 0.
62  void MakeUnit(int d); // Component d is 1, all others are zero.
63  static Vector Zero();
64  static Vector Unit(int d);
65 
66 protected:
67  // This data structure takes advantage of the built-in operator[],
68  // range checking, and visualizers in MSVS.
69  std::array<Real, N> mTuple;
70 };
71 
72 // Unary operations.
73 template <int N, typename Real>
75 
76 template <int N, typename Real>
78 
79 // Linear-algebraic operations.
80 template <int N, typename Real>
83 
84 template <int N, typename Real>
87 
88 template <int N, typename Real>
89 Vector<N, Real> operator*(Vector<N, Real> const& v, Real scalar);
90 
91 template <int N, typename Real>
92 Vector<N, Real> operator*(Real scalar, Vector<N, Real> const& v);
93 
94 template <int N, typename Real>
95 Vector<N, Real> operator/(Vector<N, Real> const& v, Real scalar);
96 
97 template <int N, typename Real>
99 
100 template <int N, typename Real>
102 
103 template <int N, typename Real>
105 
106 template <int N, typename Real>
108 
109 // Componentwise algebraic operations.
110 template <int N, typename Real>
113 
114 template <int N, typename Real>
117 
118 template <int N, typename Real>
120 
121 template <int N, typename Real>
123 
124 // Geometric operations. The functions with 'robust' set to 'false' use the
125 // standard algorithm for normalizing a vector by computing the length as a
126 // square root of the squared length and dividing by it. The results can be
127 // infinite (or NaN) if the length is zero. When 'robust' is set to 'true',
128 // the algorithm is designed to avoid floating-point overflow and sets the
129 // normalized vector to zero when the length is zero.
130 template <int N, typename Real>
131 Real Dot(Vector<N, Real> const& v0, Vector<N, Real> const& v1);
132 
133 template <int N, typename Real>
134 Real Length(Vector<N, Real> const& v, bool robust = false);
135 
136 template <int N, typename Real>
137 Real Normalize(Vector<N, Real>& v, bool robust = false);
138 
139 // Gram-Schmidt orthonormalization to generate orthonormal vectors from the
140 // linearly independent inputs. The function returns the smallest length of
141 // the unnormalized vectors computed during the process. If this value is
142 // nearly zero, it is possible that the inputs are linearly dependent (within
143 // numerical round-off errors). On input, 1 <= numElements <= N and v[0]
144 // through v[numElements-1] must be initialized. On output, the vectors
145 // v[0] through v[numElements-1] form an orthonormal set.
146 template <int N, typename Real>
147 Real Orthonormalize(int numElements, Vector<N, Real>* v, bool robust = false);
148 
149 // Construct a single vector orthogonal to the nonzero input vector. If the
150 // maximum absolute component occurs at index i, then the orthogonal vector
151 // U has u[i] = v[i+1], u[i+1] = -v[i], and all other components zero. The
152 // index addition i+1 is computed modulo N.
153 template <int N, typename Real>
154 Vector<N, Real> GetOrthogonal(Vector<N, Real> const& v, bool unitLength);
155 
156 // Compute the axis-aligned bounding box of the vectors. The return value is
157 // 'true' iff the inputs are valid, in which case vmin and vmax have valid
158 // values.
159 template <int N, typename Real>
160 bool ComputeExtremes(int numVectors, Vector<N, Real> const* v,
161  Vector<N, Real>& vmin, Vector<N, Real>& vmax);
162 
163 // Lift n-tuple v to homogeneous (n+1)-tuple (v,last).
164 template <int N, typename Real>
165 Vector<N + 1, Real> HLift(Vector<N, Real> const& v, Real last);
166 
167 // Project homogeneous n-tuple v = (u,v[n-1]) to (n-1)-tuple u.
168 template <int N, typename Real>
169 Vector<N - 1, Real> HProject(Vector<N, Real> const& v);
170 
171 // Lift n-tuple v = (w0,w1) to (n+1)-tuple u = (w0,u[inject],w1). By
172 // inference, w0 is a (inject)-tuple [nonexistent when inject=0] and w1 is a
173 // (n-inject)-tuple [nonexistent when inject=n].
174 template <int N, typename Real>
175 Vector<N + 1, Real> Lift(Vector<N, Real> const& v, int inject, Real value);
176 
177 // Project n-tuple v = (w0,v[reject],w1) to (n-1)-tuple u = (w0,w1). By
178 // inference, w0 is a (reject)-tuple [nonexistent when reject=0] and w1 is a
179 // (n-1-reject)-tuple [nonexistent when reject=n-1].
180 template <int N, typename Real>
181 Vector<N - 1, Real> Project(Vector<N, Real> const& v, int reject);
182 
183 
184 template <int N, typename Real>
186 {
187  // Uninitialized.
188 }
189 
190 template <int N, typename Real>
191 Vector<N, Real>::Vector(std::array<Real, N> const& values)
192  :
193  mTuple(values)
194 {
195 }
196 
197 template <int N, typename Real>
198 Vector<N, Real>::Vector(std::initializer_list<Real> values)
199 {
200  int i = 0;
201  for (auto value : values)
202  {
203  if (i < N)
204  {
205  mTuple[i++] = value;
206  }
207  else
208  {
209  break;
210  }
211  }
212  for (; i < N; ++i)
213  {
214  mTuple[i] = (Real)0;
215  }
216 }
217 
218 template <int N, typename Real>
220 {
221  MakeUnit(d);
222 }
223 
224 template <int N, typename Real> inline
226 {
227  return N;
228 }
229 
230 template <int N, typename Real> inline
231 Real const& Vector<N, Real>::operator[](int i) const
232 {
233  return mTuple[i];
234 }
235 
236 template <int N, typename Real> inline
238 {
239  return mTuple[i];
240 }
241 
242 template <int N, typename Real> inline
243 bool Vector<N, Real>::operator==(Vector const& vec) const
244 {
245  return mTuple == vec.mTuple;
246 }
247 
248 template <int N, typename Real> inline
249 bool Vector<N, Real>::operator!=(Vector const& vec) const
250 {
251  return mTuple != vec.mTuple;
252 }
253 
254 template <int N, typename Real> inline
255 bool Vector<N, Real>::operator<(Vector const& vec) const
256 {
257  return mTuple < vec.mTuple;
258 }
259 
260 template <int N, typename Real> inline
261 bool Vector<N, Real>::operator<=(Vector const& vec) const
262 {
263  return mTuple <= vec.mTuple;
264 }
265 
266 template <int N, typename Real> inline
267 bool Vector<N, Real>::operator>(Vector const& vec) const
268 {
269  return mTuple > vec.mTuple;
270 }
271 
272 template <int N, typename Real> inline
273 bool Vector<N, Real>::operator>=(Vector const& vec) const
274 {
275  return mTuple >= vec.mTuple;
276 }
277 
278 template <int N, typename Real>
280 {
281  std::fill(mTuple.begin(), mTuple.end(), (Real)0);
282 }
283 
284 template <int N, typename Real>
286 {
287  std::fill(mTuple.begin(), mTuple.end(), (Real)0);
288  if (0 <= d && d < N)
289  {
290  mTuple[d] = (Real)1;
291  }
292 }
293 
294 template <int N, typename Real>
296 {
298  v.MakeZero();
299  return v;
300 }
301 
302 template <int N, typename Real>
304 {
306  v.MakeUnit(d);
307  return v;
308 }
309 
310 
311 
312 template <int N, typename Real>
314 {
315  return v;
316 }
317 
318 template <int N, typename Real>
320 {
322  for (int i = 0; i < N; ++i)
323  {
324  result[i] = -v[i];
325  }
326  return result;
327 }
328 
329 template <int N, typename Real>
331  Vector<N, Real> const& v1)
332 {
334  return result += v1;
335 }
336 
337 template <int N, typename Real>
339  Vector<N, Real> const& v1)
340 {
342  return result -= v1;
343 }
344 
345 template <int N, typename Real>
347 {
349  return result *= scalar;
350 }
351 
352 template <int N, typename Real>
354 {
356  return result *= scalar;
357 }
358 
359 template <int N, typename Real>
361 {
363  return result /= scalar;
364 }
365 
366 template <int N, typename Real>
368 {
369  for (int i = 0; i < N; ++i)
370  {
371  v0[i] += v1[i];
372  }
373  return v0;
374 }
375 
376 template <int N, typename Real>
378 {
379  for (int i = 0; i < N; ++i)
380  {
381  v0[i] -= v1[i];
382  }
383  return v0;
384 }
385 
386 template <int N, typename Real>
388 {
389  for (int i = 0; i < N; ++i)
390  {
391  v[i] *= scalar;
392  }
393  return v;
394 }
395 
396 template <int N, typename Real>
398 {
399  if (scalar != (Real)0)
400  {
401  Real invScalar = ((Real)1) / scalar;
402  for (int i = 0; i < N; ++i)
403  {
404  v[i] *= invScalar;
405  }
406  }
407  else
408  {
409  for (int i = 0; i < N; ++i)
410  {
411  v[i] = (Real)0;
412  }
413  }
414  return v;
415 }
416 
417 template <int N, typename Real>
419  Vector<N, Real> const& v1)
420 {
422  return result *= v1;
423 }
424 
425 template <int N, typename Real>
427  Vector<N, Real> const& v1)
428 {
430  return result /= v1;
431 }
432 
433 template <int N, typename Real>
435 {
436  for (int i = 0; i < N; ++i)
437  {
438  v0[i] *= v1[i];
439  }
440  return v0;
441 }
442 
443 template <int N, typename Real>
445 {
446  for (int i = 0; i < N; ++i)
447  {
448  v0[i] /= v1[i];
449  }
450  return v0;
451 }
452 
453 template <int N, typename Real>
455 {
456  Real dot = v0[0] * v1[0];
457  for (int i = 1; i < N; ++i)
458  {
459  dot += v0[i] * v1[i];
460  }
461  return dot;
462 }
463 
464 template <int N, typename Real>
465 Real Length(Vector<N, Real> const& v, bool robust)
466 {
467  if (robust)
468  {
469  Real maxAbsComp = fabs(v[0]);
470  for (int i = 1; i < N; ++i)
471  {
472  Real absComp = fabs(v[i]);
473  if (absComp > maxAbsComp)
474  {
475  maxAbsComp = absComp;
476  }
477  }
478 
479  Real length;
480  if (maxAbsComp > (Real)0)
481  {
482  Vector<N, Real> scaled = v / maxAbsComp;
483  length = maxAbsComp * sqrt(Dot(scaled, scaled));
484  }
485  else
486  {
487  length = (Real)0;
488  }
489  return length;
490  }
491  else
492  {
493  return sqrt(Dot(v, v));
494  }
495 }
496 
497 template <int N, typename Real>
498 Real Normalize(Vector<N, Real>& v, bool robust)
499 {
500  if (robust)
501  {
502  Real maxAbsComp = fabs(v[0]);
503  for (int i = 1; i < N; ++i)
504  {
505  Real absComp = fabs(v[i]);
506  if (absComp > maxAbsComp)
507  {
508  maxAbsComp = absComp;
509  }
510  }
511 
512  Real length;
513  if (maxAbsComp > (Real)0)
514  {
515  v /= maxAbsComp;
516  length = sqrt(Dot(v, v));
517  v /= length;
518  length *= maxAbsComp;
519  }
520  else
521  {
522  length = (Real)0;
523  for (int i = 0; i < N; ++i)
524  {
525  v[i] = (Real)0;
526  }
527  }
528  return length;
529  }
530  else
531  {
532  Real length = sqrt(Dot(v, v));
533  if (length > (Real)0)
534  {
535  v /= length;
536  }
537  else
538  {
539  for (int i = 0; i < N; ++i)
540  {
541  v[i] = (Real)0;
542  }
543  }
544  return length;
545  }
546 }
547 
548 template <int N, typename Real>
549 Real Orthonormalize(int numInputs, Vector<N, Real>* v, bool robust)
550 {
551  if (v && 1 <= numInputs && numInputs <= N)
552  {
553  Real minLength = Normalize(v[0], robust);
554  for (int i = 1; i < numInputs; ++i)
555  {
556  for (int j = 0; j < i; ++j)
557  {
558  Real dot = Dot(v[i], v[j]);
559  v[i] -= v[j] * dot;
560  }
561  Real length = Normalize(v[i], robust);
562  if (length < minLength)
563  {
564  minLength = length;
565  }
566  }
567  return minLength;
568  }
569 
570  return (Real)0;
571 }
572 
573 template <int N, typename Real>
575 {
576  Real cmax = std::abs(v[0]);
577  int imax = 0;
578  for (int i = 1; i < N; ++i)
579  {
580  Real c = std::abs(v[i]);
581  if (c > cmax)
582  {
583  cmax = c;
584  imax = i;
585  }
586  }
587 
589  result.MakeZero();
590  int inext = imax + 1;
591  if (inext == N)
592  {
593  inext = 0;
594  }
595  result[imax] = v[inext];
596  result[inext] = -v[imax];
597  if (unitLength)
598  {
599  Real sqrDistance =
600  result[imax] * result[imax] + result[inext] * result[inext];
601  Real invLength = ((Real)1) / sqrt(sqrDistance);
602  result[imax] *= invLength;
603  result[inext] *= invLength;
604  }
605  return result;
606 }
607 
608 template <int N, typename Real>
609 bool ComputeExtremes(int numVectors, Vector<N, Real> const* v,
610  Vector<N, Real>& vmin, Vector<N, Real>& vmax)
611 {
612  if (v && numVectors > 0)
613  {
614  vmin = v[0];
615  vmax = vmin;
616  for (int j = 1; j < numVectors; ++j)
617  {
618  Vector<N, Real> const& vec = v[j];
619  for (int i = 0; i < N; ++i)
620  {
621  if (vec[i] < vmin[i])
622  {
623  vmin[i] = vec[i];
624  }
625  else if (vec[i] > vmax[i])
626  {
627  vmax[i] = vec[i];
628  }
629  }
630  }
631  return true;
632  }
633 
634  return false;
635 }
636 
637 template <int N, typename Real>
639 {
641  for (int i = 0; i < N; ++i)
642  {
643  result[i] = v[i];
644  }
645  result[N] = last;
646  return result;
647 }
648 
649 template <int N, typename Real>
650 Vector<N - 1, Real> HProject(Vector<N, Real> const& v)
651 {
652  static_assert(N >= 2, "Invalid dimension.");
653  Vector<N - 1, Real> result;
654  for (int i = 0; i < N - 1; ++i)
655  {
656  result[i] = v[i];
657  }
658  return result;
659 }
660 
661 template <int N, typename Real>
662 Vector<N + 1, Real> Lift(Vector<N, Real> const& v, int inject, Real value)
663 {
665  int i;
666  for (i = 0; i < inject; ++i)
667  {
668  result[i] = v[i];
669  }
670  result[i] = value;
671  int j = i;
672  for (++j; i < N; ++i, ++j)
673  {
674  result[j] = v[i];
675  }
676  return result;
677 }
678 
679 template <int N, typename Real>
680 Vector<N - 1, Real> Project(Vector<N, Real> const& v, int reject)
681 {
682  static_assert(N >= 2, "Invalid dimension.");
683  Vector<N - 1, Real> result;
684  for (int i = 0, j = 0; i < N - 1; ++i, ++j)
685  {
686  if (j == reject)
687  {
688  ++j;
689  }
690  result[i] = v[j];
691  }
692  return result;
693 }
694 
695 }
void MakeZero()
Definition: GteVector.h:279
bool operator>=(Vector const &vec) const
Definition: GteVector.h:273
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
GVector< Real > Project(GVector< Real > const &v, int reject)
Definition: GteGVector.h:625
DualQuaternion< Real > & operator*=(DualQuaternion< Real > &d, Real scalar)
bool operator>(Vector const &vec) const
Definition: GteVector.h:267
GLfloat GLfloat v1
Definition: glcorearb.h:812
GLsizei const GLfloat * value
Definition: glcorearb.h:819
bool operator<=(Vector const &vec) const
Definition: GteVector.h:261
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1597
Vector< N, Real > GetOrthogonal(Vector< N, Real > const &v, bool unitLength)
Definition: GteVector.h:574
GVector< Real > HLift(GVector< Real > const &v, Real last)
Definition: GteGVector.h:574
const GLubyte * c
Definition: glext.h:11671
DualQuaternion< Real > operator+(DualQuaternion< Real > const &d)
GVector< Real > HProject(GVector< Real > const &v)
Definition: GteGVector.h:587
std::array< Real, N > mTuple
Definition: GteVector.h:69
bool operator==(Vector const &vec) const
Definition: GteVector.h:243
static Vector Zero()
Definition: GteVector.h:295
DualQuaternion< Real > & operator-=(DualQuaternion< Real > &d0, DualQuaternion< Real > const &d1)
int GetSize() const
Definition: GteVector.h:225
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real Orthonormalize(int numElements, GVector< Real > *v, bool robust=false)
Definition: GteGVector.h:505
Real Normalize(GVector< Real > &v, bool robust=false)
Definition: GteGVector.h:454
GLfloat v0
Definition: glcorearb.h:811
GVector< Real > Lift(GVector< Real > const &v, int inject, Real value)
Definition: GteGVector.h:606
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:790
Real const & operator[](int i) const
Definition: GteVector.h:231
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
bool operator<(Vector const &vec) const
Definition: GteVector.h:255
const GLdouble * v
Definition: glcorearb.h:832
bool operator!=(Vector const &vec) const
Definition: GteVector.h:249
DualQuaternion< Real > operator-(DualQuaternion< Real > const &d)
DualQuaternion< Real > & operator+=(DualQuaternion< Real > &d0, DualQuaternion< Real > const &d1)
DualQuaternion< Real > & operator/=(DualQuaternion< Real > &d, Real scalar)
bool ComputeExtremes(int numVectors, GVector< Real > const *v, GVector< Real > &vmin, GVector< Real > &vmax)
Definition: GteGVector.h:537
Vector4< float > operator*(Transform const &M, Vector4< float > const &V)
void MakeUnit(int d)
Definition: GteVector.h:285
GLuint64EXT * result
Definition: glext.h:10003
static Vector Unit(int d)
Definition: GteVector.h:303
DualQuaternion< Real > operator/(DualQuaternion< Real > const &d, Real scalar)


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01