42 #ifndef OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_
43 #define OPENMESH_SRC_OPENMESH_CORE_GEOMETRY_VECTOR11T_HH_
49 #include <type_traits>
66 template<
typename ... Ts>
67 struct are_convertible_to;
69 template<
typename To,
typename From,
typename ... Froms>
70 struct are_convertible_to<To, From, Froms...> {
71 static constexpr
bool value = std::is_convertible<From, To>::value
72 && are_convertible_to<To, Froms...>::value;
75 template<
typename To,
typename From>
76 struct are_convertible_to<To, From> :
public std::is_convertible<From, To> {
82 template<
typename Scalar,
int DIM>
85 static_assert(DIM >= 1,
"VectorT requires positive dimensionality.");
88 using container = std::array<Scalar, DIM>;
96 typedef Scalar value_type;
102 static constexpr
int dim() {
107 static constexpr
size_t size() {
111 static constexpr
const size_t size_ = DIM;
115 template<
typename ... T,
116 typename =
typename std::enable_if<
sizeof...(T) == DIM>::type,
117 typename =
typename std::enable_if<
118 are_convertible_to<Scalar, T...>::value>::type>
119 constexpr
VectorT(T... vs) : values_ { {
static_cast<Scalar
>(vs)...} } {
120 static_assert(
sizeof...(T) == DIM,
121 "Invalid number of components specified in constructor.");
122 static_assert(are_convertible_to<Scalar, T...>::value,
123 "Not all components are convertible to Scalar.");
132 explicit VectorT(
const Scalar &v) {
145 template<
typename S = Scalar,
int D = DIM>
146 auto homogenized()
const ->
147 typename std::enable_if<D == 4,
149 static_assert(D == DIM,
"D and DIM need to be identical. (Never "
150 "override the default template arguments.)");
151 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
152 "to be the same type. (Never override the default template "
155 values_[0]/values_[3],
156 values_[1]/values_[3],
157 values_[2]/values_[3],
162 template<
typename Iterator,
164 *std::declval<Iterator&>(),
void(),
165 ++std::declval<Iterator&>(),
void())>
166 explicit VectorT(Iterator it) {
167 std::copy_n(it, DIM, values_.begin());
171 template<
typename otherScalarType,
172 typename =
typename std::enable_if<
173 std::is_convertible<otherScalarType, Scalar>::value>>
181 template<
typename OtherScalar,
182 typename =
typename std::enable_if<
183 std::is_convertible<OtherScalar, Scalar>::value>>
185 std::transform(_rhs.data(), _rhs.data() + DIM,
186 data(), [](OtherScalar rhs) {
187 return static_cast<Scalar
>(std::move(rhs));
193 Scalar* data() {
return values_.data(); }
196 const Scalar *data()
const {
return values_.data(); }
201 Scalar& operator[](
size_t _i) {
207 const Scalar& operator[](
size_t _i)
const {
215 bool operator==(
const vector_type& _rhs)
const {
216 return std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
220 bool operator!=(
const vector_type& _rhs)
const {
221 return !std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
227 template<
typename OtherScalar>
228 auto operator*=(
const OtherScalar& _s) ->
229 typename std::enable_if<std::is_convertible<
230 decltype(this->values_[0] * _s), Scalar>::value,
232 for (
auto& e : *
this) {
239 template<
typename OtherScalar>
240 auto operator/=(
const OtherScalar& _s) ->
241 typename std::enable_if<std::is_convertible<
242 decltype(this->values_[0] / _s), Scalar>::value,
244 for (
auto& e : *
this) {
251 template<
typename OtherScalar>
252 typename std::enable_if<std::is_convertible<
253 decltype(std::declval<Scalar>() * std::declval<OtherScalar>()),
257 return vector_type(*
this) *= _s;
261 template<
typename OtherScalar>
262 typename std::enable_if<std::is_convertible<
263 decltype(std::declval<Scalar>() / std::declval<OtherScalar>()),
266 operator/(
const OtherScalar& _s)
const {
267 return vector_type(*
this) /= _s;
273 template<
typename OtherScalar>
275 typename std::enable_if<
276 sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
277 vector_type&>::type {
278 for (
int i = 0; i < DIM; ++i) {
279 data()[i] *= _rhs.data()[i];
285 template<
typename OtherScalar>
287 typename std::enable_if<
288 sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
289 vector_type&>::type {
290 for (
int i = 0; i < DIM; ++i) {
291 data()[i] /= _rhs.data()[i];
297 template<
typename OtherScalar>
299 typename std::enable_if<
300 sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
301 vector_type&>::type {
302 for (
int i = 0; i < DIM; ++i) {
303 data()[i] -= _rhs.data()[i];
309 template<
typename OtherScalar>
311 typename std::enable_if<
312 sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
313 vector_type&>::type {
314 for (
int i = 0; i < DIM; ++i) {
315 data()[i] += _rhs.data()[i];
321 template<
typename OtherScalar>
323 typename std::enable_if<
324 sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
326 return vector_type(*
this) *= _rhs;
330 template<
typename OtherScalar>
332 typename std::enable_if<
333 sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
335 return vector_type(*
this) /= _rhs;
339 template<
typename OtherScalar>
341 typename std::enable_if<
342 sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
344 return vector_type(*
this) += _rhs;
348 template<
typename OtherScalar>
350 typename std::enable_if<
351 sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
353 return vector_type(*
this) -= _rhs;
357 vector_type operator-(
void)
const {
359 std::transform(values_.begin(), values_.end(), v.values_.begin(),
360 [](
const Scalar &s) {
return -s; });
366 template<
typename OtherScalar>
368 typename std::enable_if<DIM == 3,
369 VectorT<decltype(this->values_[0] * _rhs[0] -
370 this->values_[0] * _rhs[0]),
373 values_[1] * _rhs[2] - values_[2] * _rhs[1],
374 values_[2] * _rhs[0] - values_[0] * _rhs[2],
375 values_[0] * _rhs[1] - values_[1] * _rhs[0]
381 template<
typename OtherScalar>
383 decltype(*this->data() * *_rhs.data()) {
385 return std::inner_product(data() + 1, data() + DIM, _rhs.data() + 1,
386 *data() * *_rhs.data());
395 template<
typename S = Scalar>
396 decltype(std::declval<S>() * std::declval<S>()) sqrnorm()
const {
397 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
398 "to be the same type. (Never override the default template "
400 typedef decltype(values_[0] * values_[0]) RESULT;
401 return std::accumulate(values_.cbegin() + 1, values_.cend(),
402 values_[0] * values_[0],
403 [](
const RESULT &l,
const Scalar &r) {
return l + r * r; });
407 template<
typename S = Scalar>
410 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
411 "to be the same type. (Never override the default template "
413 return std::sqrt(sqrnorm());
416 template<
typename S = Scalar>
417 auto length()
const ->
419 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
420 "to be the same type. (Never override the default template "
427 template<
typename S = Scalar>
430 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
431 "to be the same type. (Never override the default template "
433 return *
this /= norm();
438 template<
typename S = Scalar>
439 auto normalized()
const ->
441 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
442 "to be the same type. (Never override the default template "
444 return *
this / norm();
449 template<
typename S = Scalar>
450 typename std::enable_if<
456 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
457 "to be the same type. (Never override the default template "
460 if (n !=
static_cast<decltype(norm())
>(0)) {
474 Scalar l1_norm()
const {
475 return std::accumulate(
476 values_.cbegin() + 1, values_.cend(), values_[0]);
480 Scalar l8_norm()
const {
493 return *std::max_element(values_.cbegin(), values_.cend());
497 Scalar max_abs()
const {
499 *std::max_element(values_.cbegin(), values_.cend(),
500 [](
const Scalar &a,
const Scalar &b) {
501 return std::abs(a) < std::abs(b);
507 return *std::min_element(values_.cbegin(), values_.cend());
511 Scalar min_abs()
const {
513 *std::min_element(values_.cbegin(), values_.cend(),
514 [](
const Scalar &a,
const Scalar &b) {
515 return std::abs(a) < std::abs(b);
520 Scalar mean()
const {
521 return l1_norm()/DIM;
525 Scalar mean_abs()
const {
526 return std::accumulate(values_.cbegin() + 1, values_.cend(),
527 std::abs(values_[0]),
528 [](
const Scalar &l,
const Scalar &r) {
529 return l + std::abs(r);
534 vector_type& minimize(
const vector_type& _rhs) {
535 std::transform(values_.cbegin(), values_.cend(),
536 _rhs.values_.cbegin(),
538 [](
const Scalar &l,
const Scalar &r) {
539 return std::min(l, r);
545 bool minimized(
const vector_type& _rhs) {
547 std::transform(values_.cbegin(), values_.cend(),
548 _rhs.values_.cbegin(),
550 [&result](
const Scalar &l,
const Scalar &r) {
562 vector_type& maximize(
const vector_type& _rhs) {
563 std::transform(values_.cbegin(), values_.cend(),
564 _rhs.values_.cbegin(),
566 [](
const Scalar &l,
const Scalar &r) {
567 return std::max(l, r);
573 bool maximized(
const vector_type& _rhs) {
575 std::transform(values_.cbegin(), values_.cend(),
576 _rhs.values_.cbegin(),
578 [&result](
const Scalar &l,
const Scalar &r) {
590 inline vector_type min(
const vector_type& _rhs)
const {
591 return vector_type(*this).minimize(_rhs);
595 inline vector_type max(
const vector_type& _rhs)
const {
596 return vector_type(*this).maximize(_rhs);
604 template<
typename Functor>
605 inline vector_type apply(
const Functor& _func)
const {
607 std::transform(result.values_.begin(), result.values_.end(),
608 result.values_.begin(), _func);
613 vector_type& vectorize(
const Scalar& _s) {
614 std::fill(values_.begin(), values_.end(), _s);
619 static vector_type vectorized(
const Scalar& _s) {
620 return vector_type().vectorize(_s);
624 bool operator<(
const vector_type& _rhs)
const {
625 return std::lexicographical_compare(
626 values_.begin(), values_.end(),
627 _rhs.values_.begin(), _rhs.values_.end());
632 noexcept(noexcept(std::swap(values_, _other.values_))) {
633 std::swap(values_, _other.values_);
641 using iterator =
typename container::iterator;
642 using const_iterator =
typename container::const_iterator;
643 using reverse_iterator =
typename container::reverse_iterator;
644 using const_reverse_iterator =
typename container::const_reverse_iterator;
646 iterator begin() noexcept {
return values_.begin(); }
647 const_iterator begin()
const noexcept {
return values_.cbegin(); }
648 const_iterator cbegin()
const noexcept {
return values_.cbegin(); }
650 iterator end() noexcept {
return values_.end(); }
651 const_iterator end()
const noexcept {
return values_.cend(); }
652 const_iterator cend()
const noexcept {
return values_.cend(); }
654 reverse_iterator rbegin() noexcept {
return values_.rbegin(); }
655 const_reverse_iterator rbegin()
const noexcept {
return values_.crbegin(); }
656 const_reverse_iterator crbegin()
const noexcept {
return values_.crbegin(); }
658 reverse_iterator rend() noexcept {
return values_.rend(); }
659 const_reverse_iterator rend()
const noexcept {
return values_.crend(); }
660 const_reverse_iterator crend()
const noexcept {
return values_.crend(); }
666 template<
typename Scalar,
int DIM,
typename OtherScalar>
668 decltype(rhs.operator*(_s)) {
674 template<
typename Scalar,
int DIM>
675 auto operator<<(std::ostream& os, const VectorT<Scalar, DIM> &_vec) ->
676 typename std::enable_if<
677 sizeof(decltype(os << _vec[0])) >= 0, std::ostream&>::type {
680 for (
int i = 1; i < DIM; ++i) {
681 os <<
" " << _vec[i];
687 template<
typename Scalar,
int DIM>
689 typename std::enable_if<
690 sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type {
691 for (
int i = 0; i < DIM; ++i)
698 template<
typename Scalar,
int DIM>
705 template<
typename LScalar,
typename RScalar,
int DIM>
708 decltype(_v1 % _v2) {
714 template<
typename Scalar,
int DIM>
716 noexcept(noexcept(_v1.swap(_v2))) {
836 constexpr
OpenMesh::Vec4f operator"" _htmlColor(
unsigned long long raw_color) {
838 ((raw_color >> 24) & 0xFF) / 255.0f,
839 ((raw_color >> 16) & 0xFF) / 255.0f,
840 ((raw_color >> 8) & 0xFF) / 255.0f,
841 ((raw_color >> 0) & 0xFF) / 255.0f);
VectorT< double, 3 > Vec3d
VectorT< signed int, 2 > Vec2i
VectorT< unsigned char, 2 > Vec2uc
VectorT< signed short int, 4 > Vec4s
VectorT< float, 1 > Vec1f
VectorT< signed char, 2 > Vec2c
VectorT< signed int, 6 > Vec6i
VectorT< signed int, 3 > Vec3i
void swap(VectorT< Scalar, DIM > &_v1, VectorT< Scalar, DIM > &_v2) noexcept(noexcept(_v1.swap(_v2)))
VectorT< signed char, 1 > Vec1c
VectorT< signed int, 4 > Vec4i
VectorT< signed int, 1 > Vec1i
VectorT< unsigned char, 1 > Vec1uc
VectorT< unsigned int, 1 > Vec1ui
VectorT< double, 1 > Vec1d
VectorT< Scalar1, N > operator*(Scalar2 _s, const VectorT< Scalar1, N > &_v)
VectorT< unsigned short int, 6 > Vec6us
VectorT< unsigned int, 3 > Vec3ui
VectorT< double, 5 > Vec5d
VectorT< unsigned char, 6 > Vec6uc
auto operator>>(std::istream &is, VectorT< Scalar, DIM > &_vec) -> typename std::enable_if< sizeof(decltype(is >> _vec[0])) >=0
read the space-separated components of a vector from a stream
VectorT< unsigned short int, 1 > Vec1us
VectorT< unsigned char, 5 > Vec5uc
VectorT< signed int, 5 > Vec5i
VectorT< float, 2 > Vec2f
VectorT< unsigned int, 2 > Vec2ui
VectorT< signed short int, 2 > Vec2s
VectorT< unsigned int, 6 > Vec6ui
VectorT< signed short int, 6 > Vec6s
VectorT< signed short int, 3 > Vec3s
VectorT< signed char, 3 > Vec3c
auto cross(const VectorT< LScalar, DIM > &_v1, const VectorT< RScalar, DIM > &_v2) -> decltype(_v1%_v2)
Scalar dot(const VectorT< Scalar, DIM > &_v1, const VectorT< Scalar, DIM > &_v2)
VectorT< double, 4 > Vec4d
VectorT< unsigned char, 4 > Vec4uc
VectorT< float, 6 > Vec6f
VectorT< unsigned short int, 4 > Vec4us
VectorT< signed char, 5 > Vec5c
VectorT< unsigned char, 3 > Vec3uc
VectorT< unsigned int, 5 > Vec5ui
VectorT< signed char, 4 > Vec4c
VectorT< signed char, 6 > Vec6c
VectorT< double, 2 > Vec2d
VectorT< signed short int, 5 > Vec5s
VectorT< unsigned int, 4 > Vec4ui
VectorT< unsigned short int, 3 > Vec3us
VectorT< unsigned short int, 2 > Vec2us
VectorT< float, 3 > Vec3f
VectorT< float, 5 > Vec5f
VectorT< unsigned short int, 5 > Vec5us
VectorT< signed short int, 1 > Vec1s
VectorT< float, 4 > Vec4f
VectorT< double, 6 > Vec6d