Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Vector11T.hh
1 /* ========================================================================= *
2  * *
3  * OPENVOLUMEMESHMesh *
4  * Copyright (c) 2001-2016, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.OPENVOLUMEMESHmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OPENVOLUMEMESHMesh. *
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 #ifndef OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_
44 #define OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_
45 
46 #include <array>
47 #include <utility>
48 #include <algorithm>
49 #include <numeric>
50 #include <type_traits>
51 #include <cmath>
52 #include <ostream>
53 #include <istream>
54 #include <cassert>
55 #include <cstdlib>
56 
57 namespace OpenVolumeMesh {
58 
59 namespace Geometry {
60 
61 /*
62  * Helpers for VectorT
63  */
64 template<typename ... Ts>
66 
67 template<typename To, typename From, typename ... Froms>
68 struct are_convertible_to<To, From, Froms...> {
69  static constexpr bool value = std::is_convertible<From, To>::value
70  && are_convertible_to<To, Froms...>::value;
71 };
72 
73 template<typename To, typename From>
74 struct are_convertible_to<To, From> : public std::is_convertible<From, To> {
75 };
76 
77 template<typename Scalar, int DIM>
78 class VectorT {
79 
80  static_assert(DIM >= 1, "VectorT requires positive dimensionality.");
81 
82  private:
83  using container = std::array<Scalar, DIM>;
84  container values_;
85 
86  public:
87 
88  //---------------------------------------------------------------- class info
89 
91  typedef Scalar value_type;
92 
94  typedef VectorT<Scalar, DIM> vector_type;
95 
97  static constexpr int dim() {
98  return DIM;
99  }
100 
102  static constexpr size_t size() {
103  return DIM;
104  }
105 
106  static constexpr const size_t size_ = DIM;
107 
108  //-------------------------------------------------------------- constructors
109 
111  constexpr VectorT() {}
112 
116  explicit VectorT(const Scalar &v) {
117  vectorize(v);
118  }
119 
120  template<typename ... T,
121  typename = typename std::enable_if<sizeof...(T) == DIM>::type,
122  typename = typename std::enable_if<
124  constexpr VectorT(T... vs) : values_ { {static_cast<Scalar>(vs)...} } {
125  static_assert(sizeof...(T) == DIM,
126  "Invalid number of components specified in constructor.");
128  "Not all components are convertible to Scalar.");
129  }
130 
131  VectorT(const VectorT &rhs) = default;
132  VectorT(VectorT &&rhs) = default;
133  VectorT &operator=(const VectorT &rhs) = default;
134  VectorT &operator=(VectorT &&rhs) = default;
135 
140  template<typename S = Scalar, int D = DIM>
141  auto homogenized() const ->
142  typename std::enable_if<D == 4,
143  VectorT<decltype(std::declval<S>()/std::declval<S>()), DIM>>::type {
144  static_assert(D == DIM, "D and DIM need to be identical. (Never "
145  "override the default template arguments.)");
146  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
147  "to be the same type. (Never override the default template "
148  "arguments.)");
149  return VectorT(
150  values_[0]/values_[3],
151  values_[1]/values_[3],
152  values_[2]/values_[3],
153  1);
154  }
155 
157  template<typename Iterator,
158  typename = decltype(
159  *std::declval<Iterator&>(), void(),
160  ++std::declval<Iterator&>(), void())>
161  explicit VectorT(Iterator it) {
162  std::copy_n(it, DIM, values_.begin());
163  }
164 
166  template<typename otherScalarType,
167  typename = typename std::enable_if<
168  std::is_convertible<otherScalarType, Scalar>::value>>
169  explicit VectorT(const VectorT<otherScalarType, DIM>& _rhs) {
170  operator=(_rhs);
171  }
172 
173  //--------------------------------------------------------------------- casts
174 
176  template<typename OtherScalar,
177  typename = typename std::enable_if<
178  std::is_convertible<OtherScalar, Scalar>::value>>
179  vector_type& operator=(const VectorT<OtherScalar, DIM>& _rhs) {
180  std::transform(_rhs.data(), _rhs.data() + DIM,
181  data(), [](OtherScalar rhs) {
182  return static_cast<Scalar>(std::move(rhs));
183  });
184  return *this;
185  }
186 
188  Scalar* data() { return values_.data(); }
189 
191  const Scalar *data() const { return values_.data(); }
192 
193  //----------------------------------------------------------- element access
194 
196  Scalar& operator[](size_t _i) {
197  assert(_i < DIM);
198  return values_[_i];
199  }
200 
202  const Scalar& operator[](size_t _i) const {
203  assert(_i < DIM);
204  return values_[_i];
205  }
206 
207  //---------------------------------------------------------------- comparsion
208 
210  bool operator==(const vector_type& _rhs) const {
211  return std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
212  }
213 
215  bool operator!=(const vector_type& _rhs) const {
216  return !std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
217  }
218 
219  //---------------------------------------------------------- scalar operators
220 
222  template<typename OtherScalar>
223  auto operator*=(const OtherScalar& _s) ->
224  typename std::enable_if<std::is_convertible<
225  decltype(this->values_[0] * _s), Scalar>::value,
226  VectorT<Scalar, DIM>&>::type {
227  for (auto& e : *this) {
228  e *= _s;
229  }
230  return *this;
231  }
232 
234  template<typename OtherScalar>
235  auto operator/=(const OtherScalar& _s) ->
236  typename std::enable_if<std::is_convertible<
237  decltype(this->values_[0] / _s), Scalar>::value,
238  VectorT<Scalar, DIM>&>::type {
239  for (auto& e : *this) {
240  e /= _s;
241  }
242  return *this;
243  }
244 
246  template<typename OtherScalar>
247  typename std::enable_if<std::is_convertible<
248  decltype(std::declval<Scalar>() * std::declval<OtherScalar>()),
249  Scalar>::value,
250  VectorT<Scalar, DIM>>::type
251  operator*(const OtherScalar& _s) const {
252  return vector_type(*this) *= _s;
253  }
254 
256  template<typename OtherScalar>
257  typename std::enable_if<std::is_convertible<
258  decltype(std::declval<Scalar>() / std::declval<OtherScalar>()),
259  Scalar>::value,
260  VectorT<Scalar, DIM>>::type
261  operator/(const OtherScalar& _s) const {
262  return vector_type(*this) /= _s;
263  }
264 
265  //---------------------------------------------------------- vector operators
266 
268  template<typename OtherScalar>
269  auto operator*=(const VectorT<OtherScalar, DIM>& _rhs) ->
270  typename std::enable_if<
271  sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
272  vector_type&>::type {
273  for (int i = 0; i < DIM; ++i) {
274  data()[i] *= _rhs.data()[i];
275  }
276  return *this;
277  }
278 
280  template<typename OtherScalar>
281  auto operator/=(const VectorT<OtherScalar, DIM>& _rhs) ->
282  typename std::enable_if<
283  sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
284  vector_type&>::type {
285  for (int i = 0; i < DIM; ++i) {
286  data()[i] /= _rhs.data()[i];
287  }
288  return *this;
289  }
290 
292  template<typename OtherScalar>
293  auto operator-=(const VectorT<OtherScalar, DIM>& _rhs) ->
294  typename std::enable_if<
295  sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
296  vector_type&>::type {
297  for (int i = 0; i < DIM; ++i) {
298  data()[i] -= _rhs.data()[i];
299  }
300  return *this;
301  }
302 
304  template<typename OtherScalar>
305  auto operator+=(const VectorT<OtherScalar, DIM>& _rhs) ->
306  typename std::enable_if<
307  sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
308  vector_type&>::type {
309  for (int i = 0; i < DIM; ++i) {
310  data()[i] += _rhs.data()[i];
311  }
312  return *this;
313  }
314 
316  template<typename OtherScalar>
317  auto operator*(const VectorT<OtherScalar, DIM>& _rhs) const ->
318  typename std::enable_if<
319  sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
320  vector_type>::type {
321  return vector_type(*this) *= _rhs;
322  }
323 
325  template<typename OtherScalar>
326  auto operator/(const VectorT<OtherScalar, DIM>& _rhs) const ->
327  typename std::enable_if<
328  sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
329  vector_type>::type {
330  return vector_type(*this) /= _rhs;
331  }
332 
334  template<typename OtherScalar>
335  auto operator+(const VectorT<OtherScalar, DIM>& _rhs) const ->
336  typename std::enable_if<
337  sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
338  vector_type>::type {
339  return vector_type(*this) += _rhs;
340  }
341 
343  template<typename OtherScalar>
344  auto operator-(const VectorT<OtherScalar, DIM>& _rhs) const ->
345  typename std::enable_if<
346  sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
347  vector_type>::type {
348  return vector_type(*this) -= _rhs;
349  }
350 
352  vector_type operator-(void) const {
353  vector_type v;
354  std::transform(values_.begin(), values_.end(), v.values_.begin(),
355  [](const Scalar &s) { return -s; });
356  return v;
357  }
358 
361  template<typename OtherScalar>
362  auto operator% (const VectorT<OtherScalar, DIM> &_rhs) const ->
363  typename std::enable_if<DIM == 3,
364  VectorT<decltype(this->values_[0] * _rhs[0] -
365  this->values_[0] * _rhs[0]),
366  DIM>>::type {
367  return {
368  values_[1] * _rhs[2] - values_[2] * _rhs[1],
369  values_[2] * _rhs[0] - values_[0] * _rhs[2],
370  values_[0] * _rhs[1] - values_[1] * _rhs[0]
371  };
372  }
373 
376  template<typename OtherScalar>
377  auto operator|(const VectorT<OtherScalar, DIM>& _rhs) const ->
378  decltype(*this->data() * *_rhs.data()) {
379 
380  return std::inner_product(data() + 1, data() + DIM, _rhs.data() + 1,
381  *data() * *_rhs.data());
382  }
383 
384  //------------------------------------------------------------ euclidean norm
385 
387 
388 
390  template<typename S = Scalar>
391  decltype(std::declval<S>() * std::declval<S>()) sqrnorm() const {
392  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
393  "to be the same type. (Never override the default template "
394  "arguments.)");
395  typedef decltype(values_[0] * values_[0]) RESULT;
396  return std::accumulate(values_.cbegin() + 1, values_.cend(),
397  values_[0] * values_[0],
398  [](const RESULT &l, const Scalar &r) { return l + r * r; });
399  }
400 
402  template<typename S = Scalar>
403  auto norm() const ->
404  decltype(std::sqrt(std::declval<VectorT<S, DIM>>().sqrnorm())) {
405  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
406  "to be the same type. (Never override the default template "
407  "arguments.)");
408  return std::sqrt(sqrnorm());
409  }
410 
411  template<typename S = Scalar>
412  auto length() const ->
413  decltype(std::declval<VectorT<S, DIM>>().norm()) {
414  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
415  "to be the same type. (Never override the default template "
416  "arguments.)");
417  return norm();
418  }
419 
422  template<typename S = Scalar>
423  auto normalize() ->
424  decltype(*this /= std::declval<VectorT<S, DIM>>().norm()) {
425  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
426  "to be the same type. (Never override the default template "
427  "arguments.)");
428  return *this /= norm();
429  }
430 
433  template<typename S = Scalar>
434  auto normalized() const ->
435  decltype(*this / std::declval<VectorT<S, DIM>>().norm()) {
436  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
437  "to be the same type. (Never override the default template "
438  "arguments.)");
439  return *this / norm();
440  }
441 
444  template<typename S = Scalar>
445  typename std::enable_if<
446  sizeof(decltype(
447  static_cast<S>(0),
448  std::declval<VectorT<S, DIM>>().norm())) >= 0,
449  vector_type&>::type
450  normalize_cond() {
451  static_assert(std::is_same<S, Scalar>::value, "S and Scalar need "
452  "to be the same type. (Never override the default template "
453  "arguments.)");
454  auto n = norm();
455  if (n != static_cast<decltype(norm())>(0)) {
456  *this /= n;
457  }
458  return *this;
459  }
460 
462 
463  //------------------------------------------------------------ euclidean norm
464 
466 
467 
469  Scalar l1_norm() const {
470  return std::accumulate(
471  values_.cbegin() + 1, values_.cend(), values_[0]);
472  }
473 
475  Scalar l8_norm() const {
476  return max_abs();
477  }
478 
480 
481  //------------------------------------------------------------ max, min, mean
482 
484 
485 
487  Scalar max() const {
488  return *std::max_element(values_.cbegin(), values_.cend());
489  }
490 
492  Scalar max_abs() const {
493  return std::abs(
494  *std::max_element(values_.cbegin(), values_.cend(),
495  [](const Scalar &a, const Scalar &b) {
496  return std::abs(a) < std::abs(b);
497  }));
498  }
499 
501  Scalar min() const {
502  return *std::min_element(values_.cbegin(), values_.cend());
503  }
504 
506  Scalar min_abs() const {
507  return std::abs(
508  *std::min_element(values_.cbegin(), values_.cend(),
509  [](const Scalar &a, const Scalar &b) {
510  return std::abs(a) < std::abs(b);
511  }));
512  }
513 
515  Scalar mean() const {
516  return l1_norm()/DIM;
517  }
518 
520  Scalar mean_abs() const {
521  return std::accumulate(values_.cbegin() + 1, values_.cend(),
522  std::abs(values_[0]),
523  [](const Scalar &l, const Scalar &r) {
524  return l + std::abs(r);
525  }) / DIM;
526  }
527 
529  vector_type& minimize(const vector_type& _rhs) {
530  std::transform(values_.cbegin(), values_.cend(),
531  _rhs.values_.cbegin(),
532  values_.begin(),
533  [](const Scalar &l, const Scalar &r) {
534  return std::min(l, r);
535  });
536  return *this;
537  }
538 
540  bool minimized(const vector_type& _rhs) {
541  bool result = false;
542  std::transform(values_.cbegin(), values_.cend(),
543  _rhs.values_.cbegin(),
544  values_.begin(),
545  [&result](const Scalar &l, const Scalar &r) {
546  if (l < r) {
547  return l;
548  } else {
549  result = true;
550  return r;
551  }
552  });
553  return result;
554  }
555 
557  vector_type& maximize(const vector_type& _rhs) {
558  std::transform(values_.cbegin(), values_.cend(),
559  _rhs.values_.cbegin(),
560  values_.begin(),
561  [](const Scalar &l, const Scalar &r) {
562  return std::max(l, r);
563  });
564  return *this;
565  }
566 
568  bool maximized(const vector_type& _rhs) {
569  bool result = false;
570  std::transform(values_.cbegin(), values_.cend(),
571  _rhs.values_.cbegin(),
572  values_.begin(),
573  [&result](const Scalar &l, const Scalar &r) {
574  if (l > r) {
575  return l;
576  } else {
577  result = true;
578  return r;
579  }
580  });
581  return result;
582  }
583 
585  inline vector_type min(const vector_type& _rhs) const {
586  return vector_type(*this).minimize(_rhs);
587  }
588 
590  inline vector_type max(const vector_type& _rhs) const {
591  return vector_type(*this).maximize(_rhs);
592  }
593 
595 
596  //------------------------------------------------------------ misc functions
597 
599  template<typename Functor>
600  inline vector_type apply(const Functor& _func) const {
601  vector_type result;
602  std::transform(result.values_.begin(), result.values_.end(),
603  result.values_.begin(), _func);
604  return result;
605  }
606 
608  vector_type& vectorize(const Scalar& _s) {
609  std::fill(values_.begin(), values_.end(), _s);
610  return *this;
611  }
612 
614  static vector_type vectorized(const Scalar& _s) {
615  return vector_type().vectorize(_s);
616  }
617 
619  bool operator<(const vector_type& _rhs) const {
620  return std::lexicographical_compare(
621  values_.begin(), values_.end(),
622  _rhs.values_.begin(), _rhs.values_.end());
623  }
624 
626  void swap(VectorT& _other)
627  noexcept(noexcept(std::swap(values_, _other.values_))) {
628  std::swap(values_, _other.values_);
629  }
630 
631  //------------------------------------------------------------ component iterators
632 
634 
635 
636  using iterator = typename container::iterator;
637  using const_iterator = typename container::const_iterator;
638  using reverse_iterator = typename container::reverse_iterator;
639  using const_reverse_iterator = typename container::const_reverse_iterator;
640 
641  iterator begin() noexcept { return values_.begin(); }
642  const_iterator begin() const noexcept { return values_.cbegin(); }
643  const_iterator cbegin() const noexcept { return values_.cbegin(); }
644 
645  iterator end() noexcept { return values_.end(); }
646  const_iterator end() const noexcept { return values_.cend(); }
647  const_iterator cend() const noexcept { return values_.cend(); }
648 
649  reverse_iterator rbegin() noexcept { return values_.rbegin(); }
650  const_reverse_iterator rbegin() const noexcept { return values_.crbegin(); }
651  const_reverse_iterator crbegin() const noexcept { return values_.crbegin(); }
652 
653  reverse_iterator rend() noexcept { return values_.rend(); }
654  const_reverse_iterator rend() const noexcept { return values_.crend(); }
655  const_reverse_iterator crend() const noexcept { return values_.crend(); }
656 
658 };
659 
661 template<typename Scalar, int DIM, typename OtherScalar>
662 auto operator*(const OtherScalar& _s, const VectorT<Scalar, DIM> &rhs) ->
663  decltype(rhs.operator*(_s)) {
664 
665  return rhs * _s;
666 }
667 
669 template<typename Scalar, int DIM>
670 auto operator<<(std::ostream& os, const VectorT<Scalar, DIM> &_vec) ->
671  typename std::enable_if<
672  sizeof(decltype(os << _vec[0])) >= 0, std::ostream&>::type {
673 
674  os << _vec[0];
675  for (int i = 1; i < DIM; ++i) {
676  os << " " << _vec[i];
677  }
678  return os;
679 }
680 
682 template<typename Scalar, int DIM>
683 auto operator>> (std::istream& is, VectorT<Scalar, DIM> &_vec) ->
684  typename std::enable_if<
685  sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type {
686  for (int i = 0; i < DIM; ++i)
687  is >> _vec[i];
688  return is;
689 }
690 
693 template<typename Scalar, int DIM>
694 Scalar dot(const VectorT<Scalar, DIM>& _v1, const VectorT<Scalar, DIM>& _v2) {
695  return (_v1 | _v2);
696 }
697 
700 template<typename LScalar, typename RScalar, int DIM>
701 auto
702 cross(const VectorT<LScalar, DIM>& _v1, const VectorT<RScalar, DIM>& _v2) ->
703  decltype(_v1 % _v2) {
704  return (_v1 % _v2);
705 }
706 
709 template<typename Scalar, int DIM>
710 void swap(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2)
711 noexcept(noexcept(_v1.swap(_v2))) {
712  _v1.swap(_v2);
713 }
714 
715 //== TYPEDEFS =================================================================
716 
730 typedef VectorT<float,1> Vec1f;
732 typedef VectorT<double,1> Vec1d;
733 
747 typedef VectorT<float,2> Vec2f;
749 typedef VectorT<double,2> Vec2d;
750 
764 typedef VectorT<float,3> Vec3f;
766 typedef VectorT<double,3> Vec3d;
768 typedef VectorT<bool,3> Vec3b;
769 
783 typedef VectorT<float,4> Vec4f;
785 typedef VectorT<double,4> Vec4d;
786 
800 typedef VectorT<float, 5> Vec5f;
802 typedef VectorT<double, 5> Vec5d;
803 
817 typedef VectorT<float,6> Vec6f;
819 typedef VectorT<double,6> Vec6d;
820 
821 
822 } // namespace Geometry
823 
824 using namespace Geometry;
825 
826 template <class T>
827 const std::string typeName();
828 
829 template <> const std::string typeName<Vec2f>();
830 template <> const std::string typeName<Vec2d>();
831 template <> const std::string typeName<Vec2i>();
832 template <> const std::string typeName<Vec2ui>();
833 
834 template <> const std::string typeName<Vec3f>();
835 template <> const std::string typeName<Vec3d>();
836 template <> const std::string typeName<Vec3i>();
837 template <> const std::string typeName<Vec3ui>();
838 
839 template <> const std::string typeName<Vec4f>();
840 template <> const std::string typeName<Vec4d>();
841 template <> const std::string typeName<Vec4i>();
842 template <> const std::string typeName<Vec4ui>();
843 
844 } // namespace OpenVolumeMesh
845 
846 
847 #endif /* OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_ */
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:165