OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
VectorT_inc.hh
1 /*===========================================================================*\
2 * *
3 * OpenMesh *
4 * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
5 * www.openmesh.org *
6 * *
7 *---------------------------------------------------------------------------*
8 * This file is part of OpenMesh. *
9 * *
10 * OpenMesh is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenMesh is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenMesh. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34
35 /*===========================================================================*\
36 * *
37 * $Revision: 775 $ *
38 * $Date: 2012-12-05 18:59:57 +0100 (Mi, 05 Dez 2012) $ *
39 * *
40 \*===========================================================================*/
41
42 // Set template keywords and class names properly when
43 // parsing with doxygen. This only seems to work this way since
44 // the scope of preprocessor defines is limited to one file in doxy.
45 #ifdef DOXYGEN
46
47 // Only used for correct doxygen parsing
48 #define OPENMESH_VECTOR_HH
49
50 #define DIM N
51 #define TEMPLATE_HEADER template <typename Scalar, int N>
52 #define CLASSNAME VectorT
53 #define DERIVED VectorDataT<Scalar,N>
54 #define unroll(expr) for (int i=0; i<N; ++i) expr(i)
55
56 #endif
57
58 #if defined( OPENMESH_VECTOR_HH )
59
60 // ----------------------------------------------------------------------------
61
62 TEMPLATE_HEADER
63 class CLASSNAME : public DERIVED
64 {
65 private:
66 typedef DERIVED Base;
67 public:
68
69 //---------------------------------------------------------------- class info
70
72 typedef Scalar value_type;
73
75 typedef VectorT<Scalar,DIM> vector_type;
76
78 static inline int dim() { return DIM; }
79
81 static inline size_t size() { return DIM; }
82
83 static const size_t size_ = DIM;
84
85
86 //-------------------------------------------------------------- constructors
87
89 inline VectorT() {}
90
92 explicit inline VectorT(const Scalar& v) {
93 // assert(DIM==1);
94 // values_[0] = v0;
95 vectorize(v);
96 }
97
99 inline VectorT(const Scalar& v0, const Scalar& v1) {
100 assert(DIM==2);
101 Base::values_[0] = v0; Base::values_[1] = v1;
102 }
103
105 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2) {
106 assert(DIM==3);
107 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
108 }
109
111 inline VectorT(const Scalar& v0, const Scalar& v1,
112 const Scalar& v2, const Scalar& v3) {
113 assert(DIM==4);
114 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
115 }
116
118 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
119 const Scalar& v3, const Scalar& v4) {
120 assert(DIM==5);
121 Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
122 }
123
125 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
126 const Scalar& v3, const Scalar& v4, const Scalar& v5) {
127 assert(DIM==6);
128 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
129 Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
130 }
131
133 explicit inline VectorT(const Scalar _values[DIM]) {
134 memcpy(Base::values_, _values, DIM*sizeof(Scalar));
135 }
136
137
138 #ifdef OM_CC_MIPS
139
140 // mipspro need this method
141 inline vector_type& operator=(const vector_type& _rhs) {
142 memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
143 return *this;
144 }
145 #endif
146
147
149 template<typename otherScalarType>
150 explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
151 operator=(_rhs);
152 }
153
154
155
156
157 //--------------------------------------------------------------------- casts
158
160 template<typename otherScalarType>
161 inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
162 #define expr(i) Base::values_[i] = (Scalar)_rhs[i];
163 unroll(expr);
164 #undef expr
165 return *this;
166 }
167
168 // /// cast to Scalar array
169 // inline operator Scalar*() { return Base::values_; }
170
171 // /// cast to const Scalar array
172 // inline operator const Scalar*() const { return Base::values_; }
173
175 inline Scalar* data() { return Base::values_; }
176
178 inline const Scalar*data() const { return Base::values_; }
179
180
181
182
183 //----------------------------------------------------------- element access
184
185 // /// get i'th element read-write
186 // inline Scalar& operator[](int _i) {
187 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
188 // }
189
190 // /// get i'th element read-only
191 // inline const Scalar& operator[](int _i) const {
192 // assert(_i>=0 && _i<DIM); return Base::values_[_i];
193 // }
194
196 inline Scalar& operator[](size_t _i) {
197 assert(_i<DIM); return Base::values_[_i];
198 }
199
201 inline const Scalar& operator[](size_t _i) const {
202 assert(_i<DIM); return Base::values_[_i];
203 }
204
205
206
207
208 //---------------------------------------------------------------- comparsion
209
211 inline bool operator==(const vector_type& _rhs) const {
212 #define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
213 unroll(expr);
214 #undef expr
215 return true;
216 }
217
219 inline bool operator!=(const vector_type& _rhs) const {
220 return !(*this == _rhs);
221 }
222
223
224
225
226 //---------------------------------------------------------- scalar operators
227
229 inline vector_type& operator*=(const Scalar& _s) {
230 #define expr(i) Base::values_[i] *= _s;
231 unroll(expr);
232 #undef expr
233 return *this;
234 }
235
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
245
247 inline vector_type operator*(const Scalar& _s) const {
248 #if DIM==N
249 return vector_type(*this) *= _s;
250 #else
251 #define expr(i) Base::values_[i] * _s
252 return vector_type(unroll_csv(expr));
253 #undef expr
254 #endif
255 }
256
257
259 inline vector_type operator/(const Scalar& _s) const {
260 #if DIM==N
261 return vector_type(*this) /= _s;
262 #else
263 #define expr(i) Base::values_[i] / _s
264 return vector_type(unroll_csv(expr));
265 #undef expr
266 #endif
267 }
268
269
270
271
272
273
274 //---------------------------------------------------------- vector operators
275
277 inline vector_type& operator*=(const vector_type& _rhs) {
278 #define expr(i) Base::values_[i] *= _rhs[i];
279 unroll(expr);
280 #undef expr
281 return *this;
282 }
283
285 inline vector_type& operator/=(const vector_type& _rhs) {
286 #define expr(i) Base::values_[i] /= _rhs[i];
287 unroll(expr);
288 #undef expr
289 return *this;
290 }
291
293 inline vector_type& operator-=(const vector_type& _rhs) {
294 #define expr(i) Base::values_[i] -= _rhs[i];
295 unroll(expr);
296 #undef expr
297 return *this;
298 }
299
301 inline vector_type& operator+=(const vector_type& _rhs) {
302 #define expr(i) Base::values_[i] += _rhs[i];
303 unroll(expr);
304 #undef expr
305 return *this;
306 }
307
308
310 inline vector_type operator*(const vector_type& _v) const {
311 #if DIM==N
312 return vector_type(*this) *= _v;
313 #else
314 #define expr(i) Base::values_[i] * _v.Base::values_[i]
315 return vector_type(unroll_csv(expr));
316 #undef expr
317 #endif
318 }
319
320
322 inline vector_type operator/(const vector_type& _v) const {
323 #if DIM==N
324 return vector_type(*this) /= _v;
325 #else
326 #define expr(i) Base::values_[i] / _v.Base::values_[i]
327 return vector_type(unroll_csv(expr));
328 #undef expr
329 #endif
330 }
331
332
334 inline vector_type operator+(const vector_type& _v) const {
335 #if DIM==N
336 return vector_type(*this) += _v;
337 #else
338 #define expr(i) Base::values_[i] + _v.Base::values_[i]
339 return vector_type(unroll_csv(expr));
340 #undef expr
341 #endif
342 }
343
344
346 inline vector_type operator-(const vector_type& _v) const {
347 #if DIM==N
348 return vector_type(*this) -= _v;
349 #else
350 #define expr(i) Base::values_[i] - _v.Base::values_[i]
351 return vector_type(unroll_csv(expr));
352 #undef expr
353 #endif
354 }
355
356
358 inline vector_type operator-(void) const {
359 vector_type v;
360 #define expr(i) v.Base::values_[i] = -Base::values_[i];
361 unroll(expr);
362 #undef expr
363 return v;
364 }
365
366
369 inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
370 #if DIM==3
371 {
372 return
373 VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
374 Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
375 Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
376 }
377 #else
378 ;
379 #endif
380
381
384 inline Scalar operator|(const vector_type& _rhs) const {
385 Scalar p(0);
386 #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
387 unroll(expr);
388 #undef expr
389 return p;
390 }
391
392
393
394
395
396 //------------------------------------------------------------ euclidean norm
397
399
400
401 inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
402 inline Scalar length() const { return norm(); } // OpenSG interface
403
405 inline Scalar sqrnorm() const
406 {
407 #if DIM==N
408 Scalar s(0);
409 #define expr(i) s += Base::values_[i] * Base::values_[i];
410 unroll(expr);
411 #undef expr
412 return s;
413 #else
414 #define expr(i) Base::values_[i]*Base::values_[i]
415 return (unroll_comb(expr, +));
416 #undef expr
417 #endif
418 }
419
423 inline vector_type& normalize()
424 {
425 *this /= norm();
426 return *this;
427 }
428
432 inline const vector_type normalized() const
433 {
434 return *this / norm();
435 }
436
439 inline vector_type& normalize_cond()
440 {
441 Scalar n = norm();
442 if (n != (Scalar)0.0)
443 {
444 *this /= n;
445 }
446 return *this;
447 }
448
450
451 //------------------------------------------------------------ euclidean norm
452
454
455
457 inline Scalar l1_norm() const
458 {
459 #if DIM==N
460 Scalar s(0);
461 #define expr(i) s += std::abs(Base::values_[i]);
462 unroll(expr);
463 #undef expr
464 return s;
465 #else
466 #define expr(i) std::abs(Base::values_[i])
467 return (unroll_comb(expr, +));
468 #undef expr
469 #endif
470 }
471
473 inline Scalar l8_norm() const
474 {
475 return max_abs();
476 }
477
479
480 //------------------------------------------------------------ max, min, mean
481
483
484
486 inline Scalar max() const
487 {
488 Scalar m(Base::values_[0]);
489 for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
490 return m;
491 }
492
494 inline Scalar max_abs() const
495 {
496 Scalar m(std::abs(Base::values_[0]));
497 for(int i=1; i<DIM; ++i)
498 if(std::abs(Base::values_[i])>m)
499 m=std::abs(Base::values_[i]);
500 return m;
501 }
502
503
505 inline Scalar min() const
506 {
507 Scalar m(Base::values_[0]);
508 for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
509 return m;
510 }
511
513 inline Scalar min_abs() const
514 {
515 Scalar m(std::abs(Base::values_[0]));
516 for(int i=1; i<DIM; ++i)
517 if(std::abs(Base::values_[i])<m)
518 m=std::abs(Base::values_[i]);
519 return m;
520 }
521
523 inline Scalar mean() const {
524 Scalar m(Base::values_[0]);
525 for(int i=1; i<DIM; ++i) m+=Base::values_[i];
526 return m/Scalar(DIM);
527 }
528
530 inline Scalar mean_abs() const {
531 Scalar m(std::abs(Base::values_[0]));
532 for(int i=1; i<DIM; ++i) m+=std::abs(Base::values_[i]);
533 return m/Scalar(DIM);
534 }
535
536
538 inline vector_type minimize(const vector_type& _rhs) {
539 #define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
540 unroll(expr);
541 #undef expr
542 return *this;
543 }
544
546 inline bool minimized(const vector_type& _rhs) {
547 bool result(false);
548 #define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; }
549 unroll(expr);
550 #undef expr
551 return result;
552 }
553
555 inline vector_type maximize(const vector_type& _rhs) {
556 #define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
557 unroll(expr);
558 #undef expr
559 return *this;
560 }
561
563 inline bool maximized(const vector_type& _rhs) {
564 bool result(false);
565 #define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; }
566 unroll(expr);
567 #undef expr
568 return result;
569 }
570
572 inline vector_type min(const vector_type& _rhs) {
573 return vector_type(*this).minimize(_rhs);
574 }
575
577 inline vector_type max(const vector_type& _rhs) {
578 return vector_type(*this).maximize(_rhs);
579 }
580
582
583 //------------------------------------------------------------ misc functions
584
586 template<typename Functor>
587 inline vector_type apply(const Functor& _func) const {
588 vector_type result;
589 #define expr(i) result[i] = _func(Base::values_[i]);
590 unroll(expr);
591 #undef expr
592 return result;
593 }
594
596 vector_type& vectorize(const Scalar& _s) {
597 #define expr(i) Base::values_[i] = _s;
598 unroll(expr);
599 #undef expr
600 return *this;
601 }
602
603
605 static vector_type vectorized(const Scalar& _s) {
606 return vector_type().vectorize(_s);
607 }
608
609
611 bool operator<(const vector_type& _rhs) const {
612 #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
613 return (Base::values_[i] < _rhs.Base::values_[i]);
614 unroll(expr);
615 #undef expr
616 return false;
617 }
618 };
619
620
621
623 TEMPLATE_HEADER
624 inline std::istream&
625 operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
626 {
627 #define expr(i) is >> vec[i];
628 unroll(expr);
629 #undef expr
630 return is;
631 }
632
633
635 TEMPLATE_HEADER
636 inline std::ostream&
637 operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
638 {
639 #if DIM==N
640 for(int i=0; i<N-1; ++i) os << vec[i] << " ";
641 os << vec[N-1];
642 #else
643 #define expr(i) vec[i]
644 os << unroll_comb(expr, << " " <<);
645 #undef expr
646 #endif
647
648 return os;
649 }
650
651
652 // ----------------------------------------------------------------------------
653 #endif // included by VectorT.hh
654 //=============================================================================