43 #ifndef OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_ 44 #define OPENVOLUMEMESH_SRC_OPENVOLUMEMESH_GEOMETRY_VECTOR11T_HH_ 50 #include <type_traits> 57 #include "OpenVolumeMesh/Config/Export.hh" 66 template<
typename ... Ts>
69 template<
typename To,
typename From,
typename ... Froms>
71 static constexpr
bool value = std::is_convertible<From, To>::value
75 template<
typename To,
typename From>
79 template<
typename Scalar,
int DIM>
82 static_assert(DIM >= 1,
"VectorT requires positive dimensionality.");
85 using container = std::array<Scalar, DIM>;
99 static constexpr
int dim() {
104 static constexpr
size_t size() {
108 static constexpr
const size_t size_ = DIM;
122 template<
typename ... T,
123 typename =
typename std::enable_if<
sizeof...(T) == DIM>::type,
124 typename =
typename std::enable_if<
127 constexpr
VectorT(T... vs) : values_ { {
static_cast<Scalar
>(vs)...} }
129 static_assert(
sizeof...(T) == DIM,
130 "Invalid number of components specified in constructor.");
132 "Not all components are convertible to Scalar.");
144 template<
typename S = Scalar,
int D = DIM>
146 typename
std::enable_if<D == 4,
147 VectorT<decltype(
std::declval<S>()/
std::declval<S>()), DIM>>::type {
148 static_assert(D == DIM,
"D and DIM need to be identical. (Never " 149 "override the default template arguments.)");
150 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 151 "to be the same type. (Never override the default template " 154 values_[0]/values_[3],
155 values_[1]/values_[3],
156 values_[2]/values_[3],
161 template<
typename Iterator,
163 *std::declval<Iterator&>(),
void(),
164 ++std::declval<Iterator&>(),
void())>
166 std::copy_n(it, DIM, values_.begin());
170 template<
typename otherScalarType,
171 typename =
typename std::enable_if<
172 std::is_convertible<otherScalarType, Scalar>::value>>
180 template<
typename OtherScalar,
181 typename =
typename std::enable_if<
182 std::is_convertible<OtherScalar, Scalar>::value>>
186 std::transform(_rhs.
data(), _rhs.
data() + DIM,
187 data(), [](OtherScalar rhs) {
188 return static_cast<Scalar
>(std::move(rhs));
194 Scalar*
data() {
return values_.data(); }
197 const Scalar *
data()
const {
return values_.data(); }
217 return std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
222 return !std::equal(_rhs.values_.cbegin(), _rhs.values_.cend(), values_.cbegin());
228 template<
typename OtherScalar>
230 typename std::enable_if<std::is_convertible<
231 decltype(this->values_[0] * _s), Scalar>::value,
233 for (
auto& e : *
this) {
240 template<
typename OtherScalar>
242 typename std::enable_if<std::is_convertible<
243 decltype(this->values_[0] / _s), Scalar>::value,
245 for (
auto& e : *
this) {
252 template<
typename OtherScalar>
253 typename std::enable_if<std::is_convertible<
254 decltype(std::declval<Scalar>() * std::declval<OtherScalar>()),
258 return vector_type(*
this) *= _s;
262 template<
typename OtherScalar>
263 typename std::enable_if<std::is_convertible<
264 decltype(std::declval<Scalar>() / std::declval<OtherScalar>()),
268 return vector_type(*
this) /= _s;
274 template<
typename OtherScalar>
276 typename std::enable_if<
277 sizeof(decltype(this->values_[0] * *_rhs.
data())) >= 0,
278 vector_type&>::type {
279 for (
int i = 0; i < DIM; ++i) {
280 data()[i] *= _rhs.
data()[i];
286 template<
typename OtherScalar>
288 typename std::enable_if<
289 sizeof(decltype(this->values_[0] / *_rhs.
data())) >= 0,
290 vector_type&>::type {
291 for (
int i = 0; i < DIM; ++i) {
292 data()[i] /= _rhs.
data()[i];
298 template<
typename OtherScalar>
300 typename std::enable_if<
301 sizeof(decltype(this->values_[0] - *_rhs.
data())) >= 0,
302 vector_type&>::type {
303 for (
int i = 0; i < DIM; ++i) {
304 data()[i] -= _rhs.
data()[i];
310 template<
typename OtherScalar>
312 typename std::enable_if<
313 sizeof(decltype(this->values_[0] + *_rhs.
data())) >= 0,
314 vector_type&>::type {
315 for (
int i = 0; i < DIM; ++i) {
316 data()[i] += _rhs.
data()[i];
322 template<
typename OtherScalar>
324 typename std::enable_if<
325 sizeof(decltype(this->values_[0] * *_rhs.
data())) >= 0,
327 return vector_type(*
this) *= _rhs;
331 template<
typename OtherScalar>
333 typename std::enable_if<
334 sizeof(decltype(this->values_[0] / *_rhs.
data())) >= 0,
336 return vector_type(*
this) /= _rhs;
340 template<
typename OtherScalar>
342 typename std::enable_if<
343 sizeof(decltype(this->values_[0] + *_rhs.
data())) >= 0,
345 return vector_type(*
this) += _rhs;
349 template<
typename OtherScalar>
351 typename std::enable_if<
352 sizeof(decltype(this->values_[0] - *_rhs.
data())) >= 0,
354 return vector_type(*
this) -= _rhs;
360 std::transform(values_.begin(), values_.end(), v.values_.begin(),
361 [](
const Scalar &s) {
return -s; });
367 template<
typename OtherScalar>
369 typename std::enable_if<DIM == 3,
370 VectorT<decltype(this->values_[0] * _rhs[0] -
371 this->values_[0] * _rhs[0]),
374 values_[1] * _rhs[2] - values_[2] * _rhs[1],
375 values_[2] * _rhs[0] - values_[0] * _rhs[2],
376 values_[0] * _rhs[1] - values_[1] * _rhs[0]
382 template<
typename OtherScalar>
384 decltype(*
this % _rhs)
391 template<
typename OtherScalar>
393 decltype(*this->data() * *_rhs.
data()) {
395 return std::inner_product(data() + 1, data() + DIM, _rhs.
data() + 1,
396 *data() * *_rhs.
data());
401 template<
typename OtherScalar>
403 decltype(*
this | _rhs)
414 template<
typename S = Scalar>
415 decltype(std::declval<S>() * std::declval<S>()) sqrnorm()
const {
416 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 417 "to be the same type. (Never override the default template " 419 typedef decltype(values_[0] * values_[0]) RESULT;
420 return std::accumulate(values_.cbegin() + 1, values_.cend(),
421 values_[0] * values_[0],
422 [](
const RESULT &l,
const Scalar &r) {
return l + r * r; });
426 template<
typename S = Scalar>
428 decltype(
std::sqrt(
std::declval<
VectorT<S, DIM>>().sqrnorm())) {
429 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 430 "to be the same type. (Never override the default template " 432 return std::sqrt(sqrnorm());
435 template<
typename S = Scalar>
437 decltype(
std::declval<
VectorT<S, DIM>>().norm()) {
438 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 439 "to be the same type. (Never override the default template " 446 template<
typename S = Scalar>
449 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 450 "to be the same type. (Never override the default template " 452 return *
this /= norm();
457 template<
typename S = Scalar>
459 decltype(*this /
std::declval<
VectorT<S, DIM>>().norm()) {
460 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 461 "to be the same type. (Never override the default template " 463 return *
this / norm();
468 template<
typename S = Scalar>
469 typename std::enable_if<
475 static_assert(std::is_same<S, Scalar>::value,
"S and Scalar need " 476 "to be the same type. (Never override the default template " 479 if (n !=
static_cast<decltype(norm())
>(0)) {
494 return std::accumulate(
495 values_.cbegin() + 1, values_.cend(), values_[0]);
512 return *std::max_element(values_.cbegin(), values_.cend());
518 *std::max_element(values_.cbegin(), values_.cend(),
519 [](
const Scalar &a,
const Scalar &b) {
520 return std::abs(a) < std::abs(b);
526 return *std::min_element(values_.cbegin(), values_.cend());
532 *std::min_element(values_.cbegin(), values_.cend(),
533 [](
const Scalar &a,
const Scalar &b) {
534 return std::abs(a) < std::abs(b);
540 return l1_norm()/DIM;
545 return std::accumulate(values_.cbegin() + 1, values_.cend(),
546 std::abs(values_[0]),
547 [](
const Scalar &l,
const Scalar &r) {
548 return l + std::abs(r);
554 std::transform(values_.cbegin(), values_.cend(),
555 _rhs.values_.cbegin(),
557 [](
const Scalar &l,
const Scalar &r) {
558 return std::min(l, r);
566 std::transform(values_.cbegin(), values_.cend(),
567 _rhs.values_.cbegin(),
569 [&result](
const Scalar &l,
const Scalar &r) {
582 std::transform(values_.cbegin(), values_.cend(),
583 _rhs.values_.cbegin(),
585 [](
const Scalar &l,
const Scalar &r) {
586 return std::max(l, r);
594 std::transform(values_.cbegin(), values_.cend(),
595 _rhs.values_.cbegin(),
597 [&result](
const Scalar &l,
const Scalar &r) {
609 inline vector_type
min(
const vector_type& _rhs)
const {
610 return vector_type(*this).
minimize(_rhs);
614 inline vector_type
max(
const vector_type& _rhs)
const {
615 return vector_type(*this).
maximize(_rhs);
623 template<
typename Functor>
624 inline vector_type
apply(
const Functor& _func)
const {
626 std::transform(result.values_.begin(), result.values_.end(),
627 result.values_.begin(), _func);
633 std::fill(values_.begin(), values_.end(), _s);
644 return std::lexicographical_compare(
645 values_.begin(), values_.end(),
646 _rhs.values_.begin(), _rhs.values_.end());
651 noexcept(noexcept(std::swap(values_, _other.values_))) {
652 std::swap(values_, _other.values_);
660 using iterator =
typename container::iterator;
661 using const_iterator =
typename container::const_iterator;
662 using reverse_iterator =
typename container::reverse_iterator;
663 using const_reverse_iterator =
typename container::const_reverse_iterator;
665 iterator begin() noexcept {
return values_.begin(); }
666 const_iterator begin()
const noexcept {
return values_.cbegin(); }
667 const_iterator cbegin()
const noexcept {
return values_.cbegin(); }
669 iterator end() noexcept {
return values_.end(); }
670 const_iterator end()
const noexcept {
return values_.cend(); }
671 const_iterator cend()
const noexcept {
return values_.cend(); }
673 reverse_iterator rbegin() noexcept {
return values_.rbegin(); }
674 const_reverse_iterator rbegin()
const noexcept {
return values_.crbegin(); }
675 const_reverse_iterator crbegin()
const noexcept {
return values_.crbegin(); }
677 reverse_iterator rend() noexcept {
return values_.rend(); }
678 const_reverse_iterator rend()
const noexcept {
return values_.crend(); }
679 const_reverse_iterator crend()
const noexcept {
return values_.crend(); }
685 template<
typename Scalar,
int DIM,
typename OtherScalar>
687 decltype(rhs.operator*(_s)) {
693 template<
typename Scalar,
int DIM>
694 auto operator<<(std::ostream& os, const VectorT<Scalar, DIM> &_vec) ->
695 typename std::enable_if<
696 sizeof(decltype(os << _vec[0])) >= 0, std::ostream&>::type {
699 for (
size_t i = 1; i < DIM; ++i) {
700 os <<
" " << _vec[i];
706 template<
typename Scalar,
int DIM>
708 typename std::enable_if<
709 sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type {
710 for (
size_t i = 0; i < DIM; ++i)
717 template<
typename Scalar,
int DIM>
724 template<
typename LScalar,
typename RScalar,
int DIM>
727 decltype(_v1 % _v2) {
733 template<
typename Scalar,
int DIM>
735 noexcept(noexcept(_v1.
swap(_v2))) {
848 using namespace Geometry;
853 template <> OVM_EXPORT
const std::string typeName<Vec2f>();
854 template <> OVM_EXPORT
const std::string typeName<Vec2d>();
855 template <> OVM_EXPORT
const std::string typeName<Vec2i>();
856 template <> OVM_EXPORT
const std::string typeName<Vec2ui>();
858 template <> OVM_EXPORT
const std::string typeName<Vec3f>();
859 template <> OVM_EXPORT
const std::string typeName<Vec3d>();
860 template <> OVM_EXPORT
const std::string typeName<Vec3i>();
861 template <> OVM_EXPORT
const std::string typeName<Vec3ui>();
863 template <> OVM_EXPORT
const std::string typeName<Vec4f>();
864 template <> OVM_EXPORT
const std::string typeName<Vec4d>();
865 template <> OVM_EXPORT
const std::string typeName<Vec4i>();
866 template <> OVM_EXPORT
const std::string typeName<Vec4ui>();
static constexpr int dim()
returns dimension of the vector (deprecated)
auto dot(const VectorT< OtherScalar, DIM > &_rhs) const -> decltype(*this|_rhs)
static constexpr size_t size()
returns dimension of the vector
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
vector_type & vectorize(const Scalar &_s)
store the same value in each component (e.g. to clear all entries)
void swap(VectorT &_other) noexcept(noexcept(std::swap(values_, _other.values_)))
swap with another vector
VectorT(Iterator it)
construct from a value array or any other iterator
std::enable_if< std::is_convertible< decltype(std::declval< Scalar >)/std::declval< OtherScalar >)), Scalar >::value, VectorT< Scalar, DIM > >::type operator/(const OtherScalar &_s) const
component-wise division by with scalar
auto operator*=(const OtherScalar &_s) -> typename std::enable_if< std::is_convertible< decltype(this->values_[0] *_s), Scalar >::value, VectorT< Scalar, DIM > &>::type
component-wise self-multiplication with scalar
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Scalar * data()
access to Scalar array
auto cross(const VectorT< OtherScalar, DIM > &_rhs) const -> decltype(*this % _rhs)
std::enable_if< std::is_convertible< decltype(std::declval< Scalar >) *std::declval< OtherScalar >)), Scalar >::value, VectorT< Scalar, DIM > >::type operator*(const OtherScalar &_s) const
component-wise multiplication with scalar
vector_type operator-(void) const
unary minus
const Scalar & operator[](size_t _i) const
get i'th element read-only
Scalar max() const
return the maximal component
auto homogenized() const -> typename std::enable_if< D==4, VectorT< decltype(std::declval< S >()/std::declval< S >()), DIM >>::type
vector_type apply(const Functor &_func) const
component-wise apply function object with Scalar operator()(Scalar).
Scalar l1_norm() const
compute L1 (Manhattan) norm
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
VectorT< Scalar, DIM > vector_type
type of this vector
Scalar mean_abs() const
return absolute arithmetic mean
bool operator!=(const vector_type &_rhs) const
component-wise comparison
static vector_type vectorized(const Scalar &_s)
store the same value in each component
Scalar min() const
return the minimal component
auto operator/=(const OtherScalar &_s) -> typename std::enable_if< std::is_convertible< decltype(this->values_[0]/_s), Scalar >::value, VectorT< Scalar, DIM > &>::type
component-wise self-division by scalar
Scalar value_type
the type of the scalar used in this template
Scalar & operator[](size_t _i)
get i'th element read-write
auto operator|(const VectorT< OtherScalar, DIM > &_rhs) const -> decltype(*this->data() **_rhs.data())
bool operator<(const vector_type &_rhs) const
lexicographical comparison
auto normalized() const -> decltype(*this/std::declval< VectorT< S, DIM >>().norm())
VectorT(const VectorT< otherScalarType, DIM > &_rhs)
copy & cast constructor (explicit)
vector_type & operator=(const VectorT< OtherScalar, DIM > &_rhs)
cast from vector with a different scalar type
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
const Scalar * data() const
access to const Scalar array
vector_type min(const vector_type &_rhs) const
component-wise min
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Scalar l8_norm() const
compute l8_norm
bool operator==(const vector_type &_rhs) const
component-wise comparison
constexpr VectorT()
default constructor creates uninitialized values.
bool minimized(const vector_type &_rhs)
minimize values and signalize coordinate minimization
Scalar min_abs() const
return the minimal absolute component
Scalar mean() const
return arithmetic mean
Scalar max_abs() const
return the maximal absolute component
vector_type max(const vector_type &_rhs) const
component-wise max
bool maximized(const vector_type &_rhs)
maximize values and signalize coordinate maximization
vector_type &::type normalize_cond()
compute squared euclidean norm