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 // Set template keywords and class names properly when
47 // parsing with doxygen. This only seems to work this way since
48 // the scope of preprocessor defines is limited to one file in doxy.
49 #ifdef DOXYGEN
50 
51 // Only used for correct doxygen parsing
52 #define OPENMESH_VECTOR_HH
53 
54 #define DIM N
55 #define TEMPLATE_HEADER template <typename Scalar, int N>
56 #define CLASSNAME VectorT
57 #define DERIVED VectorDataT<Scalar,N>
58 #define unroll(expr) for (int i=0; i<N; ++i) expr(i)
59 
60 #endif
61 
62 #if defined( OPENMESH_VECTOR_HH )
63 
64 // ----------------------------------------------------------------------------
65 
66 TEMPLATE_HEADER
67 class CLASSNAME : public DERIVED
68 {
69 private:
70  typedef DERIVED Base;
71 public:
72 
73  //---------------------------------------------------------------- class info
74 
76  typedef Scalar value_type;
77 
79  typedef VectorT<Scalar,DIM> vector_type;
80 
82  static inline int dim() { return DIM; }
83 
85  static inline size_t size() { return DIM; }
86 
87  static const size_t size_ = DIM;
88 
89 
90  //-------------------------------------------------------------- constructors
91 
93  inline VectorT() {}
94 
96  explicit inline VectorT(const Scalar& v) {
97 // assert(DIM==1);
98 // values_[0] = v0;
99  vectorize(v);
100  }
101 
102 #if DIM == 2
103  inline VectorT(const Scalar v0, const Scalar v1) {
105  Base::values_[0] = v0; Base::values_[1] = v1;
106  }
107 #endif
108 
109 #if DIM == 3
110  inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2) {
112  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
113  }
114 #endif
115 
116 #if DIM == 4
117  inline VectorT(const Scalar v0, const Scalar v1,
119  const Scalar v2, const Scalar v3) {
120  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
121  }
122 
123  VectorT homogenized() const { return VectorT(Base::values_[0]/Base::values_[3], Base::values_[1]/Base::values_[3], Base::values_[2]/Base::values_[3], 1); }
124 #endif
125 
126 #if DIM == 5
127  inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2,
129  const Scalar v3, const Scalar v4) {
130  Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
131  }
132 #endif
133 
134 #if DIM == 6
135  inline VectorT(const Scalar v0, const Scalar v1, const Scalar v2,
137  const Scalar v3, const Scalar v4, const Scalar v5) {
138  Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
139  Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
140  }
141 #endif
142 
144  explicit inline VectorT(const Scalar _values[DIM]) {
145  memcpy(data(), _values, DIM*sizeof(Scalar));
146  }
147 
148 
149 #ifdef OM_CC_MIPS
150  // mipspro need this method
152  inline vector_type& operator=(const vector_type& _rhs) {
153  memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
154  return *this;
155  }
156 #endif
157 
158 
160  template<typename otherScalarType>
161  explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
162  operator=(_rhs);
163  }
164 
165 
166 
167 
168  //--------------------------------------------------------------------- casts
169 
171  template<typename otherScalarType>
172  inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
173 #define expr(i) Base::values_[i] = (Scalar)_rhs[i];
174  unroll(expr);
175 #undef expr
176  return *this;
177  }
178 
179 // /// cast to Scalar array
180 // inline operator Scalar*() { return Base::values_; }
181 
182 // /// cast to const Scalar array
183 // inline operator const Scalar*() const { return Base::values_; }
184 
186  inline Scalar* data() { return Base::values_; }
187 
189  inline const Scalar*data() const { return Base::values_; }
190 
191 
192  //----------------------------------------------------------- element access
193 
194 // /// get i'th element read-write
195 // inline Scalar& operator[](int _i) {
196 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
197 // }
198 
199 // /// get i'th element read-only
200 // inline const Scalar& operator[](int _i) const {
201 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
202 // }
203 
205  inline Scalar& operator[](size_t _i) {
206  assert(_i<DIM); return Base::values_[_i];
207  }
208 
210  inline const Scalar& operator[](size_t _i) const {
211  assert(_i<DIM); return Base::values_[_i];
212  }
213 
214 
215 
216 
217  //---------------------------------------------------------------- comparsion
218 
220  inline bool operator==(const vector_type& _rhs) const {
221 #define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
222  unroll(expr);
223 #undef expr
224  return true;
225  }
226 
228  inline bool operator!=(const vector_type& _rhs) const {
229  return !(*this == _rhs);
230  }
231 
232 
233 
234 
235  //---------------------------------------------------------- scalar operators
236 
238  inline vector_type& operator*=(const Scalar& _s) {
239 #define expr(i) Base::values_[i] *= _s;
240  unroll(expr);
241 #undef expr
242  return *this;
243  }
244 
247  inline vector_type& operator/=(const Scalar& _s) {
248 #define expr(i) Base::values_[i] /= _s;
249  unroll(expr);
250 #undef expr
251  return *this;
252  }
253 
254 
256  inline vector_type operator*(const Scalar& _s) const {
257 #if DIM==N
258  return vector_type(*this) *= _s;
259 #else
260 #define expr(i) Base::values_[i] * _s
261  return vector_type(unroll_csv(expr));
262 #undef expr
263 #endif
264  }
265 
266 
268  inline vector_type operator/(const Scalar& _s) const {
269 #if DIM==N
270  return vector_type(*this) /= _s;
271 #else
272 #define expr(i) Base::values_[i] / _s
273  return vector_type(unroll_csv(expr));
274 #undef expr
275 #endif
276  }
277 
278 
279 
280 
281 
282 
283  //---------------------------------------------------------- vector operators
284 
286  inline vector_type& operator*=(const vector_type& _rhs) {
287 #define expr(i) Base::values_[i] *= _rhs[i];
288  unroll(expr);
289 #undef expr
290  return *this;
291  }
292 
294  inline vector_type& operator/=(const vector_type& _rhs) {
295 #define expr(i) Base::values_[i] /= _rhs[i];
296  unroll(expr);
297 #undef expr
298  return *this;
299  }
300 
302  inline vector_type& operator-=(const vector_type& _rhs) {
303 #define expr(i) Base::values_[i] -= _rhs[i];
304  unroll(expr);
305 #undef expr
306  return *this;
307  }
308 
310  inline vector_type& operator+=(const vector_type& _rhs) {
311 #define expr(i) Base::values_[i] += _rhs[i];
312  unroll(expr);
313 #undef expr
314  return *this;
315  }
316 
317 
319  inline vector_type operator*(const vector_type& _v) const {
320 #if DIM==N
321  return vector_type(*this) *= _v;
322 #else
323 #define expr(i) Base::values_[i] * _v.Base::values_[i]
324  return vector_type(unroll_csv(expr));
325 #undef expr
326 #endif
327  }
328 
329 
331  inline vector_type operator/(const vector_type& _v) const {
332 #if DIM==N
333  return vector_type(*this) /= _v;
334 #else
335 #define expr(i) Base::values_[i] / _v.Base::values_[i]
336  return vector_type(unroll_csv(expr));
337 #undef expr
338 #endif
339  }
340 
341 
343  inline vector_type operator+(const vector_type& _v) const {
344 #if DIM==N
345  return vector_type(*this) += _v;
346 #else
347 #define expr(i) Base::values_[i] + _v.Base::values_[i]
348  return vector_type(unroll_csv(expr));
349 #undef expr
350 #endif
351  }
352 
353 
355  inline vector_type operator-(const vector_type& _v) const {
356 #if DIM==N
357  return vector_type(*this) -= _v;
358 #else
359 #define expr(i) Base::values_[i] - _v.Base::values_[i]
360  return vector_type(unroll_csv(expr));
361 #undef expr
362 #endif
363  }
364 
365 
367  inline vector_type operator-(void) const {
368  vector_type v;
369 #define expr(i) v.Base::values_[i] = -Base::values_[i];
370  unroll(expr);
371 #undef expr
372  return v;
373  }
374 
375 
378  inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
379 #if DIM==3
380  {
381  return
382  VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
383  Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
384  Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
385  }
386 #else
387  ;
388 #endif
389 
390 
393  inline Scalar operator|(const vector_type& _rhs) const {
394  Scalar p(0);
395 #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
396  unroll(expr);
397 #undef expr
398  return p;
399  }
400 
401 
402 
403 
404 
405  //------------------------------------------------------------ euclidean norm
406 
408 
409  inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
411  inline Scalar length() const { return norm(); } // OpenSG interface
412 
414  inline Scalar sqrnorm() const
415  {
416 #if DIM==N
417  Scalar s(0);
418 #define expr(i) s += Base::values_[i] * Base::values_[i];
419  unroll(expr);
420 #undef expr
421  return s;
422 #else
423 #define expr(i) Base::values_[i]*Base::values_[i]
424  return (unroll_comb(expr, +));
425 #undef expr
426 #endif
427  }
428 
432  inline vector_type& normalize()
433  {
434  *this /= norm();
435  return *this;
436  }
437 
441  inline const vector_type normalized() const
442  {
443  return *this / norm();
444  }
445 
448  inline vector_type& normalize_cond()
449  {
450  Scalar n = norm();
451  if (n != (Scalar)0.0)
452  {
453  *this /= n;
454  }
455  return *this;
456  }
457 
459 
460  //------------------------------------------------------------ euclidean norm
461 
463 
464 
466  inline Scalar l1_norm() const
467  {
468 #if DIM==N
469  Scalar s(0);
470 #define expr(i) s += std::abs(Base::values_[i]);
471  unroll(expr);
472 #undef expr
473  return s;
474 #else
475 #define expr(i) std::abs(Base::values_[i])
476  return (unroll_comb(expr, +));
477 #undef expr
478 #endif
479  }
480 
482  inline Scalar l8_norm() const
483  {
484  return max_abs();
485  }
486 
488 
489  //------------------------------------------------------------ max, min, mean
490 
492 
493 
495  inline Scalar max() const
496  {
497  Scalar m(Base::values_[0]);
498  for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
499  return m;
500  }
501 
503  inline Scalar max_abs() const
504  {
505  Scalar m(std::abs(Base::values_[0]));
506  for(int i=1; i<DIM; ++i)
507  if(std::abs(Base::values_[i])>m)
508  m=std::abs(Base::values_[i]);
509  return m;
510  }
511 
512 
514  inline Scalar min() const
515  {
516  Scalar m(Base::values_[0]);
517  for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
518  return m;
519  }
520 
522  inline Scalar min_abs() const
523  {
524  Scalar m(std::abs(Base::values_[0]));
525  for(int i=1; i<DIM; ++i)
526  if(std::abs(Base::values_[i])<m)
527  m=std::abs(Base::values_[i]);
528  return m;
529  }
530 
532  inline Scalar mean() const {
533  Scalar m(Base::values_[0]);
534  for(int i=1; i<DIM; ++i) m+=Base::values_[i];
535  return m/Scalar(DIM);
536  }
537 
539  inline Scalar mean_abs() const {
540  Scalar m(std::abs(Base::values_[0]));
541  for(int i=1; i<DIM; ++i) m+=std::abs(Base::values_[i]);
542  return m/Scalar(DIM);
543  }
544 
545 
547  inline vector_type& minimize(const vector_type& _rhs) {
548 #define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
549  unroll(expr);
550 #undef expr
551  return *this;
552  }
553 
555  inline bool minimized(const vector_type& _rhs) {
556  bool result(false);
557 #define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; }
558  unroll(expr);
559 #undef expr
560  return result;
561  }
562 
564  inline vector_type& maximize(const vector_type& _rhs) {
565 #define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
566  unroll(expr);
567 #undef expr
568  return *this;
569  }
570 
572  inline bool maximized(const vector_type& _rhs) {
573  bool result(false);
574 #define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; }
575  unroll(expr);
576 #undef expr
577  return result;
578  }
579 
581  inline vector_type min(const vector_type& _rhs) const {
582  return vector_type(*this).minimize(_rhs);
583  }
584 
586  inline vector_type max(const vector_type& _rhs) const {
587  return vector_type(*this).maximize(_rhs);
588  }
589 
591 
592  //------------------------------------------------------------ misc functions
593 
595  template<typename Functor>
596  inline vector_type apply(const Functor& _func) const {
597  vector_type result;
598 #define expr(i) result[i] = _func(Base::values_[i]);
599  unroll(expr);
600 #undef expr
601  return result;
602  }
603 
605  vector_type& vectorize(const Scalar& _s) {
606 #define expr(i) Base::values_[i] = _s;
607  unroll(expr);
608 #undef expr
609  return *this;
610  }
611 
612 
614  static vector_type vectorized(const Scalar& _s) {
615  return vector_type().vectorize(_s);
616  }
617 
618 
620  bool operator<(const vector_type& _rhs) const {
621 #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
622  return (Base::values_[i] < _rhs.Base::values_[i]);
623  unroll(expr);
624 #undef expr
625  return false;
626  }
627 };
628 
629 
630 
632 TEMPLATE_HEADER
633 inline std::istream&
634 operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
635 {
636 #define expr(i) is >> vec[i];
637  unroll(expr);
638 #undef expr
639  return is;
640 }
641 
642 
644 TEMPLATE_HEADER
645 inline std::ostream&
646 operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
647 {
648 #if DIM==N
649  for(int i=0; i<N-1; ++i) os << vec[i] << " ";
650  os << vec[N-1];
651 #else
652 #define expr(i) vec[i]
653  os << unroll_comb(expr, << " " <<);
654 #undef expr
655 #endif
656 
657  return os;
658 }
659 
660 
661 // ----------------------------------------------------------------------------
662 #endif // included by VectorT.hh
663 //=============================================================================
std::istream & operator>>(std::istream &is, Matrix4x4T< Scalar > &m)
read the space-separated components of a vector from a stream */
Definition: Matrix4x4T.hh:295
auto operator*(const OtherScalar &_s, const VectorT< Scalar, DIM > &rhs) -> decltype(rhs.operator*(_s))
Component wise multiplication from the left.
Definition: Vector11T.hh:673