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