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 //=============================================================================
ACG::operator>>
std::istream & operator>>(std::istream &is, Matrix4x4T< Scalar > &m)
read the space-separated components of a vector from a stream */
Definition: Matrix4x4T.hh:295
VectorT
OpenMesh::operator*
auto operator*(const OtherScalar &_s, const VectorT< Scalar, DIM > &rhs) -> decltype(rhs.operator*(_s))
Component wise multiplication from the left.
Definition: Vector11T.hh:668