43 #ifndef OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_
44 #define OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_
50 #include <type_traits>
64 template<
typename ... Ts>
67 template<
typename To,
typename From,
typename ... Froms>
69 static constexpr
bool value = std::is_convertible<From, To>::value
73 template<
typename To,
typename From>
77 template<
typename Scalar,
int DIM>
80 static_assert(DIM >= 1,
"VectorT requires positive dimensionality.");
83 using container = std::array<Scalar, DIM>;
91 typedef Scalar value_type;
97 static constexpr
int dim() {
102 static constexpr
size_t size() {
106 static constexpr
const size_t size_ = DIM;
116 explicit VectorT(
const Scalar &v) {
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.");
140 template<
typename S = Scalar,
int D = DIM>
141 auto homogenized()
const ->
142 typename std::enable_if<D == 4,
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 "
150 values_[0]/values_[3],
151 values_[1]/values_[3],
152 values_[2]/values_[3],
157 template<
typename Iterator,
159 *std::declval<Iterator&>(),
void(),
160 ++std::declval<Iterator&>(),
void())>
161 explicit VectorT(Iterator it) {
162 std::copy_n(it, DIM, values_.begin());
166 template<
typename otherScalarType,
167 typename =
typename std::enable_if<
168 std::is_convertible<otherScalarType, Scalar>::value>>
176 template<
typename OtherScalar,
177 typename =
typename std::enable_if<
178 std::is_convertible<OtherScalar, Scalar>::value>>
180 std::transform(_rhs.data(), _rhs.data() + DIM,
181 data(), [](OtherScalar rhs) {
182 return static_cast<Scalar
>(std::move(rhs));
188 Scalar* data() {
return values_.data(); }
191 const Scalar *data()
const {
return values_.data(); }
196 Scalar& operator[](
size_t _i) {
202 const Scalar& operator[](
size_t _i)
const {
210 bool operator==(
const vector_type& _rhs)
const {
211 return std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
215 bool operator!=(
const vector_type& _rhs)
const {
216 return !std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
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,
227 for (
auto& e : *
this) {
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,
239 for (
auto& e : *
this) {
246 template<
typename OtherScalar>
247 typename std::enable_if<std::is_convertible<
248 decltype(std::declval<Scalar>() * std::declval<OtherScalar>()),
251 operator*(
const OtherScalar& _s)
const {
252 return vector_type(*
this) *= _s;
256 template<
typename OtherScalar>
257 typename std::enable_if<std::is_convertible<
258 decltype(std::declval<Scalar>() / std::declval<OtherScalar>()),
261 operator/(
const OtherScalar& _s)
const {
262 return vector_type(*
this) /= _s;
268 template<
typename OtherScalar>
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];
280 template<
typename OtherScalar>
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];
292 template<
typename OtherScalar>
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];
304 template<
typename OtherScalar>
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];
316 template<
typename OtherScalar>
318 typename std::enable_if<
319 sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0,
321 return vector_type(*
this) *= _rhs;
325 template<
typename OtherScalar>
327 typename std::enable_if<
328 sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0,
330 return vector_type(*
this) /= _rhs;
334 template<
typename OtherScalar>
336 typename std::enable_if<
337 sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0,
339 return vector_type(*
this) += _rhs;
343 template<
typename OtherScalar>
345 typename std::enable_if<
346 sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0,
348 return vector_type(*
this) -= _rhs;
352 vector_type operator-(
void)
const {
354 std::transform(values_.begin(), values_.end(), v.values_.begin(),
355 [](
const Scalar &s) {
return -s; });
361 template<
typename OtherScalar>
363 typename std::enable_if<DIM == 3,
364 VectorT<decltype(this->values_[0] * _rhs[0] -
365 this->values_[0] * _rhs[0]),
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]
376 template<
typename OtherScalar>
378 decltype(*this->data() * *_rhs.data()) {
380 return std::inner_product(data() + 1, data() + DIM, _rhs.data() + 1,
381 *data() * *_rhs.data());
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 "
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; });
402 template<
typename S = Scalar>
405 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
406 "to be the same type. (Never override the default template "
408 return std::sqrt(sqrnorm());
411 template<
typename S = Scalar>
412 auto length()
const ->
414 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
415 "to be the same type. (Never override the default template "
422 template<
typename S = Scalar>
425 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
426 "to be the same type. (Never override the default template "
428 return *
this /= norm();
433 template<
typename S = Scalar>
434 auto normalized()
const ->
436 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
437 "to be the same type. (Never override the default template "
439 return *
this / norm();
444 template<
typename S = Scalar>
445 typename std::enable_if<
451 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need "
452 "to be the same type. (Never override the default template "
455 if (n !=
static_cast<decltype(norm())
>(0)) {
469 Scalar l1_norm()
const {
470 return std::accumulate(
471 values_.cbegin() + 1, values_.cend(), values_[0]);
475 Scalar l8_norm()
const {
488 return *std::max_element(values_.cbegin(), values_.cend());
492 Scalar max_abs()
const {
494 *std::max_element(values_.cbegin(), values_.cend(),
495 [](
const Scalar &a,
const Scalar &b) {
496 return std::abs(a) < std::abs(b);
502 return *std::min_element(values_.cbegin(), values_.cend());
506 Scalar min_abs()
const {
508 *std::min_element(values_.cbegin(), values_.cend(),
509 [](
const Scalar &a,
const Scalar &b) {
510 return std::abs(a) < std::abs(b);
515 Scalar mean()
const {
516 return l1_norm()/DIM;
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);
529 vector_type& minimize(
const vector_type& _rhs) {
530 std::transform(values_.cbegin(), values_.cend(),
531 _rhs.values_.cbegin(),
533 [](
const Scalar &l,
const Scalar &r) {
534 return std::min(l, r);
540 bool minimized(
const vector_type& _rhs) {
542 std::transform(values_.cbegin(), values_.cend(),
543 _rhs.values_.cbegin(),
545 [&result](
const Scalar &l,
const Scalar &r) {
557 vector_type& maximize(
const vector_type& _rhs) {
558 std::transform(values_.cbegin(), values_.cend(),
559 _rhs.values_.cbegin(),
561 [](
const Scalar &l,
const Scalar &r) {
562 return std::max(l, r);
568 bool maximized(
const vector_type& _rhs) {
570 std::transform(values_.cbegin(), values_.cend(),
571 _rhs.values_.cbegin(),
573 [&result](
const Scalar &l,
const Scalar &r) {
585 inline vector_type min(
const vector_type& _rhs)
const {
586 return vector_type(*this).minimize(_rhs);
590 inline vector_type max(
const vector_type& _rhs)
const {
591 return vector_type(*this).maximize(_rhs);
599 template<
typename Functor>
600 inline vector_type apply(
const Functor& _func)
const {
602 std::transform(result.values_.begin(), result.values_.end(),
603 result.values_.begin(), _func);
608 vector_type& vectorize(
const Scalar& _s) {
609 std::fill(values_.begin(), values_.end(), _s);
614 static vector_type vectorized(
const Scalar& _s) {
615 return vector_type().vectorize(_s);
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());
627 noexcept(noexcept(std::swap(values_, _other.values_))) {
628 std::swap(values_, _other.values_);
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;
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(); }
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(); }
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(); }
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(); }
661 template<
typename Scalar,
int DIM,
typename OtherScalar>
663 decltype(rhs.operator*(_s)) {
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 {
675 for (
int i = 1; i < DIM; ++i) {
676 os <<
" " << _vec[i];
682 template<
typename Scalar,
int DIM>
684 typename std::enable_if<
685 sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type {
686 for (
int i = 0; i < DIM; ++i)
693 template<
typename Scalar,
int DIM>
700 template<
typename LScalar,
typename RScalar,
int DIM>
703 decltype(_v1 % _v2) {
709 template<
typename Scalar,
int DIM>
711 noexcept(noexcept(_v1.swap(_v2))) {
824 using namespace Geometry;
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>();
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>();
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>();
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.