Developer Documentation
VectorT_inc.hh
1 /* ========================================================================= *
2  * *
3  * OpenVolumeMesh *
4  * Copyright (c) 2001-2016, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openvolumemesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenVolumeMesh. *
11  * This file was originally taken from OpenMesh *
12  *---------------------------------------------------------------------------*
13  * *
14  * Redistribution and use in source and binary forms, with or without *
15  * modification, are permitted provided that the following conditions *
16  * are met: *
17  * *
18  * 1. Redistributions of source code must retain the above copyright notice, *
19  * this list of conditions and the following disclaimer. *
20  * *
21  * 2. Redistributions in binary form must reproduce the above copyright *
22  * notice, this list of conditions and the following disclaimer in the *
23  * documentation and/or other materials provided with the distribution. *
24  * *
25  * 3. Neither the name of the copyright holder nor the names of its *
26  * contributors may be used to endorse or promote products derived from *
27  * this software without specific prior written permission. *
28  * *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
32  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
33  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
34  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
35  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
36  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
37  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
38  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
39  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
40  * *
41  * ========================================================================= */
42 
43 
44 
45 /*===========================================================================*\
46  * *
47  * $Revision$ *
48  * $Date$ *
49  * *
50 \*===========================================================================*/
51 
52 // Set template keywords and class names properly when
53 // parsing with doxygen. This only seems to work this way since
54 // the scope of preprocessor defines is limited to one file in doxy.
55 #ifdef DOXYGEN
56 
57 // Only used for correct doxygen parsing
58 #define OPENVOLUMEMESH_VECTOR_HH
59 
60 #define DIM N
61 #define TEMPLATE_HEADER template <typename Scalar, int N>
62 #define CLASSNAME VectorT
63 #define DERIVED VectorDataT<Scalar,N>
64 #define unroll(expr) for (int i=0; i<N; ++i) expr(i)
65 
66 #endif
67 
68 #if defined( OPENVOLUMEMESH_VECTOR_HH )
69 
70 // ----------------------------------------------------------------------------
71 
72 TEMPLATE_HEADER
73 class CLASSNAME : public DERIVED
74 {
75 private:
76  typedef DERIVED Base;
77 public:
78 
79  //---------------------------------------------------------------- class info
80 
82  typedef Scalar value_type;
83 
85  typedef VectorT<Scalar,DIM> vector_type;
86 
88  static inline int dim() { return DIM; }
89 
91  static inline size_t size() { return DIM; }
92 
93  static const size_t size_ = DIM;
94 
95 
96  //-------------------------------------------------------------- constructors
97 
99  inline VectorT() {}
100 
102  explicit inline VectorT(const Scalar& v) {
103 // assert(DIM==1);
104 // values_[0] = v0;
105  vectorize(v);
106  }
107 
108 #if DIM == 2
109  inline VectorT(const Scalar v0, const Scalar v1) {
111  Base::values_[0] = v0; Base::values_[1] = v1;
112  }
113 #endif
114 
115 #if DIM == 3
116  inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2) {
118  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
119  }
120 #endif
121 
122 #if DIM == 4
123  inline VectorT(const Scalar v0, const Scalar v1,
125  const Scalar v2, const Scalar v3) {
126  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
127  }
128 
129  VectorT homogenized() const { return VectorT(Base::values_[0]/Base::values_[3], Base::values_[1]/Base::values_[3], Base::values_[2]/Base::values_[3], 1); }
130 #endif
131 
132 #if DIM == 5
133  inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2,
135  const Scalar v3, const Scalar v4) {
136  Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
137  }
138 #endif
139 
140 #if DIM == 6
141  inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2,
143  const Scalar v3, const Scalar v4, const Scalar v5) {
144  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
145  Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
146  }
147 #endif
148 
150  explicit inline VectorT(const Scalar _values[DIM]) {
151  memcpy(data(), _values, DIM*sizeof(Scalar));
152  }
153 
154 
155 #ifdef OM_CC_MIPS
156  // mipspro need this method
158  inline vector_type& operator=(const vector_type& _rhs) {
159  memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
160  return *this;
161  }
162 #endif
163 
164 
166  template<typename otherScalarType>
167  explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
168  operator=(_rhs);
169  }
170 
171 
172 
173 
174  //--------------------------------------------------------------------- casts
175 
177  template<typename otherScalarType>
178  inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
179 #define expr(i) Base::values_[i] = (Scalar)_rhs[i];
180  unroll(expr);
181 #undef expr
182  return *this;
183  }
184 
185 // /// cast to Scalar array
186 // inline operator Scalar*() { return Base::values_; }
187 
188 // /// cast to const Scalar array
189 // inline operator const Scalar*() const { return Base::values_; }
190 
192  inline Scalar* data() { return Base::values_; }
193 
195  inline const Scalar*data() const { return Base::values_; }
196 
197 
198  //----------------------------------------------------------- element access
199 
200 // /// get i'th element read-write
201 // inline Scalar& operator[](int _i) {
202 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
203 // }
204 
205 // /// get i'th element read-only
206 // inline const Scalar& operator[](int _i) const {
207 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
208 // }
209 
211  inline Scalar& operator[](size_t _i) {
212  assert(_i<DIM); return Base::values_[_i];
213  }
214 
216  inline const Scalar& operator[](size_t _i) const {
217  assert(_i<DIM); return Base::values_[_i];
218  }
219 
220 
221 
222 
223  //---------------------------------------------------------------- comparsion
224 
226  inline bool operator==(const vector_type& _rhs) const {
227 #define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
228  unroll(expr);
229 #undef expr
230  return true;
231  }
232 
234  inline bool operator!=(const vector_type& _rhs) const {
235  return !(*this == _rhs);
236  }
237 
238 
239 
240 
241  //---------------------------------------------------------- scalar operators
242 
244  inline vector_type& operator*=(const Scalar& _s) {
245 #define expr(i) Base::values_[i] *= _s;
246  unroll(expr);
247 #undef expr
248  return *this;
249  }
250 
253  inline vector_type& operator/=(const Scalar& _s) {
254 #define expr(i) Base::values_[i] /= _s;
255  unroll(expr);
256 #undef expr
257  return *this;
258  }
259 
260 
262  inline vector_type operator*(const Scalar& _s) const {
263 #if DIM==N
264  return vector_type(*this) *= _s;
265 #else
266 #define expr(i) Base::values_[i] * _s
267  return vector_type(unroll_csv(expr));
268 #undef expr
269 #endif
270  }
271 
272 
274  inline vector_type operator/(const Scalar& _s) const {
275 #if DIM==N
276  return vector_type(*this) /= _s;
277 #else
278 #define expr(i) Base::values_[i] / _s
279  return vector_type(unroll_csv(expr));
280 #undef expr
281 #endif
282  }
283 
284 
285 
286 
287 
288 
289  //---------------------------------------------------------- vector operators
290 
292  inline vector_type& operator*=(const vector_type& _rhs) {
293 #define expr(i) Base::values_[i] *= _rhs[i];
294  unroll(expr);
295 #undef expr
296  return *this;
297  }
298 
300  inline vector_type& operator/=(const vector_type& _rhs) {
301 #define expr(i) Base::values_[i] /= _rhs[i];
302  unroll(expr);
303 #undef expr
304  return *this;
305  }
306 
308  inline vector_type& operator-=(const vector_type& _rhs) {
309 #define expr(i) Base::values_[i] -= _rhs[i];
310  unroll(expr);
311 #undef expr
312  return *this;
313  }
314 
316  inline vector_type& operator+=(const vector_type& _rhs) {
317 #define expr(i) Base::values_[i] += _rhs[i];
318  unroll(expr);
319 #undef expr
320  return *this;
321  }
322 
323 
325  inline vector_type operator*(const vector_type& _v) const {
326 #if DIM==N
327  return vector_type(*this) *= _v;
328 #else
329 #define expr(i) Base::values_[i] * _v.Base::values_[i]
330  return vector_type(unroll_csv(expr));
331 #undef expr
332 #endif
333  }
334 
335 
337  inline vector_type operator/(const vector_type& _v) const {
338 #if DIM==N
339  return vector_type(*this) /= _v;
340 #else
341 #define expr(i) Base::values_[i] / _v.Base::values_[i]
342  return vector_type(unroll_csv(expr));
343 #undef expr
344 #endif
345  }
346 
347 
349  inline vector_type operator+(const vector_type& _v) const {
350 #if DIM==N
351  return vector_type(*this) += _v;
352 #else
353 #define expr(i) Base::values_[i] + _v.Base::values_[i]
354  return vector_type(unroll_csv(expr));
355 #undef expr
356 #endif
357  }
358 
359 
361  inline vector_type operator-(const vector_type& _v) const {
362 #if DIM==N
363  return vector_type(*this) -= _v;
364 #else
365 #define expr(i) Base::values_[i] - _v.Base::values_[i]
366  return vector_type(unroll_csv(expr));
367 #undef expr
368 #endif
369  }
370 
371 
373  inline vector_type operator-(void) const {
374  vector_type v;
375 #define expr(i) v.Base::values_[i] = -Base::values_[i];
376  unroll(expr);
377 #undef expr
378  return v;
379  }
380 
381 
384  inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
385 #if DIM==3
386  {
387  return
388  VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
389  Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
390  Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
391  }
392 #else
393  ;
394 #endif
395 
396 
399  inline Scalar operator|(const vector_type& _rhs) const {
400  Scalar p(0);
401 #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
402  unroll(expr);
403 #undef expr
404  return p;
405  }
406 
407 
408 
409 
410 
411  //------------------------------------------------------------ euclidean norm
412 
414 
415  inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
417  inline Scalar length() const { return norm(); } // OpenSG interface
418 
420  inline Scalar sqrnorm() const
421  {
422 #if DIM==N
423  Scalar s(0);
424 #define expr(i) s += Base::values_[i] * Base::values_[i];
425  unroll(expr);
426 #undef expr
427  return s;
428 #else
429 #define expr(i) Base::values_[i]*Base::values_[i]
430  return (unroll_comb(expr, +));
431 #undef expr
432 #endif
433  }
434 
438  inline vector_type& normalize()
439  {
440  *this /= norm();
441  return *this;
442  }
443 
447  inline const vector_type normalized() const
448  {
449  return *this / norm();
450  }
451 
454  inline vector_type& normalize_cond()
455  {
456  Scalar n = norm();
457  if (n != (Scalar)0.0)
458  {
459  *this /= n;
460  }
461  return *this;
462  }
463 
465 
466  //------------------------------------------------------------ euclidean norm
467 
469 
470 
472  inline Scalar l1_norm() const
473  {
474 #if DIM==N
475  Scalar s(0);
476 #define expr(i) s += std::abs(Base::values_[i]);
477  unroll(expr);
478 #undef expr
479  return s;
480 #else
481 #define expr(i) std::abs(Base::values_[i])
482  return (unroll_comb(expr, +));
483 #undef expr
484 #endif
485  }
486 
488  inline Scalar l8_norm() const
489  {
490  return max_abs();
491  }
492 
494 
495  //------------------------------------------------------------ max, min, mean
496 
498 
499 
501  inline Scalar max() const
502  {
503  Scalar m(Base::values_[0]);
504  for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
505  return m;
506  }
507 
509  inline Scalar max_abs() const
510  {
511  Scalar m(std::abs(Base::values_[0]));
512  for(int i=1; i<DIM; ++i)
513  if(std::abs(Base::values_[i])>m)
514  m=std::abs(Base::values_[i]);
515  return m;
516  }
517 
518 
520  inline Scalar min() const
521  {
522  Scalar m(Base::values_[0]);
523  for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
524  return m;
525  }
526 
528  inline Scalar min_abs() const
529  {
530  Scalar m(std::abs(Base::values_[0]));
531  for(int i=1; i<DIM; ++i)
532  if(std::abs(Base::values_[i])<m)
533  m=std::abs(Base::values_[i]);
534  return m;
535  }
536 
538  inline Scalar mean() const {
539  Scalar m(Base::values_[0]);
540  for(int i=1; i<DIM; ++i) m+=Base::values_[i];
541  return m/Scalar(DIM);
542  }
543 
545  inline Scalar mean_abs() const {
546  Scalar m(std::abs(Base::values_[0]));
547  for(int i=1; i<DIM; ++i) m+=std::abs(Base::values_[i]);
548  return m/Scalar(DIM);
549  }
550 
551 
553  inline vector_type& minimize(const vector_type& _rhs) {
554 #define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
555  unroll(expr);
556 #undef expr
557  return *this;
558  }
559 
561  inline bool minimized(const vector_type& _rhs) {
562  bool result(false);
563 #define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; }
564  unroll(expr);
565 #undef expr
566  return result;
567  }
568 
570  inline vector_type& maximize(const vector_type& _rhs) {
571 #define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
572  unroll(expr);
573 #undef expr
574  return *this;
575  }
576 
578  inline bool maximized(const vector_type& _rhs) {
579  bool result(false);
580 #define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; }
581  unroll(expr);
582 #undef expr
583  return result;
584  }
585 
587  inline vector_type min(const vector_type& _rhs) const {
588  return vector_type(*this).minimize(_rhs);
589  }
590 
592  inline vector_type max(const vector_type& _rhs) const {
593  return vector_type(*this).maximize(_rhs);
594  }
595 
597 
598  //------------------------------------------------------------ misc functions
599 
601  template<typename Functor>
602  inline vector_type apply(const Functor& _func) const {
603  vector_type result;
604 #define expr(i) result[i] = _func(Base::values_[i]);
605  unroll(expr);
606 #undef expr
607  return result;
608  }
609 
611  vector_type& vectorize(const Scalar& _s) {
612 #define expr(i) Base::values_[i] = _s;
613  unroll(expr);
614 #undef expr
615  return *this;
616  }
617 
618 
620  static vector_type vectorized(const Scalar& _s) {
621  return vector_type().vectorize(_s);
622  }
623 
624 
626  bool operator<(const vector_type& _rhs) const {
627 #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
628  return (Base::values_[i] < _rhs.Base::values_[i]);
629  unroll(expr);
630 #undef expr
631  return false;
632  }
633 };
634 
635 
636 
638 TEMPLATE_HEADER
639 inline std::istream&
640 operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
641 {
642 #define expr(i) is >> vec[i];
643  unroll(expr);
644 #undef expr
645  return is;
646 }
647 
648 
650 TEMPLATE_HEADER
651 inline std::ostream&
652 operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
653 {
654 #if DIM==N
655  for(int i=0; i<N-1; ++i) os << vec[i] << " ";
656  os << vec[N-1];
657 #else
658 #define expr(i) vec[i]
659  os << unroll_comb(expr, << " " <<);
660 #undef expr
661 #endif
662 
663  return os;
664 }
665 
666 
667 // ----------------------------------------------------------------------------
668 #endif // included by VectorT.hh
669 //=============================================================================
auto operator*(const OtherScalar &_s, const VectorT< Scalar, DIM > &rhs) -> decltype(rhs.operator*(_s))
Component wise multiplication from the left.
Definition: Vector11T.hh:667
std::istream & operator>>(std::istream &is, Matrix4x4T< Scalar > &m)
read the space-separated components of a vector from a stream */
Definition: Matrix4x4T.hh:301