diff --git a/src/modm/math/geometry/geometric_traits.hpp b/src/modm/math/geometry/geometric_traits.hpp index fd5528c94c..b61af32602 100644 --- a/src/modm/math/geometry/geometric_traits.hpp +++ b/src/modm/math/geometry/geometric_traits.hpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2009-2011, Fabian Greif * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -10,12 +11,13 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_GEOMETRIC_TRAITS_HPP -#define MODM_GEOMETRIC_TRAITS_HPP +#pragma once +#include #include -#include +#include #include +#include namespace modm { @@ -24,120 +26,42 @@ namespace modm * * \ingroup modm_math_geometry * \author Fabian Greif + * \author Thomas Sommer */ template - struct GeometricTraits - { - static const bool isValidType = false; + struct GeometricTraits; - /** - * \brief Round if converting from a floating point base to - * a integer base. - * - * For T = \c float and \c double this method is specialized to return - * the result directly without any rounding. - */ - static inline T - round(float value) - { - return ::round(value); - } - }; - - template <> - struct GeometricTraits + template + struct GeometricTraits { - static const bool isValidType = true; - - typedef float FloatType; - typedef int16_t WideType; - - static inline int8_t - round(float value) - { - return ::round(value); - } - }; - - // TODO is this useful? - template <> - struct GeometricTraits - { - static const bool isValidType = true; - - typedef float FloatType; - typedef int16_t WideType; + [[deprecated("Use an appropriate C++ concept instead!")]] + static const bool isValidType = false; - static inline uint8_t - round(float value) - { - return ::round(value); - } + using FloatType = float; + using WideType = modm::WideType; }; - template <> - struct GeometricTraits + template + struct GeometricTraits { + [[deprecated("Use an appropriate C++ concept instead!")]] static const bool isValidType = true; - typedef float FloatType; - typedef int32_t WideType; - - static inline int16_t - round(float value) - { - return ::round(value); - } + using FloatType = T; + using WideType = T; }; + #ifdef __AVR__ template <> struct GeometricTraits { + [[deprecated("Use an appropriate C++ concept instead!")]] static const bool isValidType = true; - typedef float FloatType; - - // Usually the range of a int32_t is big enough so that no + using FloatType = float; // conversion to int64_t is required. This exception is made because // 64-bit operations are very, very slow on an AVR. - typedef int32_t WideType; - - static inline int32_t - round(float value) - { - return ::round(value); - } - }; - - template <> - struct GeometricTraits - { - static const bool isValidType = true; - - typedef float FloatType; - typedef float WideType; - - static inline float - round(float value) - { - return value; - } + using WideType = int32_t; }; - - template <> - struct GeometricTraits - { - static const bool isValidType = true; - - typedef double FloatType; - typedef double WideType; - - static inline double - round(double value) - { - return value; - } - }; -} - -#endif // MODM_GEOMETRIC_TRAITS_HPP + #endif +} \ No newline at end of file diff --git a/src/modm/math/geometry/location_2d.hpp b/src/modm/math/geometry/location_2d.hpp index c0a350e019..8eff73ceb7 100644 --- a/src/modm/math/geometry/location_2d.hpp +++ b/src/modm/math/geometry/location_2d.hpp @@ -3,6 +3,8 @@ * Copyright (c) 2009-2011, Fabian Greif * Copyright (c) 2012, Niklas Hauser * Copyright (c) 2012, Sascha Schade + * Copyright (c) 2013, Kevin Läufer + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -12,10 +14,7 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_LOCATION_2D_HPP -#define MODM_LOCATION_2D_HPP - -#include +#pragma once #include @@ -37,39 +36,60 @@ namespace modm class Location2D { public: - Location2D(); - - Location2D(const Vector& position, const float& orientation); - - Location2D(const T& x, const T& y, const float& orientation); - - inline const Vector& - getPosition() const; - - inline const T& - getX() const; - - inline const T& - getY() const; - - void - setPosition(const Vector& point); - - void - setPosition(const T& x, const T& y); + Vector position; + float orientation = 0; + + constexpr Location2D() = default; + constexpr Location2D(const Vector& position, const float& orientation) + : position(position), orientation(orientation) {} + + [[deprecated("Use 'setPosition({x, y}, orientation)' instead!")]] + constexpr Location2D(const T& x, const T& y, const float& orientation) + : position(x, y), orientation(orientation) {} + + template + constexpr Location2D(const Location2D &l) : position(l.position), orientation(l.orientation) {} + + // getters and setters + void setPosition(const Vector& position) { this->position = position; } + + [[deprecated("Use 'setPosition({x, y}' instead!")]] + void setPosition(T x, T y) { this->position.x = x; this->position.y = y; } + void setOrientation(const float orientation) { this->orientation = orientation; } + + Vector getPosition() const { return position; } + inline float getOrientation() const { return orientation; } + T getX() const { return position.x; } + T getY() const { return position.y; } + + bool operator== (const Location2D &other) const { + return ( + position == other.position and + std::abs(orientation - other.orientation) < __FLT_EPSILON__ + ); + } + bool operator!= (const Location2D &other) const { + return ( + position != other.position or + std::abs(orientation - other.orientation) > __FLT_EPSILON__ + ); + } - inline float - getOrientation() const; + /// Add a position increment + void move(const Location2D& diff) { + Vector movement = diff.position; + movement.rotate(orientation); - void - setOrientation(const float& phi); + position.translate(movement); + orientation = Angle::normalize(orientation + diff.orientation); + } - /// Add a position increment - void - move(const Location2D& diff); + void move(const Vector& diff) { + Vector movement(diff); + movement.rotate(orientation); - void - move(const Vector& diff); + position.translate(movement); + } /** * \brief Add a increment only in x-direction @@ -85,62 +105,38 @@ namespace modm * movement over time. * Because the y-component will always be zero, we created this * method, which avoids unnecessary computations for the y-component - * and is therefore faster the the universal move-method. + * and is therefore faster than the universal move-method. * * \param x movement in x-direction * \param phi rotation */ void - move(T x, float phi); + move(T x, float phi) { + Vector vector(Vector(x * std::cos(orientation), x * std::sin(orientation))); + position.translate(vector); - /// TODO - Vector - translated(const Vector& vector) const; - - /// Convert between Location-objects with different base-types - template - Location2D - convert() const; + orientation = Angle::normalize(orientation + phi); + } - bool - operator == (const Location2D &other) const; + // TODO + Vector translated(const Vector& vector) const { + Vector result(vector); + result.rotate(orientation); + result.translate(position); - bool - operator != (const Location2D &other) const; + return result; + } private: template friend IOStream& operator <<( IOStream&, const Location2D&); - - Vector position; - float orientation; }; - // ------------------------------------------------------------------------ - // Global functions - // ------------------------------------------------------------------------ - /** - * \brief Stream operator to \b modm::Location - * - * \ingroup modm_math_geometry - */ template IOStream& - operator << (IOStream& os, const Location2D& l); - - // ------------------------------------------------------------------------ - // Declaration of specialized methods - // ------------------------------------------------------------------------ - /*template<> - bool - Location2D::operator == (const Location2D &other) const; - - template<> - bool - Location2D::operator == (const Location2D &other) const;*/ -} - -#include "location_2d_impl.hpp" - -#endif // MODM_LOCATION_2D_HPP + operator<< (IOStream& os, const Location2D& location) { + os << location.position << ", phi=" << location.orientation; + return os; + } +} \ No newline at end of file diff --git a/src/modm/math/geometry/location_2d_impl.hpp b/src/modm/math/geometry/location_2d_impl.hpp deleted file mode 100644 index 913449fcd7..0000000000 --- a/src/modm/math/geometry/location_2d_impl.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2009-2010, Martin Rosekeit - * Copyright (c) 2009-2011, Fabian Greif - * Copyright (c) 2013, Kevin Läufer - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_LOCATION_2D_HPP - #error "Don't include this file directly use 'location.hpp' instead!" -#endif - -#include -#include - -// ----------------------------------------------------------------------------- -template -modm::Location2D::Location2D() : - position(), orientation() -{ -} - -template -modm::Location2D::Location2D(const Vector& position, - const float& orientation) : - position(position), - orientation(orientation) -{ -} - -template -modm::Location2D::Location2D(const T& x, const T& y, const float& orientation) : - position(x, y), - orientation(orientation) -{ -} - -// ---------------------------------------------------------------------------- -template -const modm::Vector& -modm::Location2D::getPosition() const -{ - return this->position; -} - -template -inline const T& -modm::Location2D::getX() const -{ - return this->position.x; -} - -template -inline const T& -modm::Location2D::getY() const -{ - return this->position.y; -} - -template -void -modm::Location2D::setPosition(const Vector& point) -{ - this->position = point; -} - -template -void -modm::Location2D::setPosition(const T& x, const T& y) -{ - this->position.set(x, y); -} - -template -float -modm::Location2D::getOrientation() const -{ - return this->orientation; -} - -template -void -modm::Location2D::setOrientation(const float& orientation) -{ - this->orientation = orientation; -} - -// ----------------------------------------------------------------------------- -template -void -modm::Location2D::move(const Location2D& diff) -{ - Vector movement = diff.position; - movement.rotate(this->orientation); - - this->position.translate(movement); - this->orientation = Angle::normalize(this->orientation + diff.orientation); -} - -template -void -modm::Location2D::move(const Vector& diff) -{ - Vector movement(diff); - movement.rotate(this->orientation); - - this->position.translate(movement); -} - -template -void -modm::Location2D::move(T x, float phi) -{ - Vector vector(GeometricTraits::round(x * std::cos(this->orientation)), - GeometricTraits::round(x * std::sin(this->orientation))); - position.translate(vector); - - this->orientation = Angle::normalize(this->orientation + phi); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Location2D::translated(const Vector& vector) const -{ - Vector result(vector); - result.rotate(this->orientation); - result.translate(this->position); - - return result; -} - -// ---------------------------------------------------------------------------- -template template -modm::Location2D -modm::Location2D::convert() const -{ - return Location2D(this->position.template convert(), this->orientation); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Location2D::operator == (const Location2D &other) const -{ - return ((this->position == other.position) && - (std::abs(this->orientation - other.orientation) < __FLT_EPSILON__)); -} - -template -bool -modm::Location2D::operator != (const Location2D &other) const -{ - return ((this->position != other.position) || - (std::abs(this->orientation - other.orientation) > __FLT_EPSILON__)); -} - -// ---------------------------------------------------------------------------- -template -modm::IOStream& -modm::operator << (modm::IOStream& os, const modm::Location2D& location) -{ - os << location.position << ", phi=" << location.orientation; - return os; -} diff --git a/src/modm/math/geometry/quaternion.hpp b/src/modm/math/geometry/quaternion.hpp index d3cbcdb761..879ca8847a 100644 --- a/src/modm/math/geometry/quaternion.hpp +++ b/src/modm/math/geometry/quaternion.hpp @@ -11,8 +11,7 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_QUATERNION_HPP -#define MODM_QUATERNION_HPP +#pragma once #include #include @@ -20,10 +19,10 @@ namespace modm { // forward declaration - template + template class Vector; - template + template class Matrix; /** @@ -111,5 +110,3 @@ namespace modm } #include "quaternion_impl.hpp" - -#endif // MODM_QUATERNION_HPP diff --git a/src/modm/math/geometry/quaternion_impl.hpp b/src/modm/math/geometry/quaternion_impl.hpp index 0fa1b4e24e..2cac396087 100644 --- a/src/modm/math/geometry/quaternion_impl.hpp +++ b/src/modm/math/geometry/quaternion_impl.hpp @@ -9,15 +9,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_QUATERNION_HPP -# error "Don't include this file directly, use 'quaternion.hpp' instead!" -#endif +#pragma once #include "quaternion.hpp" -// ---------------------------------------------------------------------------- template modm::Quaternion::Quaternion() : diff --git a/src/modm/math/geometry/vector.hpp b/src/modm/math/geometry/vector.hpp index 20f918e37c..208dc778c6 100644 --- a/src/modm/math/geometry/vector.hpp +++ b/src/modm/math/geometry/vector.hpp @@ -3,6 +3,7 @@ * Copyright (c) 2012, Georgi Grinshpun * Copyright (c) 2012, Martin Rosekeit * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -12,140 +13,227 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_VECTOR_HPP -#define MODM_VECTOR_HPP +#pragma once #include -#include - +#include +#include #include -#include + +#include "geometric_traits.hpp" namespace modm { - // forward declaration - template class Matrix; - - /** - * \brief Class for handling common point operations - * - * Basic data type of all geometric operations. Used to represent vectors - * as well as particular points in the coordinate system. - * - * \section point_vector Point vs. vector - * - * In geometry, it is often convenient to use vector arithmetic to - * represent points. - * - * A vector, by its definition, has no fixed starting point, but if we - * imagine the starting point of a vector to be the origin, then the - * endpoint of the vector represents a particular point. - * - * In this manner, every vector can be said to identify a unique point, - * which is the endpoint of the vector when its starting point is the - * origin. - * - * Therefore there isn't a Point-class, but only a Vector class. - * - * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). - * - * \see Homepage - * - * \ingroup modm_math_geometry - * \author Niklas Hauser - */ - template - class Vector - { - public: - Vector(); - Vector(const T *ptData); - - Vector(const Matrix &rhs); - Vector& operator = (const Matrix &rhs); - - bool operator == (const Vector &rhs) const; - bool operator != (const Vector &rhs) const; - bool operator < (const Vector &rhs) const; - bool operator <= (const Vector &rhs) const; - bool operator > (const Vector &rhs) const; - bool operator >= (const Vector &rhs) const; - - const T& operator [] (uint8_t index) const; - T& operator [] (uint8_t index); - - T* ptr(); - const T* ptr() const; - - Vector operator + (const Vector &rhs) const; - Vector operator - (const Vector &rhs) const; - T operator * (const Vector &rhs) const; - Vector operator * (const T &rhs) const; - Vector operator / (const T &rhs) const; - Vector& operator += (const Vector &rhs); - Vector& operator -= (const Vector &rhs); - Vector& operator *= (const T &rhs); - Vector& operator /= (const T &rhs); - Vector& operator - (); // FIXME - - T getLength() const; - T getLengthSquared() const; - - Matrix& - asMatrix(); - - const Matrix& - asMatrix() const; - - Matrix& - asTransposedMatrix(); - - const Matrix& - asTransposedMatrix() const; - - public: - static inline uint8_t - getSize(); - - T coords[N]; - }; - - template< typename T, uint8_t N > - struct detail::MakeSigned< Vector > +// forward declaration +template +class Matrix; + +/** + * \brief Class for handling common point operations + * + * Basic data type of all geometric operations. Used to represent vectors + * as well as particular points in the coordinate system. + * + * \section point_vector Point vs. vector + * + * In geometry, it is often convenient to use vector arithmetic to + * represent points. + * + * A vector, by its definition, has no fixed starting point, but if we + * imagine the starting point of a vector to be the origin, then the + * endpoint of the vector represents a particular point. + * + * In this manner, every vector can be said to identify a unique point, + * which is the endpoint of the vector when its starting point is the + * origin. + * + * Therefore there isn't a Point-class, but only a Vector class. + * + * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). + * + * \see Homepage + * + * \ingroup modm_math_geometry + * \author Niklas Hauser + * \author Thomas Sommer + */ +template +class Vector +{ +public: + static constexpr std::size_t size = N; + + T coords[N] = {0}; + + // fundamental constructors + constexpr Vector() = default; + + constexpr explicit Vector(T v) + { std::fill(coords, coords + N, v); } + + template + requires std::integral && std::floating_point + constexpr explicit Vector(U v) + { std::fill(coords, coords + N, std::round(v)); } + + constexpr Vector(const T (&arr)[N]) + { std::copy(arr, arr + N, coords); } + + // TODO need std::round + template + requires std::integral && std::floating_point + constexpr Vector(const U (&arr)[N]) + { std::copy(arr, arr + N, coords); } + + // matrix constructor + constexpr Vector(const Matrix &rhs) + { std::copy(rhs, rhs + N, coords); } + + // as matrix convertors + Matrix& + asMatrix() + { return *reinterpret_cast*>(this); } + + const Matrix& + asMatrix() const + { return *reinterpret_cast*>(this); } + + Matrix& + asTransposedMatrix() + { return *reinterpret_cast*>(this); } + + const Matrix& + asTransposedMatrix() const + { return *reinterpret_cast*>(this); } + + // matrix assignment + Vector& operator= (const Matrix &rhs) { + std::copy(coords, coords + N, &rhs); + return *this; + } + + // accessors + T& operator [] (std::size_t index) + { return coords[index]; } + + const T& operator [] (std::size_t index) const + { return coords[index]; } + + T* ptr() { return coords; } + + const T* ptr() const { return reinterpret_cast(coords); } + + // operators + auto operator<=>(const Vector &) const = default; + + Vector operator+ (const Vector &rhs) const { + Vector ret; + std::transform(coords, coords + N, rhs.coords, ret.coords, std::plus()); + return ret; + } + + Vector operator- (const Vector &rhs) const { + Vector ret; + std::transform(coords, coords + N, rhs.coords, ret.coords, std::minus()); + return ret; + } + + T operator* (const Vector &rhs) const { + T tmp[N]; + std::transform(coords, coords + N, rhs.coords, tmp, std::multiplies()); + return std::accumulate(tmp, tmp + N, 0); + } + + Vector operator* (const T &rhs) const { + Vector ret; + std::transform(coords, coords + N, ret.coords, [=] (T c) {return c * rhs;}); + return ret; + } + + Vector operator/ (const T &rhs) const { + Vector ret; + std::transform(coords, coords + N, ret.coords, [=] (T c) {return c / rhs;}); + return ret; + } + + Vector& operator+= (const Vector &rhs) { + std::transform(coords, coords + N, rhs.coords, coords, std::plus()); + return *this; + } + + Vector& operator-= (const Vector &rhs) { + std::transform(coords, coords + N, rhs.coords, coords, std::minus()); + return *this; + } + + Vector& operator*= (const T &rhs) { + std::transform(coords, coords + N, coords, [=] (T c) {return c * rhs;}); + return *this; + } + + Vector& operator/= (const T &rhs) { + std::transform(coords, coords + N, coords, [=] (T c) {return c / rhs;}); + return *this; + } + + // template + // requires std::is_signed::value + constexpr Vector operator- () { + Vector ret; + std::transform(coords, coords + N, ret.coords, std::negate()); + return ret; + } + + // additional methods + T getLength() const + { return std::sqrt(getLengthSquared()); } + + T getLengthSquared() const { + T tmp[N]; + // Better do std::pow(c, 2); + std::transform(coords, coords + N, coords, tmp, std::multiplies()); + return std::accumulate(tmp, tmp + N, 0); + } + + // IMPLEMENT operator<< +}; + +namespace detail { + template< typename T, std::size_t N > + struct MakeSigned< Vector > { using type = Vector< SignedType, N >; }; - template< typename T, uint8_t N > - struct detail::MakeUnsigned< Vector > + template< typename T, std::size_t N > + struct MakeUnsigned< Vector > { using type = Vector< UnsignedType, N >; }; - template< typename T, uint8_t N > - struct detail::WideType< Vector > + template< typename T, std::size_t N > + struct WideType< Vector > { using type = Vector< WideType, N >; }; -} -#define IMPLEMENT_VECTOR_ACCESSOR2(a,b) \ - Vector a##b() const \ - { \ - return Vector(a, b); \ - } +} // namespace detail -#define IMPLEMENT_VECTOR_ACCESSOR3(a, b, c) \ - Vector a##b##c() const \ - { \ - return Vector(a, b, c); \ - } +} // namespace modm -#define IMPLEMENT_VECTOR_ACCESSOR4(a, b, c, d) \ - Vector a##b##c##d() const \ - { \ - return Vector(a, b, c, d); \ - } +#define IMPLEMENT_VECTOR_ACCESSOR2(a,b) \ + Vector a##b() const \ + { \ + return Vector(a, b); \ + } -#include "vector_impl.hpp" +#define IMPLEMENT_VECTOR_ACCESSOR3(a, b, c) \ + Vector a##b##c() const \ + { \ + return Vector(a, b, c); \ + } + +#define IMPLEMENT_VECTOR_ACCESSOR4(a, b, c, d)\ + Vector a##b##c##d() const \ + { \ + return Vector(a, b, c, d); \ + } #include "vector1.hpp" #include "vector2.hpp" #include "vector3.hpp" -#include "vector4.hpp" - -#endif // MODM_VECTOR_HPP +#include "vector4.hpp" \ No newline at end of file diff --git a/src/modm/math/geometry/vector1.hpp b/src/modm/math/geometry/vector1.hpp index 923879e033..c5107510f8 100644 --- a/src/modm/math/geometry/vector1.hpp +++ b/src/modm/math/geometry/vector1.hpp @@ -2,6 +2,7 @@ * Copyright (c) 2009-2010, Martin Rosekeit * Copyright (c) 2009-2012, Fabian Greif * Copyright (c) 2011-2012, Niklas Hauser + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -11,103 +12,179 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_VECTOR1_HPP -#define MODM_VECTOR1_HPP +#pragma once #include #include -#include +#include +#include #include "vector.hpp" namespace modm { - /** - * \brief Class for handling common vector operations (1D) - * - * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). - * - * \see Homepage - * - * \ingroup modm_math_geometry - * \author Niklas Hauser - */ - template - class Vector - { - public: - Vector(); - Vector(T inX); - Vector(const Matrix &rhs); - - inline void - set(const T& x); - - inline void - setX(const T& value); - - inline const T& - getX() const; - - Vector& operator = (const Matrix &rhs); - - bool operator == (const Vector &rhs) const; - bool operator != (const Vector &rhs) const; - bool operator < (const Vector &rhs) const; - bool operator <= (const Vector &rhs) const; - bool operator > (const Vector &rhs) const; - bool operator >= (const Vector &rhs) const; - - const T& operator [] (uint8_t index) const; - T& operator [] (uint8_t index); - T* ptr(); - const T* ptr() const; - - Vector operator - () const; - Vector operator + (const Vector &rhs) const; - Vector operator - (const Vector &rhs) const; - T operator * (const Vector &rhs) const; - Vector operator * (const T &rhs) const; - Vector operator / (const T &rhs) const; - - Vector& operator += (const Vector &rhs); - Vector& operator -= (const Vector &rhs); - Vector& operator *= (const T &rhs); - Vector& operator /= (const T &rhs); - - T getLength() const; - T getLengthSquared() const; - - Matrix& - asMatrix(); - - const Matrix& - asMatrix() const; - - bool hasNan() const; - bool hasInf() const; - - public: - T x; - - public: - #ifndef __DOXYGEN__ - IMPLEMENT_VECTOR_ACCESSOR2(x,x) - IMPLEMENT_VECTOR_ACCESSOR3(x,x,x) - IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x) - #endif - }; - - template - static inline Vector operator * (const U &lhs, const Vector &rhs) - { - return rhs * lhs; +/** + * \brief Class for handling common vector operations (1D) + * + * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). + * + * \see Homepage + * + * \author Niklas Hauser + * \author Thomas Sommer + * \ingroup modm_math_geometry + */ +template +class Vector +{ +public: + using WideType = GeometricTraits::WideType; + using FloatType = GeometricTraits::FloatType; + + T x{0}; + + // fundamental constructors + constexpr Vector() = default; + + constexpr Vector(T x) : x(x) {} + + template + requires std::integral && std::floating_point + constexpr Vector(U x) : x(std::round(x)) {} + + template + constexpr Vector(Vector v) : Vector(v.x) {} + + // matrix constructors + template + constexpr Vector(const Matrix &rhs) + : Vector(*reinterpret_cast(&rhs)) {} + + // as matrix convertors + Matrix& + asMatrix() { return *(modm::Matrix*) this; } + + const Matrix& + asMatrix() const { return *(modm::Matrix*) this; } + + // matrix assignment + Vector& operator= (const Matrix &rhs) { + x = *reinterpret_cast(&rhs); + return *this; } - typedef Vector Vector1f; - typedef Vector Vector1i; + // getters + T getX() const { return x; } + + // setters + void setX(T x) { this->x = x; } + + template + requires std::integral && std::floating_point + void setX(U x) { this->x = std::round(x); } + + void set(T x) { this->x = x; } + + template + requires std::integral && std::floating_point + void set(U x) { this->x = std::round(x); } + + // accessors + T& operator[] (std::size_t index) + { return reinterpret_cast(this)[index]; } + + const T& operator[] (std::size_t index) const + { return reinterpret_cast(this)[index]; } + + T* ptr() { return reinterpret_cast(this); } + + const T* ptr() const { return reinterpret_cast(this);} + + // operators + auto operator<=>(const Vector &) const = default; + + constexpr Vector operator+ (const Vector &rhs) const + { return Vector(x + rhs.x); } + + constexpr Vector operator- (const Vector &rhs) const + { return Vector(x - rhs.x); } + + constexpr T operator* (const Vector &rhs) const + { return x * rhs.x; } + + template + constexpr Vector operator* (U scale) const + { return Vector(x * scale); } + + template + constexpr Vector operator/ (U scale) const + { return Vector(x / scale); } + + Vector& operator+= (const Vector &rhs) + { x += rhs.x; return *this; } + + Vector& operator-= (const Vector &rhs) + { x -= rhs.x; return *this; } + + template + Vector& operator*= (U scale) + { x *= scale; return *this; } + + template + Vector& operator/= (U scale) + { x /= scale; return *this; } + + // template + // requires std::is_signed::value + constexpr Vector operator- () const + { return Vector(-x); } + + // additional methods + T getLength() const + { return std::abs(x); } + + WideType getLengthSquared() const + { return std::pow(x, 2); } + + bool hasNan() const { return std::isnan(x); } + + bool hasInf() const { return std::isinf(x); } + +#ifndef __DOXYGEN__ + IMPLEMENT_VECTOR_ACCESSOR2(x,x) + IMPLEMENT_VECTOR_ACCESSOR3(x,x,x) + IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x) +#endif + + // depricated methods + template + [[deprecated("Use common constructor instead!")]] + Vector + convert() const { return {*this}; } + +protected: + template + friend IOStream& + operator<<(IOStream& os, const Vector& c); +}; + +template +static inline Vector operator * (const U &lhs, const Vector &rhs) +{ return rhs * lhs; } + +#if __has_include() +#include + +template +IOStream& +operator<< (IOStream& os, const Vector& v) { + os << "x=" << v.x; + return os; } +#endif -#include "vector1_impl.hpp" +using Vector1f = Vector; +using Vector1i = Vector; +using Vector1u = Vector; -#endif // MODM_VECTOR1_HPP +} // namespace modm diff --git a/src/modm/math/geometry/vector1_impl.hpp b/src/modm/math/geometry/vector1_impl.hpp deleted file mode 100644 index 3a9045d78a..0000000000 --- a/src/modm/math/geometry/vector1_impl.hpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2011, Fabian Greif - * Copyright (c) 2012, Georgi Grinshpun - * Copyright (c) 2012, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_VECTOR1_HPP - #error "Don't include this file directly, use 'vector1.hpp' instead!" -#endif - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector() : - x() -{ -} - -template -modm::Vector::Vector(T inX) : - x(inX) -{ -} - -template -modm::Vector::Vector(const modm::Matrix &rhs) : - x(*reinterpret_cast(&rhs)) -{ -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::set(const T& value) -{ - this->x = value; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::setX(const T& value) -{ - this->x = value; -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::getX() const -{ - return this->x; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator = (const modm::Matrix &rhs) -{ - x = *reinterpret_cast(&rhs); - return *this; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator == (const modm::Vector &rhs) const -{ - return (rhs.x == x); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator != (const modm::Vector &rhs) const -{ - return (rhs.x != x); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator < (const modm::Vector &rhs) const -{ - return (x < rhs.x); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator <= (const modm::Vector &rhs) const -{ - return (x <= rhs.x); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator > (const modm::Vector &rhs) const -{ - return (x > rhs.x); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator >= (const modm::Vector &rhs) const -{ - return (x >= rhs.x); -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::operator [] (uint8_t index) const -{ - return reinterpret_cast(this)[index]; -} - -template -T& -modm::Vector::operator [] (uint8_t index) -{ - return reinterpret_cast(this)[index]; -} - -// ---------------------------------------------------------------------------- -template -T* -modm::Vector::ptr() -{ - return reinterpret_cast(this); -} - -template -const T* -modm::Vector::ptr() const -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator + (const modm::Vector &rhs) const -{ - return modm::Vector(x+rhs.x); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - (const modm::Vector &rhs) const -{ - return modm::Vector(x-rhs.x); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::operator * (const modm::Vector &rhs) const -{ - return x*rhs.x; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator * (const T &rhs) const -{ - return modm::Vector(x*rhs); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator / (const T &rhs) const -{ - return modm::Vector(x/rhs); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator += (const modm::Vector &rhs) -{ - x += rhs.x; - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator -= (const modm::Vector &rhs) -{ - x -= rhs.x; - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator *= (const T &rhs) -{ - x *= rhs; - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator /= (const T &rhs) -{ - x /= rhs; - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - () const -{ - return Vector(-x); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::getLength() const -{ - return std::abs(x); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::getLengthSquared() const -{ - return x * x; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asMatrix() -{ - return *(modm::Matrix*) this; -} - -// ---------------------------------------------------------------------------- -template -const modm::Matrix& -modm::Vector::asMatrix() const -{ - return *(modm::Matrix*) this; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::hasNan() const -{ - return std::isnan(x); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::hasInf() const -{ - return std::isinf(x); -} - -// ---------------------------------------------------------------------------- -//template -//static modm::Vector operator * (const U &lhs, const modm::Vector &rhs) -//{ -// return rhs * lhs; -//} diff --git a/src/modm/math/geometry/vector2.cpp b/src/modm/math/geometry/vector2.cpp deleted file mode 100644 index 64bd297920..0000000000 --- a/src/modm/math/geometry/vector2.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010-2012, Fabian Greif - * Copyright (c) 2010, 2012, Martin Rosekeit - * Copyright (c) 2012, Georgi Grinshpun - * Copyright (c) 2012, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#include - -#include "vector2.hpp" - -// this explicit namespace is needed here, otherwise we get an error about -// "specialization of ... in different namespace" -namespace modm -{ - template<> - int16_t - Vector::getLength() const - { - int32_t t; - - t = math::mul(this->x, this->x); - t = math::mac(t, this-> y, this->y); - - return math::sqrt(t); - } - - template<> - int32_t - Vector::getLengthSquared() const - { - int32_t t; - - t = math::mul(this->x, this->x); - t = math::mac(t,this-> y, this->y); - - return t; - } - - template<> - int32_t - Vector::dot(const modm::Vector& other) const - { - int32_t t; - - t = math::mul(this->x, other.x); - t = math::mac(t,this->y, other.y); - - return t; - } - - // ------------------------------------------------------------------------ - template<> - template<> - Vector - Vector::convert() const - { - return Vector(this->x, this->y); - } - - template<> - template<> - Vector - Vector::convert() const - { - return Vector(this->x, this->y); - } -} diff --git a/src/modm/math/geometry/vector2.hpp b/src/modm/math/geometry/vector2.hpp index 7cb06624e9..8585c12c0c 100644 --- a/src/modm/math/geometry/vector2.hpp +++ b/src/modm/math/geometry/vector2.hpp @@ -3,6 +3,7 @@ * Copyright (c) 2010, Martin Rosekeit * Copyright (c) 2012, Georgi Grinshpun * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -12,373 +13,409 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_VECTOR2_HPP -#define MODM_VECTOR2_HPP +#pragma once #include -#include -#include +#include -#include "geometric_traits.hpp" #include "angle.hpp" #include "vector.hpp" namespace modm { - // forward declaration - template - class Location2D; +// forward declaration +template +class Location2D; + +/** + * \brief Class for handling common vector operations (2D) + * + * Operations: + * \code + * + : addition of points + * - : different of points + * * : dot product or scalar multiplication + * / : scalar division + * ^ : cross product (determinant) + * ~ : perpendicular + * \endcode + * + * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com) + * and heavily modified. + * + * \see Homepage + * + * \author Fabian Greif + * \author Niklas Hauser + * \author Thomas Sommer + * \ingroup modm_math_geometry + */ +template +class Vector +{ + using VecT1 = Vector; + using VecT2 = Vector; + +public: + using WideType = GeometricTraits::WideType; + using FloatType = GeometricTraits::FloatType; + + T x{0}, y{0}; + + // fundamental constructors + constexpr Vector() = default; + + constexpr explicit Vector(T xy) + : x(xy), y(xy) {} + + template + requires std::integral && std::floating_point + constexpr explicit Vector(T xy) + : x(std::round(xy)), y(std::round(xy)) {} + + constexpr Vector(T x, T y) + : x(x), y(y) {} + + template + requires std::integral && std::floating_point + constexpr Vector(U x, U y) + : x(std::round(x)), y(std::round(y)) {} + + template + constexpr Vector(Vector v) : Vector(v.x, v.y) {} + + // vector constructors + constexpr Vector(VecT1 vx, VecT1 vy) : Vector(vx.x, vy.x) {} + constexpr Vector(T x, VecT1 vy) : Vector(x, vy.x) {} + constexpr Vector(VecT1 vx, T y) : Vector(vx.x, y) {} + + // matrix constructors + constexpr Vector(const Matrix &rhs) + : Vector(reinterpret_cast(&rhs)[0], reinterpret_cast(&rhs)[1]) {} + + // array constructors + template + constexpr explicit Vector(U *array) : Vector(array[0], array[1]) {} + + // as matrix convertors + Matrix& + asMatrix() { return *((Matrix *) this); } + + const Matrix& + asMatrix() const { return *((Matrix *) this); } + + Matrix& + asTransposedMatrix() { return *((Matrix *) this); } + + const Matrix& + asTransposedMatrix() const { return *((Matrix *) this); } + + // matrix assignment + Vector& operator= (const Matrix &rhs) { + x = reinterpret_cast(&rhs)[0]; + y = reinterpret_cast(&rhs)[1]; + + return *this; + } + + // getters + T getX() const { return x; } + T getY() const { return y; } + + // setters + void setX(T x) { this->x = x; } + + template + requires std::integral && std::floating_point + void setX(U x) { this->x = std::round(x); } + + + void setY(T y) { this->y = y; } + + template + requires std::integral && std::floating_point + void setY(U y) { this->x = std::round(y); } + + + void set(T x, T y) { + this->x = x; + this->y = y; + } + + template + requires std::integral && std::floating_point + void set(U x, U y) { + this->x = std::round(x); + this->y = std::round(y); + } + + // accessors + T& operator[] (std::size_t index) + { return reinterpret_cast(this)[index]; } + + const T& operator[] (std::size_t index) const + { return reinterpret_cast(this)[index]; } + + T* ptr() { return reinterpret_cast(this); } + + const T* ptr() const { return reinterpret_cast(this); } + + // operators + auto operator<=>(const Vector&) const = default; + + constexpr Vector operator+ (const Vector &rhs) const + { return Vector(x + rhs.x, y + rhs.y); } + + constexpr Vector operator- (const Vector &rhs) const + { return Vector(x - rhs.x, y - rhs.y); } + + constexpr T operator* (const Vector &rhs) const + { return x * rhs.x + y * rhs.y; } + + constexpr T operator^ (const Vector &rhs) const + { return x * rhs.y - y * rhs.x; } + + template + constexpr Vector operator* (U scale) const + { return Vector(x * scale, y * scale); } + + template + constexpr Vector operator/ (U scale) const + { return Vector(x / scale, y / scale); } + + Vector& operator+= (const Vector &rhs) + { x += rhs.x; y += rhs.y; return *this; } + + Vector& operator-= (const Vector &rhs) + { x -= rhs.x; y -= rhs.y; return *this; } + + template + Vector& operator*= (U scale) + { x *= scale; y *= scale; return *this; } + + template + Vector& operator/= (U scale) + { x /= scale; y /= scale; return *this; } + + Vector& operator~ () + { *this = perpendicular(); return *this; } + + // template + // requires std::is_signed::value + constexpr Vector operator- () const + { return Vector(-x, -y); } + + // additional methods + T getLength() const + { return std::sqrt(getLengthSquared()); } + + T getLength() const + requires std::integral + { return round(std::sqrt(getLengthSquared())); } + + WideType getLengthSquared() const + { return std::pow(x, 2) + std::pow(y, 2); } + + WideType getDistanceTo(const Vector& other) const + { return (other - *this).getLength(); } + + float getAngle() const + { return std::atan2(y, x); } + + float getAngleTo(const Vector& other) const + { return (other - *this).getAngle(); } + + /** + * \brief Normalize length to 1 + * + * \warning This method is only useful if T is a floating point type. + * For integer types the result might be wrong! + */ + Vector& normalize() { + operator/=( getLength() ); + return *this; + } + + Vector normalized() const { + return *this / getLength(); + } + + /** + * \brief Scale the vector to \p length + */ + Vector& scale(float length) { + operator*=( length / getLength() ); + return *this; + } + + Vector scaled(float length) const { + return *this * (length / getLength()); + } + + // TODO implement as operator+=(Angle phi), operator-=(Angle phi) + Vector& + rotate(float phi) { + const float c = std::cos(phi); + const float s = std::sin(phi); + const Vector tmp(c * x - s * y, s * x + c * y); + set(tmp.x, tmp.y); + + return *this; + } /** - * \brief Class for handling common vector operations (2D) + * \brief Same like operator+= but also returns reference + */ + Vector& + translate(Vector v) + { operator+=(v); return *this; } + + /** + * \brief Calculate the dot-product + * + * Also known as the scalar product. * - * Operations: * \code - * + : addition of points - * - : different of points - * * : dot product or scalar multiplication - * / : scalar division - * ^ : cross product (determinant) - * ~ : perpendicular + * this.x * other.x + this.y * other.y * \endcode + */ + WideType dot(const Vector& other) const + { return WideType(x) * WideType(other.x) + WideType(y) * WideType(other.y); } + + /** + * \brief Calculate the cross-product * - * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com) - * and heavily modified. + * In 2D there is no clear definition of this operation. * - * \see Homepage + * This implementation is the most common one and will return the + * magnitude of the vector that would result from a regular + * 3D cross product of the input vectors, taking their Z values + * implicitly as 0 (i.e. treating the 2D space as a plane in the 3D space). + * The 3D cross product will be perpendicular to that plane, and thus + * have 0 X & Y components (thus the scalar returned is the Z value of + * the 3D cross product vector). * - * \author Fabian Greif - * \author Niklas Hauser + * \code + * this.x * other.y - this.y * other.x + * \endcode * - * \ingroup modm_math_geometry - */ - template - class Vector - { - friend class Location2D; - - public: - typedef typename GeometricTraits::WideType WideType; - typedef typename GeometricTraits::FloatType FloatType; - - public: - /** - * \brief Default-Constructor - * - * Creates a Vector with coordinates (0, 0). - */ - Vector(); - - Vector(const T& inX, const T& inY); - - Vector(const Vector &inX, const Vector &inY); - Vector(const T &inX, const Vector &inY); - Vector(const Vector &inX, const T &inY); - explicit Vector(T inVal); - Vector(const Matrix &rhs); - - inline void - setX(const T& value); - - inline void - setY(const T& value); - - inline void - set(const T& x, const T& y); - - - inline const T& - getX() const; - - inline const T& - getY() const; - - /** - * \brief Calculate length of the vector - */ - T - getLength() const; - - /** - * \brief Calculate squared length of the vector - * - * This method is considerably faster than getLength() because it - * doesn't need to calculate the square root. - * - * \return squared length (x*x + y*y) - */ - WideType - getLengthSquared() const; - - /** - * \brief Calculate the absolute angle - * - * \code - * atan2(y, x) - * \endcode - */ - float - getAngle() const; - - /** - * \brief Normalize length to 1 - * - * \warning This method is only useful if T is a floating point type. - * For integer types the result might be wrong! - */ - Vector& - normalize(); - - Vector - normalized() const; - - /** - * \brief Scale the vector to \p length - */ - Vector& - scale(float length); - - Vector - scaled(float length) const; - - - Vector& - rotate(float phi); - - /** - * \brief Move the point in x and y direction - */ - Vector& - translate(const Vector& vector); - - - WideType - getDistanceTo(const Vector& other) const; - - float - getAngleTo(const Vector& other) const; - - /** - * \brief Calculate the dot-product - * - * Also known as the scalar product. - * - * \code - * this.x * other.x + this.y * other.y - * \endcode - */ - WideType - dot(const Vector& other) const; - - /** - * \brief Calculate the cross-product - * - * In 2D there is no clear definition of this operation. - * - * This implementation is the most common one and will return the - * magnitude of the vector that would result from a regular - * 3D cross product of the input vectors, taking their Z values - * implicitly as 0 (i.e. treating the 2D space as a plane in the 3D space). - * The 3D cross product will be perpendicular to that plane, and thus - * have 0 X & Y components (thus the scalar returned is the Z value of - * the 3D cross product vector). - * - * \code - * this.x * other.y - this.y * other.x - * \endcode - * - * Other implementations take no arguments and returns a vector - * perpendicular to the input vector. This can be reached with the - * toOrthogonalVector() method, which returns a perpendicular copy - * of the vector. - */ - WideType - cross(const Vector& other) const; - - /** - * \brief Convert between Point-objects with different base-types - */ - template - Vector - convert() const; - - /** - * \brief Returns a perpendicular copy of the vector - * - * \return (y, -x) - */ - Vector - toOrthogonalVector() const; - - // TODO - Vector - perpendicular() const; - - /** - * \brief Check if three points are in a counter-clock wise direction - * - * Check if we move counter-clock wise if we move from the first point - * to the second and the third. - * - * If all three points are in a line there are three possibilities: - * 1) strait line: third point behind the second (returns 1) - * 2) last point between the other two (returns 0) - * 3) third point before the first one (returns -1) - * - * This definition is useful for inclusion or intersection testing. - */ - static int_fast8_t - ccw(const Vector& a, const Vector& b, const Vector& c); - - Vector& operator = (const Matrix &rhs); - - bool operator == (const Vector &rhs) const; - bool operator != (const Vector &rhs) const; - bool operator < (const Vector &rhs) const; - bool operator <= (const Vector &rhs) const; - bool operator > (const Vector &rhs) const; - bool operator >= (const Vector &rhs) const; - - const T& operator [] (uint8_t index) const; - T& operator [] (uint8_t index); - - T* ptr(); - const T* ptr() const; - - Vector operator - () const; - Vector operator - (const Vector &rhs) const; - Vector operator + (const Vector &rhs) const; - T operator * (const Vector &rhs) const; - T operator ^ (const Vector &rhs) const; - Vector operator * (float rhs) const; - Vector operator / (float rhs) const; - - Vector& operator += (const Vector &rhs); - Vector& operator -= (const Vector &rhs); - Vector& operator *= (const T &rhs); - Vector& operator /= (const T &rhs); - Vector& operator ~ (); - - Matrix& - asMatrix(); - - const Matrix& - asMatrix() const; - - Matrix& - asTransposedMatrix(); - - const Matrix& - asTransposedMatrix() const; - - bool hasNan() const; - bool hasInf() const; - - #ifndef __DOXYGEN__ - IMPLEMENT_VECTOR_ACCESSOR2(x,x); IMPLEMENT_VECTOR_ACCESSOR2(x,y); - IMPLEMENT_VECTOR_ACCESSOR2(y,x); IMPLEMENT_VECTOR_ACCESSOR2(y,y); - - IMPLEMENT_VECTOR_ACCESSOR3(x,x,x); IMPLEMENT_VECTOR_ACCESSOR3(x,x,y); - IMPLEMENT_VECTOR_ACCESSOR3(x,y,x); IMPLEMENT_VECTOR_ACCESSOR3(x,y,y); - IMPLEMENT_VECTOR_ACCESSOR3(y,x,x); IMPLEMENT_VECTOR_ACCESSOR3(y,x,y); - IMPLEMENT_VECTOR_ACCESSOR3(y,y,x); IMPLEMENT_VECTOR_ACCESSOR3(y,y,y); - - IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,y); - IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,y); - IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,y); - IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,y); - - IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,y); - IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,y); - IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,y); - IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,y); - #endif - - public: - T x; - T y; - - protected: - template - friend IOStream& - operator <<(IOStream& os, const Vector& c); - - template - friend Vector - operator * (float scale, const Vector &vector); - }; - - typedef Vector Vector2f; - typedef Vector Vector2i; - typedef Vector Vector2u; - - // ------------------------------------------------------------------------ - // Global functions - // ------------------------------------------------------------------------ - /** - * \brief Stream operator for \b modm::Vector - * \ingroup modm_math_geometry + * Other implementations take no arguments and returns a vector + * perpendicular to the input vector. This can be reached with the + * toOrthogonalVector() method, which returns a perpendicular copy + * of the vector. */ - template - IOStream& - operator << (IOStream& os, const Vector& c); + WideType cross(const Vector& other) const + { return WideType(x) * WideType(other.y) - WideType(y) * WideType(other.x); } - /** - * \brief Scalar multiplication - * \ingroup modm_math_geometry - */ - template - Vector - operator * (float scale, const Vector &vector); + Vector toOrthogonalVector() const + { return Vector(y, -x); } + + Vector perpendicular() const + { return Vector(y, -x); } /** - * \brief Scalar division - * \ingroup modm_math_geometry + * \brief Check if three points are in a counter-clock wise direction + * + * Check if we move counter-clock wise if we move from the first point + * to the second and the third. + * + * If all three points are in a line there are three possibilities: + * 1) strait line: third point behind the second (returns 1) + * 2) last point between the other two (returns 0) + * 3) third point before the first one (returns -1) + * + * This definition is useful for inclusion or intersection testing. */ - template - Vector - operator / (float scale, const Vector &vector); - - // ------------------------------------------------------------------------ - // Declaration of specialized methods - // ------------------------------------------------------------------------ - template<> - int16_t - Vector::getLength() const; + static int8_t + ccw(const Vector& a, const Vector& b, const Vector& c) { + const Vector v1 = b - a; + const Vector v2 = c - a; + const WideType d1 = v1.x * v2.y; + const WideType d2 = v1.y * v2.x; + + if (d1 > d2) + return 1; + else if (d1 < d2) + return -1; + else + { + if ((v1.x * v2.x < 0) || (v1.y * v2.y < 0)) + return -1; + else + return (v1.x * v1.x + v1.y * v1.y) < (v2.x * v2.x + v2.y * v2.y) ? 1 : 0; + } + } - template<> - int32_t - Vector::getLengthSquared() const; + bool hasNan() const { return std::isnan(x) || std::isnan(y); } + bool hasInf() const { return std::isinf(x) || std::isinf(y); } - template<> - int32_t - Vector::dot(const modm::Vector& other) const; +#ifndef __DOXYGEN__ + IMPLEMENT_VECTOR_ACCESSOR2(x,x); IMPLEMENT_VECTOR_ACCESSOR2(x,y); + IMPLEMENT_VECTOR_ACCESSOR2(y,x); IMPLEMENT_VECTOR_ACCESSOR2(y,y); + IMPLEMENT_VECTOR_ACCESSOR3(x,x,x); IMPLEMENT_VECTOR_ACCESSOR3(x,x,y); + IMPLEMENT_VECTOR_ACCESSOR3(x,y,x); IMPLEMENT_VECTOR_ACCESSOR3(x,y,y); + IMPLEMENT_VECTOR_ACCESSOR3(y,x,x); IMPLEMENT_VECTOR_ACCESSOR3(y,x,y); + IMPLEMENT_VECTOR_ACCESSOR3(y,y,x); IMPLEMENT_VECTOR_ACCESSOR3(y,y,y); - template<> template<> - Vector - Vector::convert() const; + IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,y); + IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,y); + IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,y); + IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,y); - template<> template<> - Vector - Vector::convert() const; + IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,y); + IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,y); + IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,y); + IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,y); +#endif - // round for everything that's not float => double or double => float - template<> template + // depricated methods + template + [[deprecated("Use common constructor instead!")]] Vector - Vector::convert() const - { - return Vector(round(this->x), round(this->y)); - } + convert() const { return {*this}; } - template<> template - Vector - Vector::convert() const - { - return Vector(round(this->x), round(this->y)); - } +protected: + template + friend Vector + operator* (float scale, const Vector &vector); + + template + friend IOStream& + operator<<(IOStream& os, const Vector& c); +}; + +/** + * \brief Scalar multiplication + * \ingroup modm_math_geometry + */ +template +Vector +operator* (float scale, const Vector &vector) +{ return vector * scale; } + +/** + * \brief Scalar division + * \ingroup modm_math_geometry + */ +template +Vector +operator/ (float scale, const Vector &vector) +{ return vector / scale; } + +#if __has_include() +#include + +template +IOStream& +operator<< (IOStream& os, const Vector& v) { + os << "x=" << v.x << "\ty=" << v.y; + return os; } +#endif -#include "vector2_impl.hpp" +using Vector2f = Vector; +using Vector2i = Vector; +using Vector2u = Vector; -#endif // MODM_VECTOR2_HPP +} // namespace modm \ No newline at end of file diff --git a/src/modm/math/geometry/vector2_impl.hpp b/src/modm/math/geometry/vector2_impl.hpp deleted file mode 100644 index b30f16be8e..0000000000 --- a/src/modm/math/geometry/vector2_impl.hpp +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2011, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_VECTOR2_HPP - #error "Don't include this file directly, use 'vector2.hpp' instead!" -#endif - -#include - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector() : - x(), - y() -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T& inX, const T& inY) : - x(inX), - y(inY) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector( - const modm::Vector &inX, - const modm::Vector &inY) : - x(inX.x), - y(inY.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY) : - x(inX), - y(inY.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY) : - x(inX.x), - y(inY) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(T inVal) : - x(inVal), - y(inVal) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Matrix &rhs) : - x(reinterpret_cast(&rhs)[0]), - y(reinterpret_cast(&rhs)[1]) -{ -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::set(const T& newX, const T& newY) -{ - this->x = newX; - this->y = newY; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::setX(const T& value) -{ - this->x = value; -} - -template -void -modm::Vector::setY(const T& value) -{ - this->y = value; -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::getX() const -{ - return this->x; -} - -template -const T& -modm::Vector::getY() const -{ - return this->y; -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::getLength() const -{ - float tx = this->x; - float ty = this->y; - - return GeometricTraits::round(std::sqrt(tx*tx + ty*ty)); -} - -// ---------------------------------------------------------------------------- -template -typename modm::Vector::WideType -modm::Vector::getLengthSquared() const -{ - WideType tx = static_cast(this->x); - WideType ty = static_cast(this->y); - - return tx * tx + ty * ty; -} - -// ---------------------------------------------------------------------------- -template -float -modm::Vector::getAngle() const -{ - return std::atan2(this->y, this->x); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::normalize() -{ - T length = this->getLength(); - - this->x = this->x / length; - this->y = this->y / length; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::normalized() const -{ - Vector a(*this); - a.normalize(); - return a; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::scale(float length) -{ - float factor = length / getLength(); - - this->x = this->x * factor; - this->y = this->y * factor; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::scaled(float length) const -{ - Vector a(*this); - a.scale(length); - return a; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::rotate(float phi) -{ - float c = std::cos(phi); - float s = std::sin(phi); - - // without rounding the result might be false for T = integer - T tx = GeometricTraits::round(c * this->x - s * this->y); - this->y = GeometricTraits::round(s * this->x + c * this->y); - this->x = tx; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::translate(const Vector& vector) -{ - this->x += vector.x; - this->y += vector.y; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -typename modm::Vector::WideType -modm::Vector::getDistanceTo(const Vector& other) const -{ - return (other - *this).getLength(); -} - -// ---------------------------------------------------------------------------- -template -float -modm::Vector::getAngleTo(const Vector& other) const -{ - return (other - *this).getAngle(); -} - -// ---------------------------------------------------------------------------- -template -typename modm::Vector::WideType -modm::Vector::dot(const modm::Vector& other) const -{ - return (static_cast(this->x) * static_cast(other.x) + - static_cast(this->y) * static_cast(other.y)); -} - -// ---------------------------------------------------------------------------- -template -typename modm::Vector::WideType -modm::Vector::cross(const modm::Vector& other) const -{ - return (static_cast(this->x) * static_cast(other.y) - - static_cast(this->y) * static_cast(other.x)); -} - -// ---------------------------------------------------------------------------- -template template -modm::Vector -modm::Vector::convert() const -{ - return Vector(static_cast(this->x), static_cast(this->y)); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::toOrthogonalVector() const -{ - return modm::Vector(y, -x); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::perpendicular() const -{ - return modm::Vector(y, -x); -} - -// ---------------------------------------------------------------------------- -template -int_fast8_t -modm::Vector::ccw(const Vector& a, const Vector& b, - const Vector& c) -{ - WideType dx1 = b.x - a.x; - WideType dy1 = b.y - a.y; - WideType dx2 = c.x - a.x; - WideType dy2 = c.y - a.y; - - WideType d1 = dx1 * dy2; - WideType d2 = dy1 * dx2; - - if (d1 > d2) { - return 1; - } - else if (d1 < d2) { - return -1; - } - else - { - if ((dx1 * dx2 < 0) || (dy1 * dy2 < 0)) { - return -1; - } - else - { - if ((dx1 * dx1 + dy1 * dy1) >= (dx2 * dx2 + dy2 * dy2)) { - return 0; - } - else { - return 1; - } - } - } -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& modm::Vector::operator = (const modm::Matrix &rhs) -{ - x = reinterpret_cast(&rhs)[0]; - y = reinterpret_cast(&rhs)[1]; - return *this; -} - -// ---------------------------------------------------------------------------- -template -bool modm::Vector::operator == (const modm::Vector &rhs) const -{ - return ((rhs.x == x) && (rhs.y == y)); -} - -// ---------------------------------------------------------------------------- -template -bool modm::Vector::operator != (const modm::Vector &rhs) const -{ - return ((rhs.x != x) || (rhs.y != y)); -} - -// ---------------------------------------------------------------------------- -template -bool modm::Vector::operator < (const modm::Vector &rhs) const -{ - return (x < rhs.x) || ((x == rhs.x) && (y < rhs.y)); -} - -// ---------------------------------------------------------------------------- -template -bool modm::Vector::operator <= (const modm::Vector &rhs) const -{ - return (x < rhs.x) || ((x == rhs.x) && (y <= rhs.y)); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator > (const modm::Vector &rhs) const -{ - return (x > rhs.x) || ((x == rhs.x) && (y > rhs.y)); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator >= (const modm::Vector &rhs) const -{ - return (x > rhs.x) || ((x == rhs.x) && (y >= rhs.y)); -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::operator [] (uint8_t index) const -{ - return reinterpret_cast(this)[index]; -} - -// ---------------------------------------------------------------------------- -template -T& -modm::Vector::operator [] (uint8_t index) -{ - return reinterpret_cast(this)[index]; -} - -// ---------------------------------------------------------------------------- -template -T* -modm::Vector::ptr() -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -const T* -modm::Vector::ptr() const -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - () const -{ - return Vector(-x, -y); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - (const modm::Vector &rhs) const -{ - return modm::Vector(x - rhs.x, y - rhs.y); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator + (const modm::Vector &rhs) const -{ - return modm::Vector(x + rhs.x, y + rhs.y); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::operator * (const modm::Vector &rhs) const -{ - return (x * rhs.x + y * rhs.y); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::operator ^ (const modm::Vector &rhs) const -{ - return (x * rhs.y - y * rhs.x); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator * (float scale) const -{ - return Vector(GeometricTraits::round(this->x * scale), - GeometricTraits::round(this->y * scale)); -} - -template -modm::Vector -modm::Vector::operator / (float scale) const -{ - return Vector(GeometricTraits::round(this->x / scale), - GeometricTraits::round(this->y / scale)); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator += (const modm::Vector &rhs) -{ - x += rhs.x; - y += rhs.y; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator -= (const modm::Vector &rhs) -{ - x -= rhs.x; - y -= rhs.y; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator *= (const T &rhs) -{ - x *= rhs; - y *= rhs; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator /= (const T &rhs) -{ - x /= rhs; - y /= rhs; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator ~ () -{ - *this = perpendicular(); - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asMatrix() -{ - return *((modm::Matrix *) this); -} - -template -const modm::Matrix& -modm::Vector::asMatrix() const -{ - return *((modm::Matrix *) this); -} -//----------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asTransposedMatrix() -{ - return *((modm::Matrix *) this); -} - -template -const modm::Matrix& -modm::Vector::asTransposedMatrix() const -{ - return *((modm::Matrix *) this); -} - -// ---------------------------------------------------------------------------- -template -bool modm::Vector::hasNan() const -{ - return std::isnan(x) || std::isnan(y); -} - -// ---------------------------------------------------------------------------- -template -bool modm::Vector::hasInf() const -{ - return std::isinf(x) || std::isinf(y); -} - -// ---------------------------------------------------------------------------- -// Global functions -// ---------------------------------------------------------------------------- -template -modm::IOStream& -modm::operator << (modm::IOStream& s, const modm::Vector& c) -{ - s << "x=" << c.x << ", y=" << c.y; - return s; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::operator * (float scale, const Vector &vector) -{ - // invoke member function - return vector * scale; -} - -template -modm::Vector -modm::operator / (float scale, const Vector &vector) -{ - // invoke member function - return vector / scale; -} - diff --git a/src/modm/math/geometry/vector3.hpp b/src/modm/math/geometry/vector3.hpp index 6287ee671b..2003fa6bb9 100644 --- a/src/modm/math/geometry/vector3.hpp +++ b/src/modm/math/geometry/vector3.hpp @@ -2,6 +2,7 @@ * Copyright (c) 2011-2012, Fabian Greif * Copyright (c) 2012, Georgi Grinshpun * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -11,208 +12,333 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_VECTOR3_HPP -#define MODM_VECTOR3_HPP +#pragma once -#include +#include #include "vector.hpp" namespace modm { - /** - * \brief Class for handling common vector operations (3D) - * - * + : addition of points - * - : different of points - * * : dot product or scalar multiplication - * / : scalar division - * ^ : cross product (determinant) - * - * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). - * - * \see Homepage - * - * \ingroup modm_math_geometry - * \author Niklas Hauser - */ - template - class Vector - { - public: - Vector(); +/** + * \brief Class for handling common vector operations (3D) + * + * + : addition of points + * - : different of points + * * : dot product or scalar multiplication + * / : scalar division + * ^ : cross product (determinant) + * + * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). + * + * \see Homepage + * + * \author Niklas Hauser + * \author Thomas Sommer + * \ingroup modm_math_geometry + */ +template +class Vector +{ + using VecT1 = Vector; + using VecT2 = Vector; + using VecT3 = Vector; + +public: + using WideType = GeometricTraits::WideType; + using WideWideType = GeometricTraits::WideType; + using FloatType = GeometricTraits::FloatType; + + T x{0}, y{0}, z{0}; + + // fundamental constructors + constexpr Vector() = default; + + constexpr explicit Vector(T xyz) + : x(xyz), y(xyz), z(xyz) {} + + template + requires std::integral && std::floating_point + constexpr explicit Vector(T xyz) + : x(std::round(xyz)), y(std::round(xyz)), z(std::round(xyz)) {} + + constexpr Vector(T x, T y, T z) + : x(x), y(y), z(z) {} + + template + requires std::integral && std::floating_point + constexpr Vector(U x, U y, U z) + : x(std::round(x)), y(std::round(y)), z(std::round(z)) {} + + template + constexpr Vector(const Vector &v) : Vector(v.x, v.y, v.z) {} + + // vector constructors + constexpr Vector(VecT1 vx, T y, T z) : Vector(vx.x, y, z) {} + constexpr Vector(T x, VecT1 vy, T z) : Vector(x, vy.x, z) {} + constexpr Vector(T x, T y, VecT1 vz) : Vector(x, y, vz.x) {} + + constexpr Vector(VecT1 vx, T y, VecT1 vz) : Vector(vx.x, y, vz.x) {} + constexpr Vector(VecT1 vx, VecT1 vy, T z) : Vector(vx.x, vy.x, z) {} + constexpr Vector(T x, VecT1 vy, VecT1 vz) : Vector(x, vy.x, vz.x) {} + + constexpr Vector(VecT1 vx, VecT1 vy, VecT1 vz) : Vector(vx.x, vy.x, vz.x) {} + + constexpr Vector(Vector vxy, T z) : Vector(vxy.x, vxy.y, z) {} + constexpr Vector(T x, VecT2 vyz) : Vector(x, vyz.x, vyz.y) {} + + constexpr Vector(VecT2 vxy, VecT1 vz) : Vector(vxy.x, vxy.y, vz.x) {} + constexpr Vector(VecT1 vx, VecT2 vyz) : Vector(vx.x, vyz.x, vyz.y) {} + + // matrix constructors + constexpr Vector(const Matrix &rhs) + : x(reinterpret_cast(&rhs)[0]), + y(reinterpret_cast(&rhs)[1]), + z(reinterpret_cast(&rhs)[2]) + {} + + // array constructors + template + constexpr explicit Vector(U *array) : Vector(array[0], array[1], array[2]) {} + + // as matrix convertors + Matrix& + asMatrix() { return *(Matrix*)this; } + + const Matrix& + asMatrix() const { return *(Matrix*)this; } + + Matrix& + asTransposedMatrix() { return *(Matrix*)this; } + + const Matrix& + asTransposedMatrix() const { return *(Matrix*)this; } + + // matrix assignment + Vector& operator= (const Matrix &rhs) { + x = reinterpret_cast(&rhs)[0]; + y = reinterpret_cast(&rhs)[1]; + z = reinterpret_cast(&rhs)[2]; + + return *this; + } + + // getters + T getX() const { return x; } + T getY() const { return y; } + T getZ() const { return z; } + + // setters + void setX(T x) { this->x = x; } + + template + requires std::integral && std::floating_point + void setX(U x) { this->x = std::round(x); } - template - explicit Vector(const U *array); - explicit Vector(T inVal); - Vector(T inX, T inY, T inZ); + void setY(T y) { this->y = y; } - Vector(const Vector &inX, const T &inY, const T &inZ); - Vector(const T &inX, const Vector &inY, const T &inZ); - Vector(const T &inX, const T &inY, const Vector &inZ); + template + requires std::integral && std::floating_point + void setY(U y) { this->x = std::round(y); } - Vector(const Vector &inX, const T &inY, const Vector &inZ); - Vector(const Vector &inX, const Vector &inY, const T &inZ); - Vector(const T &inX, const Vector &inY, const Vector &inZ); - Vector(const Vector &inX, const Vector &inY, const Vector &inZ); + void setZ(T z) { this->z = z; } - Vector(const Vector &inXY, const T &inZ); - Vector(const T &inX, const Vector &inYZ); + template + requires std::integral && std::floating_point + void setZ(U z) { this->z = std::round(z); } - Vector(const Vector &inXY, const Vector &inZ); - Vector(const Vector &inX, const Vector &inYZ); - - template - Vector(const Vector &rhs); - Vector(const Matrix &rhs); - - - inline void - set(const T& x, const T& y, const T& z); - - - inline void - setX(const T& value); - - inline void - setY(const T& value); - - inline void - setZ(const T& value); - - - inline const T& - getX() const; - - inline const T& - getY() const; - - inline const T& - getZ() const; - - - Vector& operator = (const Matrix &rhs); - - bool operator == (const Vector &rhs) const; - bool operator != (const Vector &rhs) const; - bool operator < (const Vector &rhs) const; - bool operator <= (const Vector &rhs) const; - bool operator > (const Vector &rhs) const; - bool operator >= (const Vector &rhs) const; - - const T& operator [] (uint8_t index) const; - T& operator [] (uint8_t index); - T* ptr(); - const T* ptr() const; - - Vector operator - () const; - Vector operator + (const Vector &rhs) const; - Vector operator - (const Vector &rhs) const; - T operator * (const Vector &rhs) const; - Vector operator ^ (const Vector &rhs) const; - Vector operator * (const T &rhs) const; - Vector operator / (const T &rhs) const; - - Vector& operator += (const Vector &rhs); - Vector& operator -= (const Vector &rhs); - Vector& operator *= (const T &rhs); - Vector& operator /= (const T &rhs); - - float getLength() const; - float getLengthSquared() const; - - Vector scaled(float newLength) const; - void scale(float newLength); - - Vector normalized() const; - void normalize(); - - Matrix& - asMatrix(); - - const Matrix& - asMatrix() const; - - Matrix& - asTransposedMatrix(); - - const Matrix& - asTransposedMatrix() const; - - bool hasNan() const; - bool hasInf() const; - - #ifndef __DOXYGEN__ - IMPLEMENT_VECTOR_ACCESSOR2(x,x); IMPLEMENT_VECTOR_ACCESSOR2(x,y); IMPLEMENT_VECTOR_ACCESSOR2(x,z); - IMPLEMENT_VECTOR_ACCESSOR2(y,x); IMPLEMENT_VECTOR_ACCESSOR2(y,y); IMPLEMENT_VECTOR_ACCESSOR2(y,z); - IMPLEMENT_VECTOR_ACCESSOR2(z,x); IMPLEMENT_VECTOR_ACCESSOR2(z,y); IMPLEMENT_VECTOR_ACCESSOR2(z,z); - - IMPLEMENT_VECTOR_ACCESSOR3(x,x,x); IMPLEMENT_VECTOR_ACCESSOR3(x,x,y); IMPLEMENT_VECTOR_ACCESSOR3(x,x,z); - IMPLEMENT_VECTOR_ACCESSOR3(x,y,x); IMPLEMENT_VECTOR_ACCESSOR3(x,y,y); IMPLEMENT_VECTOR_ACCESSOR3(x,y,z); - IMPLEMENT_VECTOR_ACCESSOR3(x,z,x); IMPLEMENT_VECTOR_ACCESSOR3(x,z,y); IMPLEMENT_VECTOR_ACCESSOR3(x,z,z); - IMPLEMENT_VECTOR_ACCESSOR3(y,x,x); IMPLEMENT_VECTOR_ACCESSOR3(y,x,y); IMPLEMENT_VECTOR_ACCESSOR3(y,x,z); - IMPLEMENT_VECTOR_ACCESSOR3(y,y,x); IMPLEMENT_VECTOR_ACCESSOR3(y,y,y); IMPLEMENT_VECTOR_ACCESSOR3(y,y,z); - IMPLEMENT_VECTOR_ACCESSOR3(y,z,x); IMPLEMENT_VECTOR_ACCESSOR3(y,z,y); IMPLEMENT_VECTOR_ACCESSOR3(y,z,z); - IMPLEMENT_VECTOR_ACCESSOR3(z,x,x); IMPLEMENT_VECTOR_ACCESSOR3(z,x,y); IMPLEMENT_VECTOR_ACCESSOR3(z,x,z); - IMPLEMENT_VECTOR_ACCESSOR3(z,y,x); IMPLEMENT_VECTOR_ACCESSOR3(z,y,y); IMPLEMENT_VECTOR_ACCESSOR3(z,y,z); - IMPLEMENT_VECTOR_ACCESSOR3(z,z,x); IMPLEMENT_VECTOR_ACCESSOR3(z,z,y); IMPLEMENT_VECTOR_ACCESSOR3(z,z,z); - - IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,y); IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,y); IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,y); IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,y); IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,y); IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,y); IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,y); IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,y); IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,x); IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,y); IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,z); - - IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,y); IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,y); IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,y); IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,y); IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,y); IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,y); IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,y); IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,y); IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,x); IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,y); IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,z); - - IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,y); IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,y); IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,x); IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,y); IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,y); IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,y); IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,x); IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,y); IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,x); IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,y); IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,x); IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,y); IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,z); - IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,x); IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,y); IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,z); - #endif - - public: - T x; - T y; - T z; - }; - - template - static inline Vector operator * (const U &lhs, const Vector &rhs) - { - return rhs * lhs; + + void set(T x, T y, T z) { + this->x = x; + this->y = y; + this->z = z; } - template - static inline Vector operator * (const Matrix &lhs, const Vector &rhs) - { - return lhs * rhs.asMatrix(); + template + requires std::integral && std::floating_point + void set(U x, U y, U z) { + this->x = std::round(x); + this->y = std::round(y); + this->z = std::round(z); } + // accessors + T& operator [] (std::size_t index) + { return reinterpret_cast(this)[index]; } + + const T& operator [] (std::size_t index) const + { return reinterpret_cast(this)[index]; } + + T* ptr() { return reinterpret_cast(this); } + + const T* ptr() const { return reinterpret_cast(this); } + + // operators + auto operator<=>(const Vector&) const = default; + + constexpr Vector operator+ (const Vector &rhs) const + { return Vector(x + rhs.x, y + rhs.y, z + rhs.z); } + + constexpr Vector operator- (const Vector &rhs) const + { return Vector(x - rhs.x, y - rhs.y, z - rhs.z); } + + constexpr T operator* (const Vector &rhs) const + { return x * rhs.x + y * rhs.y + z * rhs.z; } + + constexpr Vector operator^ (const Vector &rhs) const + { return Vector(y * rhs.z-z * rhs.y, z * rhs.x-x * rhs.z, x * rhs.y-y * rhs.x); } + + template + constexpr Vector operator* (U scale) const + { return Vector(x * scale, y * scale, z * scale); } + + template + constexpr Vector operator/ (U scale) const + { return Vector(x / scale, y / scale, z / scale); } + + Vector& operator += (const Vector &rhs) + { x += rhs.x; y += rhs.y; z += rhs.z; return *this; } + + Vector& operator -= (const Vector &rhs) + { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; } + + template + Vector& operator *= (U scale) + { x *= scale; y *= scale; z *= scale; return *this; } + + template + Vector& operator /= (U scale) + { x /= scale; y /= scale; z /= scale; return *this; } + + // template + // requires std::is_signed::value + constexpr Vector operator- () const + { return Vector(-x, -y, -z); } + + // additional methods + T getLength() const + { return std::sqrt(getLengthSquared()); } + + T getLength() const + requires std::integral + { return round(std::sqrt(getLengthSquared())); } + + WideWideType getLengthSquared() const + { return std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2); } + + Vector scaled(float newLength) const { + float scale = newLength / getLength(); + return *this * scale; + } + + void scale(float newLength) + { *this = scaled(newLength); } + + Vector normalized() const { return scaled(1.0f); } + void normalize() { scale(1.0); } + + bool hasNan() const { return std::isnan(x) || std::isnan(y) || std::isnan(z); } + bool hasInf() const { return std::isinf(x) || std::isinf(y) || std::isinf(z); } + +#ifndef __DOXYGEN__ + IMPLEMENT_VECTOR_ACCESSOR2(x,x); IMPLEMENT_VECTOR_ACCESSOR2(x,y); IMPLEMENT_VECTOR_ACCESSOR2(x,z); + IMPLEMENT_VECTOR_ACCESSOR2(y,x); IMPLEMENT_VECTOR_ACCESSOR2(y,y); IMPLEMENT_VECTOR_ACCESSOR2(y,z); + IMPLEMENT_VECTOR_ACCESSOR2(z,x); IMPLEMENT_VECTOR_ACCESSOR2(z,y); IMPLEMENT_VECTOR_ACCESSOR2(z,z); + + IMPLEMENT_VECTOR_ACCESSOR3(x,x,x); IMPLEMENT_VECTOR_ACCESSOR3(x,x,y); IMPLEMENT_VECTOR_ACCESSOR3(x,x,z); + IMPLEMENT_VECTOR_ACCESSOR3(x,y,x); IMPLEMENT_VECTOR_ACCESSOR3(x,y,y); IMPLEMENT_VECTOR_ACCESSOR3(x,y,z); + IMPLEMENT_VECTOR_ACCESSOR3(x,z,x); IMPLEMENT_VECTOR_ACCESSOR3(x,z,y); IMPLEMENT_VECTOR_ACCESSOR3(x,z,z); + IMPLEMENT_VECTOR_ACCESSOR3(y,x,x); IMPLEMENT_VECTOR_ACCESSOR3(y,x,y); IMPLEMENT_VECTOR_ACCESSOR3(y,x,z); + IMPLEMENT_VECTOR_ACCESSOR3(y,y,x); IMPLEMENT_VECTOR_ACCESSOR3(y,y,y); IMPLEMENT_VECTOR_ACCESSOR3(y,y,z); + IMPLEMENT_VECTOR_ACCESSOR3(y,z,x); IMPLEMENT_VECTOR_ACCESSOR3(y,z,y); IMPLEMENT_VECTOR_ACCESSOR3(y,z,z); + IMPLEMENT_VECTOR_ACCESSOR3(z,x,x); IMPLEMENT_VECTOR_ACCESSOR3(z,x,y); IMPLEMENT_VECTOR_ACCESSOR3(z,x,z); + IMPLEMENT_VECTOR_ACCESSOR3(z,y,x); IMPLEMENT_VECTOR_ACCESSOR3(z,y,y); IMPLEMENT_VECTOR_ACCESSOR3(z,y,z); + IMPLEMENT_VECTOR_ACCESSOR3(z,z,x); IMPLEMENT_VECTOR_ACCESSOR3(z,z,y); IMPLEMENT_VECTOR_ACCESSOR3(z,z,z); + + IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,y); IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,y); IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,x); IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,y); IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,y); IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,y); IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,x); IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,y); IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,x); IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,y); IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,x); IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,y); IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,x); IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,y); IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,z); + + IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,y); IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,y); IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,x); IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,y); IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,y); IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,y); IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,x); IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,y); IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,x); IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,y); IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,x); IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,y); IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,x); IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,y); IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,z); + + IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,x); IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,y); IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,x); IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,y); IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,x); IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,y); IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,x); IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,y); IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,x); IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,y); IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,x); IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,y); IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,x); IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,y); IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,x); IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,y); IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,z); + IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,x); IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,y); IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,z); +#endif + + // depricated methods + template + [[deprecated("Use common constructor instead!")]] + Vector + convert() const { return {*this}; } + +protected: + template + friend IOStream& + operator<<(IOStream& os, const Vector& c); +}; + +template +static inline Vector operator * (const U &lhs, const Vector &rhs) +{ + return rhs * lhs; +} + +template +static inline Vector operator * (const Matrix &lhs, const Vector &rhs) +{ + return lhs * rhs.asMatrix(); +} - typedef Vector Vector3f; - typedef Vector Vector3i; - typedef Vector Vector3u; +// TODO Whats with these? +// template +// static inline Vector +// operator * (const T &lhs, const Vector &rhs) +// { +// return rhs * lhs; +// } + +// template +// static inline Vector +// operator * (const Matrix &lhs, const Vector &rhs) +// { +// return lhs * rhs.asTMatrix(); +// } + +#if __has_include() +#include + +template +IOStream& +operator<< (IOStream& os, const Vector& v) { + os << "x=" << v.x << "\ty=" << v.y << "\tz=" << v.z; + return os; } +#endif -#include "vector3_impl.hpp" +using Vector3f = Vector; +using Vector3i = Vector; +using Vector3u = Vector; -#endif // MODM_VECTOR3_HPP +} // namespace modm \ No newline at end of file diff --git a/src/modm/math/geometry/vector3_impl.hpp b/src/modm/math/geometry/vector3_impl.hpp deleted file mode 100644 index 70b37af96d..0000000000 --- a/src/modm/math/geometry/vector3_impl.hpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (c) 2011-2012, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_VECTOR3_HPP - #error "Don't include this file directly, use 'vector3.hpp' instead!" -#endif - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector() : - x(), - y(), - z() -{ -} - -// ---------------------------------------------------------------------------- -template -template -modm::Vector::Vector(const U *array) : - x(array[0]), - y(array[1]), - z(array[2]) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(T inX, T inY, T inZ) : - x(inX), - y(inY), - z(inZ) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, - const modm::Vector &inY, - const modm::Vector &inZ) : - x(inX.x), - y(inY.x), - z(inZ.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, - const modm::Vector &inY, - const modm::Vector &inZ) : - x(inX), - y(inY.x), - z(inZ.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const modm::Vector &inZ) : - x(inX.x), - y(inY), - z(inZ.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inY, const T &inZ) -: - x(inX.x), - y(inY.x), - z(inZ) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const T &inZ) : - x(inX.x), - y(inY), - z(inZ) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY, const T &inZ) : - x(inX), - y(inY.x), - z(inZ) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const T &inY, const modm::Vector &inZ) : - x(inX), - y(inY), - z(inZ.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const T &inZ) : - x(inXY.x), - y(inXY.y), - z(inZ) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const modm::Vector &inZ) : - x(inXY.x), - y(inXY.y), - z(inZ.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inYZ) : - x(inX), - y(inYZ.x), - z(inYZ.y) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inYZ) : - x(inX.x), - y(inYZ.x), - z(inYZ.y) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(T inVal) : - x(inVal), - y(inVal), - z(inVal) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Matrix &rhs) : - x(reinterpret_cast(&rhs)[0]), - y(reinterpret_cast(&rhs)[1]), - z(reinterpret_cast(&rhs)[2]) -{ -} - -// ---------------------------------------------------------------------------- -template -template -modm::Vector::Vector(const modm::Vector &rhs) : - x(rhs.x), - y(rhs.y), - z(rhs.z) -{ -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::set(const T& x, const T& y, const T& z) -{ - this->x = x; - this->y = y; - this->z = z; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::setX(const T& value) -{ - this->x = value; -} - -template -void -modm::Vector::setY(const T& value) -{ - this->y = value; -} - -template -void -modm::Vector::setZ(const T& value) -{ - this->z = value; -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::getX() const -{ - return this->x; -} - -template -const T& -modm::Vector::getY() const -{ - return this->y; -} - -template -const T& -modm::Vector::getZ() const -{ - return this->z; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator = (const modm::Matrix &rhs) -{ - x = reinterpret_cast(&rhs)[0]; - y = reinterpret_cast(&rhs)[1]; - z = reinterpret_cast(&rhs)[2]; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator == (const Vector &rhs) const -{ - return (rhs.x == x) && (rhs.y == y) && (rhs.z == z); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator != (const Vector &rhs) const -{ - return (rhs.x != x) || (rhs.y != y) || (rhs.z != z); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator < (const Vector &rhs) const -{ - return (x < rhs.x) || ((x == rhs.x) && ((y < rhs.y) || ((y == rhs.y) && (z < rhs.z)))); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator <= (const Vector &rhs) const -{ - return (x < rhs.x) || ((x == rhs.x) && ((y < rhs.y) || ((y == rhs.y) && (z <= rhs.z)))); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator > (const Vector &rhs) const -{ - return (x > rhs.x) || ((x == rhs.x) && ((y > rhs.y) || ((y == rhs.y) && (z > rhs.z)))); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator >= (const Vector &rhs) const -{ - return (x > rhs.x) || ((x == rhs.x) && ((y > rhs.y) || ((y == rhs.y) && (z >= rhs.z)))); -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::operator [] (uint8_t index) const -{ - return reinterpret_cast(this)[index]; -} - -// ---------------------------------------------------------------------------- -template -T& -modm::Vector::operator [] (uint8_t index) -{ - return reinterpret_cast(this)[index]; -} - - -// ---------------------------------------------------------------------------- -template -T* -modm::Vector::ptr() -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -const T* -modm::Vector::ptr() const -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator + (const modm::Vector &rhs) const -{ - return modm::Vector(x+rhs.x, y+rhs.y, z+rhs.z); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - (const modm::Vector &rhs) const -{ - return modm::Vector(x-rhs.x, y-rhs.y, z-rhs.z); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::operator * (const modm::Vector &rhs) const -{ - return x*rhs.x + y*rhs.y + z*rhs.z; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator ^ (const modm::Vector &rhs) const -{ - return modm::Vector(y*rhs.z-z*rhs.y, z*rhs.x-x*rhs.z, x*rhs.y-y*rhs.x); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator * (const T &rhs) const -{ - return modm::Vector(x*rhs, y*rhs, z*rhs); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator / (const T &rhs) const -{ - return modm::Vector(x/rhs, y/rhs, z/rhs); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator += (const modm::Vector &rhs) -{ - x += rhs.x; - y += rhs.y; - z += rhs.z; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator -= (const modm::Vector &rhs) -{ - x -= rhs.x; - y -= rhs.y; - z -= rhs.z; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator *= (const T &rhs) -{ - x *= rhs; - y *= rhs; - z *= rhs; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator /= (const T &rhs) -{ - x /= rhs; - y /= rhs; - z /= rhs; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - () const -{ - return modm::Vector(-x, -y, -z); -} - -// ---------------------------------------------------------------------------- -template -float -modm::Vector::getLength() const -{ - return std::sqrt(getLengthSquared()); -} - -// ---------------------------------------------------------------------------- -template -float -modm::Vector::getLengthSquared() const -{ - return x*x+y*y+z*z; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::scale(float newLength) -{ - *this = scaled(newLength); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::scaled(float newLength) const -{ - float scale = newLength/getLength(); - return *this * scale; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::normalize() -{ - scale(1.0); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::normalized() const -{ - return scaled(1.0f); -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asMatrix() -{ - return *(modm::Matrix*)this; -} - -// ---------------------------------------------------------------------------- -template -const modm::Matrix& -modm::Vector::asMatrix() const -{ - return *(modm::Matrix*)this; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asTransposedMatrix() -{ - return *(modm::Matrix*)this; -} - -// ---------------------------------------------------------------------------- -template -const modm::Matrix& -modm::Vector::asTransposedMatrix() const -{ - return *(modm::Matrix*)this; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::hasNan() const -{ - return std::isnan(x) || std::isnan(y) || std::isnan(z); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::hasInf() const -{ - return std::isinf(x) || std::isinf(y) || std::isinf(z); -} - -// ---------------------------------------------------------------------------- -//template -//static inline modm::Vector operator * (const T &lhs, const modm::Vector &rhs) -//{ -// return rhs * lhs; -//} -// -// -//// ---------------------------------------------------------------------------- -//template -//static inline modm::Vector operator * (const modm::Matrix &lhs, const modm::Vector &rhs) -//{ -// return lhs * rhs.asTMatrix(); -//} diff --git a/src/modm/math/geometry/vector4.hpp b/src/modm/math/geometry/vector4.hpp index c91bcbed9d..f9b0416fb7 100644 --- a/src/modm/math/geometry/vector4.hpp +++ b/src/modm/math/geometry/vector4.hpp @@ -2,6 +2,7 @@ * Copyright (c) 2011-2012, Fabian Greif * Copyright (c) 2012, Georgi Grinshpun * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2022, Thomas Sommer * * This file is part of the modm project. * @@ -11,252 +12,377 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_VECTOR4_HPP -#define MODM_VECTOR4_HPP +#pragma once -#include +#include #include "vector.hpp" namespace modm { - /** - * \brief Class for handling common vector operations (4D) - * - * + : addition of points - * - : different of points - * * : dot product or scalar multiplication - * / : scalar division - * - * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). - * - * \see Homepage - * - * \ingroup modm_math_geometry - * \author Niklas Hauser - */ - template - class Vector - { - public: - Vector(); - - explicit Vector(T inVal); - Vector(T inX, T inY, T inZ, T inW); - - Vector(const Vector &inX, const Vector &inY, const Vector &inZ, const Vector &inW); - Vector(const Vector &inX, const Vector &inY, const Vector &inZ, const T &inW); - Vector(const Vector &inX, const Vector &inY, const T &inZ, const T &inW); - Vector(const Vector &inX, const T &inY, const Vector &inZ, const T &inW); - Vector(const T &inX, const Vector &inY, const Vector &inZ, const T &inW); - Vector(const Vector &inX, const T &inY, const T &inZ, const T &inW); - Vector(const T &inX, const Vector &inY, const T &inZ, const T &inW); - Vector(const Vector &inX, const Vector &inY, const T &inZ, const Vector &inW); - Vector(const Vector &inX, const T &inY, const T &inZ, const Vector &inW); - Vector(const T &inX, const Vector &inY, const T &inZ, const Vector &inW); - Vector(const T &inX, const T &inY, const T &inZ, const Vector &inW); - Vector(const Vector &inX, const T &inY, const Vector &inZ, const Vector &inW); - Vector(const T &inX, const T &inY, const Vector &inZ, const Vector &inW); - Vector(const T &inX, const Vector &inY, const Vector &inZ, const Vector &inW); +/** + * \brief Class for handling common vector operations (4D) + * + * + : addition of points + * - : different of points + * * : dot product or scalar multiplication + * / : scalar division + * + * Adapted from the implementation of Gaspard Petit (gaspardpetit@gmail.com). + * + * \see Homepage + * + * \author Niklas Hauser + * \author Thomas Sommer + * \ingroup modm_math_geometry + */ +template +class Vector +{ + using VecT1 = Vector; + using VecT2 = Vector; + using VecT3 = Vector; + using VecT4 = Vector; + +public: + using WideType = GeometricTraits::WideType; + using WideWideType = GeometricTraits::WideType; + using FloatType = GeometricTraits::FloatType; + + T x{0}, y{0}, z{0}, w{0}; + + // basic constructors + constexpr Vector() = default; + + constexpr explicit Vector(T xyzw) + : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {} + + template + requires std::integral && std::floating_point + constexpr explicit Vector(T xyzw) + : x(std::round(xyzw)), y(std::round(xyzw)), z(std::round(xyzw)), w(std::round(xyzw)) {} + + constexpr Vector(T x, T y, T z, T w) + : x(x), y(y), z(z), w(w) {} + + template + requires std::integral && std::floating_point + constexpr Vector(U x, U y, U z, U w) + : x(std::round(x)), y(std::round(y)), z(std::round(z)), w(std::round(w)) {} + + template + constexpr Vector(const Vector &v) : Vector(v.x, v.y, v.z, v.w) {} + + // vector constructors + constexpr Vector(VecT1 vx, VecT1 vy, VecT1 vz, VecT1 vw) : Vector(vx.x, vy.x, vz.x, vw.x) {} + constexpr Vector(VecT1 vx, VecT1 vy, VecT1 vz, T w) : Vector(vx.x, vy.x, vz.x, w) {} + constexpr Vector(VecT1 vx, VecT1 vy, T z, T w) : Vector(vx.x, vy.x, z, w) {} + constexpr Vector(VecT1 vx, T y, VecT1 vz, T w) : Vector(vx.x, y, vz.x, w) {} + constexpr Vector(T x, VecT1 vy, VecT1 vz, T w) : Vector(x, vy.x, vz.x, w) {} + constexpr Vector(VecT1 vx, T y, T z, T w) : Vector(vx.x, y, z, w) {} + constexpr Vector(T x, VecT1 vy, T z, T w) : Vector(x, vy.x, z, w) {} + constexpr Vector(VecT1 vx, VecT1 vy, T z, VecT1 vw) : Vector(vx.x, vy.x, z, vw.x) {} + constexpr Vector(VecT1 vx, T y, T z, VecT1 vw) : Vector(vx.x, y, z, vw.x) {} + constexpr Vector(T x, VecT1 vy, T z, VecT1 vw) : Vector(x, vy.x, z, vw.x) {} + constexpr Vector(T x, T y, T z, VecT1 vw) : Vector(x, y, z, vw.x) {} + constexpr Vector(VecT1 vx, T y, VecT1 vy, VecT1 vz, VecT1 vw) : Vector(vx.x, y, vy.x, vz.x, vw.x) {} + constexpr Vector(T x, T y, VecT1 vz, VecT1 vw) : Vector(x, y, vz.x, vw.x) {} + constexpr Vector(T x, VecT1 vy, VecT1 vz, VecT1 vw) : Vector(x, vy.x, vz.x, vw.x) {} + + constexpr Vector(VecT2 vxy, VecT1 vz, VecT1 vw) : Vector(vxy.x, vxy.y, vz.x, vw.x) {} + constexpr Vector(VecT2 vxy, VecT1 vz, T w) : Vector(vxy.x, vxy.y, vz.x, w) {} + constexpr Vector(VecT2 vxy, T z, T w) : Vector(vxy.x, vxy.y, z, w) {} + constexpr Vector(VecT2 vxy, T z, VecT1 w) : Vector(vxy.x, vxy.y, z, w.x) {} + + constexpr Vector(VecT1 vx, VecT2 vyz, VecT1 vw) : Vector(vx.x, vyz.x, vyz.y, vw.x) {} + constexpr Vector(VecT1 vx, VecT2 vyz, T w) : Vector(vx.x, vyz.x, vyz.y, w) {} + constexpr Vector(T x, VecT2 vyz, T w) : Vector(x, vyz.x, vyz.y, w) {} + constexpr Vector(T x, VecT2 vyz, VecT1 vw) : Vector(x, vyz.x, vyz.y, vw.x) {} + + constexpr Vector(VecT1 vx, VecT1 vy, VecT2 vzw) : Vector(vx.x, vy.x, vzw.x, vzw.y) {} + constexpr Vector(VecT1 vx, T y, VecT2 vzw) : Vector(vx.x, y, vzw.x, vzw.y) {} + constexpr Vector(T x, T y, VecT2 vzw) : Vector(x, y, vzw.x, vzw.y) {} + constexpr Vector(T x, VecT1 vy, VecT2 vzw) : Vector(x, vy.x, vzw.x, vzw.y) {} + + constexpr Vector(VecT2 vxy, VecT2 vzw) : Vector(vxy.x, vxy.y, vzw.x, vzw.y) {} + + constexpr Vector(const VecT3 &vxyz, T w) : Vector(vxyz.x, vxyz.y, vxyz.z, w) {} + constexpr Vector(const VecT3 &vxyz, VecT1 vw) : Vector(vxyz.x, vxyz.y, vxyz.z, vw.x) {} + + constexpr Vector(VecT1 vx, const VecT3 &vyzw) : Vector(vx.x, vyzw.x, vyzw.y, vyzw.z) {} + constexpr Vector(T x, const VecT3 &vyzw) : Vector(x, vyzw.x, vyzw.y, vyzw.z) {} + + // matrix constructors + constexpr Vector(const Matrix &rhs) + : x(reinterpret_cast(&rhs)[0]), + y(reinterpret_cast(&rhs)[1]), + z(reinterpret_cast(&rhs)[2]), + w(reinterpret_cast(&rhs)[3]) + {} + + // array constructors + template + constexpr explicit Vector(U *array) : Vector(array[0], array[1], array[2], array[3]) {} + + // as matrix convertors + Matrix& + asMatrix() { return *(Matrix*)this; } + + const Matrix& + asMatrix() const { return *(Matrix*)this; } + + Matrix& + asTransposedMatrix() { return *(Matrix*)this; } + + const Matrix& + asTransposedMatrix() const { return *(Matrix*)this; } + + // matrix assignment + Vector& operator= (const Matrix &rhs) { + x = reinterpret_cast(&rhs)[0]; + y = reinterpret_cast(&rhs)[1]; + z = reinterpret_cast(&rhs)[2]; + w = reinterpret_cast(&rhs)[3]; + + return *this; + } + + // getters + T getX() const { return x; } + T getY() const { return y; } + T getZ() const { return z; } + T getW() const { return w; } + + // setters + void setX(T x) { this->x = x; } + + template + requires std::integral && std::floating_point + void setX(U x) { this->x = std::round(x); } + + + void setY(T y) { this->y = y; } + + template + requires std::integral && std::floating_point + void setY(U y) { this->x = std::round(y); } + - Vector(const Vector &inXY, const Vector &inZ, const Vector &inW); - Vector(const Vector &inXY, const Vector &inZ, const T &inW); - Vector(const Vector &inXY, const T &inZ, const T &inW); - Vector(const Vector &inXY, const T &inZ, const Vector &inW); - - Vector(const Vector &inX, const Vector &inYZ, const Vector &inW); - Vector(const Vector &inX, const Vector &inYZ, const T &inW); - Vector(const T &inX, const Vector &inYZ, const T &inW); - Vector(const T &inX, const Vector &inYZ, const Vector &inW); - - Vector(const Vector &inX, const Vector &inY, const Vector &inZW); - Vector(const Vector &inX, const T &inY, const Vector &inZW); - Vector(const T &inX, const T &inY, const Vector &inZW); - Vector(const T &inX, const Vector &inY, const Vector &inZW); - - Vector(const Vector &inXY, const Vector &inZW); - - Vector(const Vector &inXYZ, const Vector &inW); - Vector(const Vector &inXYZ, const T &inW); - - Vector(const Vector &inX, const Vector &inYZW); - Vector(const T &inX, const Vector &inYZW); - - Vector(const Matrix &rhs); - - - inline void - set(const T& x, const T& y, const T& z, const T& w); - - - inline void - setX(const T& value); - - inline void - setY(const T& value); - - inline void - setZ(const T& value); - - inline void - setW(const T& value); - - - inline const T& - getX() const; - - inline const T& - getY() const; - - inline const T& - getZ() const; - - inline const T& - getW() const; - - - Vector& operator = (const Matrix &rhs); - - bool operator == (const Vector &rhs) const; - bool operator != (const Vector &rhs) const; - bool operator < (const Vector &rhs) const; - bool operator <= (const Vector &rhs) const; - bool operator > (const Vector &rhs) const; - bool operator >= (const Vector &rhs) const; - - const T& operator [] (uint8_t index) const; - T& operator [] (uint8_t index); - T* ptr(); - const T* ptr() const; - - Vector operator - () const; - Vector operator + (const Vector &rhs) const; - Vector operator - (const Vector &rhs) const; - T operator * (const Vector &rhs) const; - Vector operator * (const T &rhs) const; - Vector operator / (const T &rhs) const; - - Vector& operator += (const Vector &rhs); - Vector& operator -= (const Vector &rhs); - Vector& operator *= (const T &rhs); - Vector& operator /= (const T &rhs); - - float getLength() const; - float getLengthSquared() const; - - void scale(float newLength); - Vector scaled(float newLength) const; - - void normalize(); - Vector normalized() const; - - Matrix& - asMatrix(); - - const Matrix& - asMatrix() const; - - Matrix& - asTransposedMatrix(); - - const Matrix& - asTransposedMatrix() const; - - #ifndef __DOXYGEN__ - IMPLEMENT_VECTOR_ACCESSOR2(x,x) IMPLEMENT_VECTOR_ACCESSOR2(x,y) IMPLEMENT_VECTOR_ACCESSOR2(x,z) IMPLEMENT_VECTOR_ACCESSOR2(x,w) - IMPLEMENT_VECTOR_ACCESSOR2(y,x) IMPLEMENT_VECTOR_ACCESSOR2(y,y) IMPLEMENT_VECTOR_ACCESSOR2(y,z) IMPLEMENT_VECTOR_ACCESSOR2(y,w) - IMPLEMENT_VECTOR_ACCESSOR2(z,x) IMPLEMENT_VECTOR_ACCESSOR2(z,y) IMPLEMENT_VECTOR_ACCESSOR2(z,z) IMPLEMENT_VECTOR_ACCESSOR2(z,w) - IMPLEMENT_VECTOR_ACCESSOR2(w,x) IMPLEMENT_VECTOR_ACCESSOR2(w,y) IMPLEMENT_VECTOR_ACCESSOR2(w,z) IMPLEMENT_VECTOR_ACCESSOR2(w,w) - - IMPLEMENT_VECTOR_ACCESSOR3(x,x,x) IMPLEMENT_VECTOR_ACCESSOR3(x,x,y) IMPLEMENT_VECTOR_ACCESSOR3(x,x,z) IMPLEMENT_VECTOR_ACCESSOR3(x,x,w) - IMPLEMENT_VECTOR_ACCESSOR3(x,y,x) IMPLEMENT_VECTOR_ACCESSOR3(x,y,y) IMPLEMENT_VECTOR_ACCESSOR3(x,y,z) IMPLEMENT_VECTOR_ACCESSOR3(x,y,w) - IMPLEMENT_VECTOR_ACCESSOR3(x,z,x) IMPLEMENT_VECTOR_ACCESSOR3(x,z,y) IMPLEMENT_VECTOR_ACCESSOR3(x,z,z) IMPLEMENT_VECTOR_ACCESSOR3(x,z,w) - IMPLEMENT_VECTOR_ACCESSOR3(y,x,x) IMPLEMENT_VECTOR_ACCESSOR3(y,x,y) IMPLEMENT_VECTOR_ACCESSOR3(y,x,z) IMPLEMENT_VECTOR_ACCESSOR3(y,x,w) - IMPLEMENT_VECTOR_ACCESSOR3(y,y,x) IMPLEMENT_VECTOR_ACCESSOR3(y,y,y) IMPLEMENT_VECTOR_ACCESSOR3(y,y,z) IMPLEMENT_VECTOR_ACCESSOR3(y,y,w) - IMPLEMENT_VECTOR_ACCESSOR3(y,z,x) IMPLEMENT_VECTOR_ACCESSOR3(y,z,y) IMPLEMENT_VECTOR_ACCESSOR3(y,z,z) IMPLEMENT_VECTOR_ACCESSOR3(y,z,w) - IMPLEMENT_VECTOR_ACCESSOR3(z,x,x) IMPLEMENT_VECTOR_ACCESSOR3(z,x,y) IMPLEMENT_VECTOR_ACCESSOR3(z,x,z) IMPLEMENT_VECTOR_ACCESSOR3(z,x,w) - IMPLEMENT_VECTOR_ACCESSOR3(z,y,x) IMPLEMENT_VECTOR_ACCESSOR3(z,y,y) IMPLEMENT_VECTOR_ACCESSOR3(z,y,z) IMPLEMENT_VECTOR_ACCESSOR3(z,y,w) - IMPLEMENT_VECTOR_ACCESSOR3(z,z,x) IMPLEMENT_VECTOR_ACCESSOR3(z,z,y) IMPLEMENT_VECTOR_ACCESSOR3(z,z,z) IMPLEMENT_VECTOR_ACCESSOR3(z,z,w) - IMPLEMENT_VECTOR_ACCESSOR3(w,x,x) IMPLEMENT_VECTOR_ACCESSOR3(w,x,y) IMPLEMENT_VECTOR_ACCESSOR3(w,x,z) IMPLEMENT_VECTOR_ACCESSOR3(w,x,w) - IMPLEMENT_VECTOR_ACCESSOR3(w,y,x) IMPLEMENT_VECTOR_ACCESSOR3(w,y,y) IMPLEMENT_VECTOR_ACCESSOR3(w,y,z) IMPLEMENT_VECTOR_ACCESSOR3(w,y,w) - IMPLEMENT_VECTOR_ACCESSOR3(w,z,x) IMPLEMENT_VECTOR_ACCESSOR3(w,z,y) IMPLEMENT_VECTOR_ACCESSOR3(w,z,z) IMPLEMENT_VECTOR_ACCESSOR3(w,z,w) - - IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,w) - - IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,w) - - IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,w) - - IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,w) - IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,w) - #endif - - public: - T x; - T y; - T z; - T w; - }; - - template - static inline Vector operator * (const U &lhs, const Vector &rhs) - { - return rhs * lhs; + void setZ(T z) { this->z = z; } + + template + requires std::integral && std::floating_point + void setZ(U z) { this->z = std::round(z); } + + + void setW(T w) { this->w = w; } + + template + requires std::integral && std::floating_point + void setW(U w) { this->w = std::round(w); } + + + void set(T x, T y, T z, T w) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; + } + + template + requires std::integral && std::floating_point + void set(U x, U y, U z, U w) { + this->x = std::round(x); + this->y = std::round(y); + this->z = std::round(z); + this->w = std::round(w); } - template - static inline Vector operator * (const Matrix &lhs, const Vector &rhs) - { - return lhs * rhs.asTMatrix(); + // accessors + T& operator [] (std::size_t index) + { return reinterpret_cast(this)[index]; } + + const T& operator [] (std::size_t index) const + { return reinterpret_cast(this)[index]; } + + T* ptr() { return reinterpret_cast(this); } + + const T* ptr() const { return reinterpret_cast(this); } + + // operators + auto operator<=>(const Vector&) const = default; + + constexpr Vector operator+ (const Vector &rhs) const + { return Vector(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w); } + + constexpr Vector operator- (const Vector &rhs) const + { return Vector(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); } + + constexpr T operator* (const Vector &rhs) const + { return x * rhs.x + y * rhs.y + z * rhs.z + w * rhs.w; } + + // IMPLEMENT operator^ ? + + template + constexpr Vector operator* (U scale) const + { return Vector(x * scale, y * scale, z * scale, w * scale); } + + template + constexpr Vector operator/ (U scale) const + { return Vector(x / scale, y / scale, z / scale, w / scale); } + + Vector& operator+= (const Vector &rhs) + { x += rhs.x; y += rhs.y; z += rhs.z; w+= rhs.w; return *this; } + + Vector& operator-= (const Vector &rhs) + { x -= rhs.x; y -= rhs.y; z -= rhs.z; w-= rhs.w; return *this; } + + Vector& operator *= (T scale) + { x *= scale; y *= scale; z *= scale; w *= scale; return *this; } + + Vector& operator /= (T scale) + { x /= scale; y /= scale; z /= scale; w /= scale; return *this; } + + // template + // requires std::is_signed::value + constexpr Vector operator- () const + { return Vector(-x, -y, -z, -w); } + + // additional methods + T getLength() const + { return std::sqrt(getLengthSquared()); } + + T getLength() const + requires std::integral + { return round(std::sqrt(getLengthSquared())); } + + WideWideType getLengthSquared() const + { return std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2) + std::pow(w, 2); } + + void scale(float newLength) { *this = scaled(newLength); } + + Vector scaled(float newLength) const { + float scale = newLength / getLength(); + return *this * scale; } - typedef Vector Vector4f; - typedef Vector Vector4i; - typedef Vector Vector4u; + void normalize() { scale(1.0f); } + Vector normalized() const { return scaled(1.0); } + + bool hasNan() const { return std::isnan(x) || std::isnan(y) || std::isnan(z) || std::isnan(w); } + bool hasInf() const { return std::isinf(x) || std::isinf(y) || std::isinf(z) || std::isinf(w); } + +#ifndef __DOXYGEN__ + IMPLEMENT_VECTOR_ACCESSOR2(x,x) IMPLEMENT_VECTOR_ACCESSOR2(x,y) IMPLEMENT_VECTOR_ACCESSOR2(x,z) IMPLEMENT_VECTOR_ACCESSOR2(x,w) + IMPLEMENT_VECTOR_ACCESSOR2(y,x) IMPLEMENT_VECTOR_ACCESSOR2(y,y) IMPLEMENT_VECTOR_ACCESSOR2(y,z) IMPLEMENT_VECTOR_ACCESSOR2(y,w) + IMPLEMENT_VECTOR_ACCESSOR2(z,x) IMPLEMENT_VECTOR_ACCESSOR2(z,y) IMPLEMENT_VECTOR_ACCESSOR2(z,z) IMPLEMENT_VECTOR_ACCESSOR2(z,w) + IMPLEMENT_VECTOR_ACCESSOR2(w,x) IMPLEMENT_VECTOR_ACCESSOR2(w,y) IMPLEMENT_VECTOR_ACCESSOR2(w,z) IMPLEMENT_VECTOR_ACCESSOR2(w,w) + + IMPLEMENT_VECTOR_ACCESSOR3(x,x,x) IMPLEMENT_VECTOR_ACCESSOR3(x,x,y) IMPLEMENT_VECTOR_ACCESSOR3(x,x,z) IMPLEMENT_VECTOR_ACCESSOR3(x,x,w) + IMPLEMENT_VECTOR_ACCESSOR3(x,y,x) IMPLEMENT_VECTOR_ACCESSOR3(x,y,y) IMPLEMENT_VECTOR_ACCESSOR3(x,y,z) IMPLEMENT_VECTOR_ACCESSOR3(x,y,w) + IMPLEMENT_VECTOR_ACCESSOR3(x,z,x) IMPLEMENT_VECTOR_ACCESSOR3(x,z,y) IMPLEMENT_VECTOR_ACCESSOR3(x,z,z) IMPLEMENT_VECTOR_ACCESSOR3(x,z,w) + IMPLEMENT_VECTOR_ACCESSOR3(y,x,x) IMPLEMENT_VECTOR_ACCESSOR3(y,x,y) IMPLEMENT_VECTOR_ACCESSOR3(y,x,z) IMPLEMENT_VECTOR_ACCESSOR3(y,x,w) + IMPLEMENT_VECTOR_ACCESSOR3(y,y,x) IMPLEMENT_VECTOR_ACCESSOR3(y,y,y) IMPLEMENT_VECTOR_ACCESSOR3(y,y,z) IMPLEMENT_VECTOR_ACCESSOR3(y,y,w) + IMPLEMENT_VECTOR_ACCESSOR3(y,z,x) IMPLEMENT_VECTOR_ACCESSOR3(y,z,y) IMPLEMENT_VECTOR_ACCESSOR3(y,z,z) IMPLEMENT_VECTOR_ACCESSOR3(y,z,w) + IMPLEMENT_VECTOR_ACCESSOR3(z,x,x) IMPLEMENT_VECTOR_ACCESSOR3(z,x,y) IMPLEMENT_VECTOR_ACCESSOR3(z,x,z) IMPLEMENT_VECTOR_ACCESSOR3(z,x,w) + IMPLEMENT_VECTOR_ACCESSOR3(z,y,x) IMPLEMENT_VECTOR_ACCESSOR3(z,y,y) IMPLEMENT_VECTOR_ACCESSOR3(z,y,z) IMPLEMENT_VECTOR_ACCESSOR3(z,y,w) + IMPLEMENT_VECTOR_ACCESSOR3(z,z,x) IMPLEMENT_VECTOR_ACCESSOR3(z,z,y) IMPLEMENT_VECTOR_ACCESSOR3(z,z,z) IMPLEMENT_VECTOR_ACCESSOR3(z,z,w) + IMPLEMENT_VECTOR_ACCESSOR3(w,x,x) IMPLEMENT_VECTOR_ACCESSOR3(w,x,y) IMPLEMENT_VECTOR_ACCESSOR3(w,x,z) IMPLEMENT_VECTOR_ACCESSOR3(w,x,w) + IMPLEMENT_VECTOR_ACCESSOR3(w,y,x) IMPLEMENT_VECTOR_ACCESSOR3(w,y,y) IMPLEMENT_VECTOR_ACCESSOR3(w,y,z) IMPLEMENT_VECTOR_ACCESSOR3(w,y,w) + IMPLEMENT_VECTOR_ACCESSOR3(w,z,x) IMPLEMENT_VECTOR_ACCESSOR3(w,z,y) IMPLEMENT_VECTOR_ACCESSOR3(w,z,z) IMPLEMENT_VECTOR_ACCESSOR3(w,z,w) + + IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,x,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,x,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,x,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,y,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,y,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,y,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,z,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,z,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,z,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(x,w,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(x,w,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(x,w,z,w) + + IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,x,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,x,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,x,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,y,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,y,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,y,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,z,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,z,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,z,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(y,w,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(y,w,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(y,w,z,w) + + IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,x,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,x,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,x,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,y,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,y,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,y,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,z,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,z,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,z,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(z,w,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(z,w,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(z,w,z,w) + + IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,x,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,x,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,x,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,y,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,y,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,y,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,z,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,z,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,z,z,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,x) IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,y) IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,z) IMPLEMENT_VECTOR_ACCESSOR4(w,w,x,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,x) IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,y) IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,z) IMPLEMENT_VECTOR_ACCESSOR4(w,w,y,w) + IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,x) IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,y) IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,z) IMPLEMENT_VECTOR_ACCESSOR4(w,w,z,w) +#endif + + // depricated methods + template + [[deprecated("Use common constructor instead!")]] + Vector + convert() const { return {*this}; } + +protected: + template + friend IOStream& + operator<<(IOStream& os, const Vector& c); +}; + +template +static inline Vector operator* (const U &lhs, const Vector &rhs) +{ return rhs * lhs; } + +// Should be covered by the above +// template +// static inline Vector operator* (const T &lhs, const Vector &rhs) +// { +// return rhs * lhs; +// } + +template +static inline Vector operator* (const Matrix &lhs, const Vector &rhs) +{ return lhs * rhs.asTMatrix(); } + +#if __has_include() +#include + +template +IOStream& +operator<< (IOStream& os, const Vector& v) { + os << "x=" << v.x << "\ty=" << v.y << "\tz=" << v.z << "\tw=" << v.w; + return os; } +#endif -#include "vector4_impl.hpp" +using Vector4f = Vector; +using Vector4i = Vector; +using Vector4u = Vector; -#endif // MODM_VECTOR4_HPP +} // namespace modm \ No newline at end of file diff --git a/src/modm/math/geometry/vector4_impl.hpp b/src/modm/math/geometry/vector4_impl.hpp deleted file mode 100644 index 36e8d2c664..0000000000 --- a/src/modm/math/geometry/vector4_impl.hpp +++ /dev/null @@ -1,788 +0,0 @@ -/* - * Copyright (c) 2011-2012, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_VECTOR4_HPP - #error "Don't include this file directly, use 'vector4.hpp' instead!" -#endif - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector() -: - x(), - y(), - z(), - w() -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(T inX, T inY, T inZ, T inW) -: - x(inX), - y(inY), - z(inZ), - w(inW) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inY, const modm::Vector &inZ, const modm::Vector &inW) -: - x(inX.x), - y(inY.x), - z(inZ.x), - w(inW.x) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inY, const modm::Vector &inZ, const T &inW) -: - x(inX.x), - y(inY.x), - z(inZ.x), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inY, const T &inZ, const T &inW) -: - x(inX.x), - y(inY.x), - z(inZ), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const modm::Vector &inZ, const T &inW) -: - x(inX.x), - y(inY), - z(inZ.x), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY, const modm::Vector &inZ, const T &inW) -: - x(inX), - y(inY.x), - z(inZ.x), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const T &inZ, const T &inW) -: - x(inX.x), - y(inY), - z(inZ), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY, const T &inZ, const T &inW) -: - x(inX), - y(inY.x), - z(inZ), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inY, const T &inZ, const modm::Vector &inW) -: - x(inX.x), - y(inY.x), - z(inZ), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const T &inZ, const modm::Vector &inW) -: - x(inX.x), - y(inY), - z(inZ), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY, const T &inZ, const modm::Vector &inW) -: - x(inX), - y(inY.x), - z(inZ), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const T &inY, const T &inZ, const modm::Vector &inW) -: - x(inX), - y(inY), - z(inZ), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const modm::Vector &inZ, const modm::Vector &inW) -: - x(inX.x), - y(inY), - z(inZ.x), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const T &inY, const modm::Vector &inZ, const modm::Vector &inW) -: - x(inX), - y(inY), - z(inZ.x), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY, const modm::Vector &inZ, const modm::Vector &inW) -: - x(inX), - y(inY.x), - z(inZ.x), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const modm::Vector &inZ, const modm::Vector &inW) -: - x(inXY.x), - y(inXY.y), - z(inZ.x), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const modm::Vector &inZ, const T &inW) -: - x(inXY.x), - y(inXY.y), - z(inZ.x), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const T &inZ, const T &inW) -: - x(inXY.x), - y(inXY.y), - z(inZ), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const T &inZ, const modm::Vector &inW) -: - x(inXY.x), - y(inXY.y), - z(inZ), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inYZ, const modm::Vector &inW) -: - x(inX.x), - y(inYZ.x), - z(inYZ.y), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inYZ, const T &inW) -: - x(inX.x), - y(inYZ.x), - z(inYZ.y), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inYZ, const T &inW) -: - x(inX), - y(inYZ.x), - z(inYZ.y), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inYZ, const modm::Vector &inW) -: - x(inX), - y(inYZ.x), - z(inYZ.y), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inY, const modm::Vector &inZW) -: - x(inX.x), - y(inY.x), - z(inZW.x), - w(inZW.y) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const T &inY, const modm::Vector &inZW) -: - x(inX.x), - y(inY), - z(inZW.x), - w(inZW.y) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const T &inY, const modm::Vector &inZW) -: - x(inX), - y(inY), - z(inZW.x), - w(inZW.y) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inY, const modm::Vector &inZW) -: - x(inX), - y(inY.x), - z(inZW.x), - w(inZW.y) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXY, const modm::Vector &inZW) -: - x(inXY.x), - y(inXY.y), - z(inZW.x), - w(inZW.y) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXYZ, const modm::Vector &inW) -: - x(inXYZ.x), - y(inXYZ.y), - z(inXYZ.z), - w(inW.x) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inXYZ, const T &inW) -: - x(inXYZ.x), - y(inXYZ.y), - z(inXYZ.z), - w(inW) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Vector &inX, const modm::Vector &inYZW) -: - x(inX.x), - y(inYZW.x), - z(inYZW.y), - w(inYZW.z) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T &inX, const modm::Vector &inYZW) -: - x(inX), - y(inYZW.x), - z(inYZW.y), - w(inYZW.z) -{ -} - - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const modm::Matrix &rhs) -: - x(reinterpret_cast(&rhs)[0]), - y(reinterpret_cast(&rhs)[1]), - z(reinterpret_cast(&rhs)[2]), - w(reinterpret_cast(&rhs)[3]) -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(T inVal) -: - x(inVal), - y(inVal), - z(inVal), - w(inVal) -{ -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::set(const T& x_, const T& y_, const T& z_, const T& w_) -{ - this->x = x_; - this->y = y_; - this->z = z_; - this->w = w_; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::setX(const T& value) -{ - this->x = value; -} - -template -void -modm::Vector::setY(const T& value) -{ - this->y = value; -} - -template -void -modm::Vector::setZ(const T& value) -{ - this->z = value; -} - -template -void -modm::Vector::setW(const T& value) -{ - this->w = value; -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::getX() const -{ - return this->x; -} - -template -const T& -modm::Vector::getY() const -{ - return this->y; -} - -template -const T& -modm::Vector::getZ() const -{ - return this->z; -} - -template -const T& -modm::Vector::getW() const -{ - return this->w; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator = (const modm::Matrix &rhs) -{ - x = reinterpret_cast(&rhs)[0]; - y = reinterpret_cast(&rhs)[1]; - z = reinterpret_cast(&rhs)[2]; - w = reinterpret_cast(&rhs)[3]; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator == (const modm::Vector &rhs) const -{ - return (rhs.x == x) && (rhs.y == y) && (rhs.z == z) && (rhs.w == w); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator != (const modm::Vector &rhs) const -{ - return (rhs.x != x) || (rhs.y != y) || (rhs.z != z) || (rhs.w != w); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator < (const modm::Vector &rhs) const -{ - return (x < rhs.x) || ((x == rhs.x) && ((y < rhs.y) || ((y == rhs.y) && ((z < rhs.z) || ((z == rhs.z) && (w < rhs.w)))))); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator <= (const modm::Vector &rhs) const -{ - return (x < rhs.x) || ((x == rhs.x) && ((y < rhs.y) || ((y == rhs.y) && ((z < rhs.z) || ((z == rhs.z) && (w <= rhs.w)))))); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator > (const modm::Vector &rhs) const -{ - return (x > rhs.x) || ((x == rhs.x) && ((y > rhs.y) || ((y == rhs.y) && ((z > rhs.z) || ((z == rhs.z) && (w > rhs.w)))))); -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator >= (const modm::Vector &rhs) const -{ - return (x > rhs.x) || ((x == rhs.x) && ((y > rhs.y) || ((y == rhs.y) && ((z > rhs.z) || ((z == rhs.z) && (w >= rhs.w)))))); -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::operator [] (uint8_t index) const -{ - return reinterpret_cast(this)[index]; -} - -// ---------------------------------------------------------------------------- -template -T& -modm::Vector::operator [] (uint8_t index) -{ - return reinterpret_cast(this)[index]; -} - -// ---------------------------------------------------------------------------- -template -T* -modm::Vector::ptr() -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -const T* -modm::Vector::ptr() const -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator + (const modm::Vector &rhs) const -{ - return modm::Vector(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - (const modm::Vector &rhs) const -{ - return modm::Vector(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::operator * (const modm::Vector &rhs) const -{ - return x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator * (const T &rhs) const -{ - return modm::Vector(x*rhs, y*rhs, z*rhs, w*rhs); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator / (const T &rhs) const -{ - return modm::Vector(x/rhs, y/rhs, z/rhs, w/rhs); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator += (const modm::Vector &rhs) -{ - x += rhs.x; - y += rhs.y; - z += rhs.z; - w += rhs.w; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator -= (const modm::Vector &rhs) -{ - x -= rhs.x; - y -= rhs.y; - z -= rhs.z; - w -= rhs.w; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator *= (const T &rhs) -{ - x *= rhs; - y *= rhs; - z *= rhs; - w *= rhs; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator /= (const T &rhs) -{ - x /= rhs; - y /= rhs; - z /= rhs; - w /= rhs; - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - () const -{ - return modm::Vector(-x, -y, -z, -w); -} - -// ---------------------------------------------------------------------------- -template -float -modm::Vector::getLength() const -{ - return std::sqrt(getLengthSquared()); -} - -// ---------------------------------------------------------------------------- -template -float -modm::Vector::getLengthSquared() const -{ - return x*x + y*y + z*z + w*w; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::scale(float newLength) -{ - *this = scaled(newLength); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::scaled(float newLength) const -{ - float scale = newLength / getLength(); - return *this * scale; -} - -// ---------------------------------------------------------------------------- -template -void -modm::Vector::normalize() -{ - scale(1.0f); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::normalized() const -{ - return scaled(1.0); -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asMatrix() -{ - return *(modm::Matrix*)this; -} - -template -const modm::Matrix& -modm::Vector::asMatrix() const -{ - return *(modm::Matrix*)this; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asTransposedMatrix() -{ - return *(modm::Matrix*)this; -} - - -template -const modm::Matrix& -modm::Vector::asTransposedMatrix() const -{ - return *(modm::Matrix*)this; -} - -// ---------------------------------------------------------------------------- -template -static inline modm::Vector -operator * (const T &lhs, const modm::Vector &rhs) -{ - return rhs * lhs; -} - -template -static inline modm::Vector -operator * (const modm::Matrix &lhs, const modm::Vector &rhs) -{ - return lhs * rhs.asTMatrix(); -} - diff --git a/src/modm/math/geometry/vector_impl.hpp b/src/modm/math/geometry/vector_impl.hpp deleted file mode 100644 index ccb4d78451..0000000000 --- a/src/modm/math/geometry/vector_impl.hpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2011-2012, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_VECTOR_HPP - #error "Don't include this file directly, use 'vector.hpp' instead!" -#endif - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector() -{ -} - -template -modm::Vector::Vector(const T *ptData) -{ - memcpy(coords, ptData, sizeof(T) * N); -} - -template -modm::Vector::Vector(const modm::Matrix &rhs) -{ - memcpy(coords, &rhs, sizeof(T) * N); -} - -// ---------------------------------------------------------------------------- -template -uint8_t -modm::Vector::getSize() -{ - return N; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator = (const modm::Matrix &rhs) -{ - memcpy(coords, &rhs, sizeof(T) * N); - return *this; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator == (const modm::Vector &rhs) const -{ - return memcmp(coords, rhs.coords, sizeof(T)*N) == 0; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator != (const modm::Vector &rhs) const -{ - return memcmp(coords, rhs.coords, sizeof(T)*N) != 0; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator < (const modm::Vector &rhs) const -{ - for (uint_fast8_t i = 0; i < N; ++i) - { - if ((*this)[i] < rhs[i]) { - return true; - } - else if ((*this)[i] > rhs[i]) { - return false; - } - } - return false; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator <= (const modm::Vector &rhs) const -{ - for (uint_fast8_t i = 0; i < N; ++i) - { - if ((*this)[i] < rhs[i]) { - return true; - } - else if ((*this)[i] > rhs[i]) { - return false; - } - } - return true; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator > (const modm::Vector &rhs) const -{ - for (uint_fast8_t i = 0; i < N; ++i) - { - if ((*this)[i] > rhs[i]) { - return true; - } - else if ((*this)[i] < rhs[i]) { - return false; - } - } - return false; -} - -// ---------------------------------------------------------------------------- -template -bool -modm::Vector::operator >= (const modm::Vector &rhs) const -{ - for (uint_fast8_t i = 0; i < N; ++i) - { - if ((*this)[i] > rhs[i]) { - return true; - } - else if ((*this)[i] < rhs[i]) { - return false; - } - } - return true; -} - -// ---------------------------------------------------------------------------- -template -const T& -modm::Vector::operator [] (uint8_t index) const -{ - return coords[index]; -} - -// ---------------------------------------------------------------------------- -template -T& -modm::Vector::operator [] (uint8_t index) -{ - return coords[index]; -} - -// ---------------------------------------------------------------------------- -template -T* -modm::Vector::ptr() -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -const T* -modm::Vector::ptr() const -{ - return reinterpret_cast(this); -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator + (const modm::Vector &rhs) const -{ - modm::Vector pt; - for (uint_fast8_t i = 0; i < N; ++i) { - pt[i] = coords[i] + rhs.coords[i]; - } - return pt; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator - (const modm::Vector &rhs) const -{ - modm::Vector pt; - for (uint_fast8_t i = 0; i < N; ++i) { - pt[i] = coords[i] - rhs.coords[i]; - } - return pt; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Vector::asMatrix() -{ - return *reinterpret_cast*>(this); -} - -template -const modm::Matrix& -modm::Vector::asMatrix() const -{ - return *reinterpret_cast*>(this); -} - -// ---------------------------------------------------------------------------- -template -const modm::Matrix& -modm::Vector::asTransposedMatrix() const -{ - return *reinterpret_cast*>(this); -} - -template -modm::Matrix& -modm::Vector::asTransposedMatrix() -{ - return *reinterpret_cast*>(this); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::operator * (const Vector &rhs) const -{ - T v = 0; - for (uint_fast8_t i = 0; i < N; ++i) { - v += (*this)[i]*rhs[i]; - } - - return v; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator * (const T &rhs) const -{ - modm::Vector pt; - for (uint_fast8_t i = 0; i < N; ++i) { - pt[i] = coords[i] * rhs; - } - return pt; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector -modm::Vector::operator / (const T &rhs) const -{ - modm::Vector pt; - for (uint_fast8_t i = 0; i < N; ++i) { - pt[i] = coords[i] / rhs; - } - return pt; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator += (const Vector &rhs) -{ - for (uint_fast8_t i = 0; i < N; ++i) { - coords[i] += rhs.coords[i]; - } - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator -= (const Vector &rhs) -{ - for (uint_fast8_t i = 0; i < N; ++i) { - coords[i] -= rhs.coords[i]; - } - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator *= (const T &rhs) -{ - for (uint_fast8_t i = 0; i < N; ++i) { - coords[i] -= rhs; - } - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator /= (const T &rhs) -{ - for (uint_fast8_t i = 0; i < N; ++i) { - coords[i] /= rhs; - } - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Vector& -modm::Vector::operator - () -{ - for (uint_fast8_t i = 0; i < N; ++i) { - coords[i] = -coords[i]; - } - return *this; -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::getLength() const -{ - return std::sqrt(getLengthSquared()); -} - -// ---------------------------------------------------------------------------- -template -T -modm::Vector::getLengthSquared() const -{ - T len2 = 0; - for (uint_fast8_t i = 0; i < N; ++i) { - len2 += (*this)[i]*(*this)[i]; - } - - return len2; -} diff --git a/src/modm/math/lu_decomposition.hpp b/src/modm/math/lu_decomposition.hpp index eb1c18a29a..c2b618d416 100644 --- a/src/modm/math/lu_decomposition.hpp +++ b/src/modm/math/lu_decomposition.hpp @@ -11,8 +11,7 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_LU_DECOMPOSITION_HPP -#define MODM_LU_DECOMPOSITION_HPP +#pragma once #include "matrix.hpp" #include "geometry/vector.hpp" @@ -20,8 +19,11 @@ namespace modm { // forward declaration - template class Matrix; - template class Vector; + template + class Matrix; + + template + class Vector; /** * \brief Class for decomposing matrices @@ -39,41 +41,41 @@ namespace modm class LUDecomposition { public: - template + template static bool - decompose(const Matrix &matrix, - Matrix *l, - Matrix *u); + decompose(const Matrix &matrix, + Matrix *l, + Matrix *u); - template + template static bool - decompose(const Matrix &matrix, - Matrix *l, - Matrix *u, - Matrix *p); + decompose(const Matrix &matrix, + Matrix *l, + Matrix *u, + Matrix *p); - template + template static bool - decompose(const Matrix &matrix, - Matrix *l, - Matrix *u, - Vector *p); + decompose(const Matrix &matrix, + Matrix *l, + Matrix *u, + Vector *p); - template + template static bool - solve(const Matrix &l, - const Matrix &u, - Matrix *xb); + solve(const Matrix &l, + const Matrix &u, + Matrix *xb); - template + template static bool - solve(const Matrix &A, - Matrix *xb); + solve(const Matrix &A, + Matrix *xb); private: - template + template class LUSubDecomposition { public: @@ -89,19 +91,19 @@ namespace modm static bool decompose(T *u, T *l, int8_t *p); - template + template static bool solveLyEqualsB( Matrix *l, Matrix *bx); - template + template static bool solveUxEqualsY( Matrix *u, Matrix *bx); - template + template static bool solve( const Matrix &l, @@ -109,7 +111,7 @@ namespace modm Matrix *bx); }; - template + template class RowOperation { public: @@ -145,7 +147,7 @@ namespace modm swap(T *row1, T *row2); }; - template + template class LUSubDecomposition { public: @@ -155,13 +157,13 @@ namespace modm static bool decomposeRecur(T *u, T *l); - template + template static bool solveUxEqualsY( Matrix *u, Matrix *bx); - template + template static bool solveLyEqualsB( Matrix *l, @@ -170,5 +172,3 @@ namespace modm }; } #include "lu_decomposition_impl.hpp" - -#endif // MODM_LU_DECOMPOSITION_HPP diff --git a/src/modm/math/lu_decomposition_impl.hpp b/src/modm/math/lu_decomposition_impl.hpp index f79a9228ee..3068e1518b 100644 --- a/src/modm/math/lu_decomposition_impl.hpp +++ b/src/modm/math/lu_decomposition_impl.hpp @@ -9,14 +9,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// ---------------------------------------------------------------------------- +#pragma once +#include "lu_decomposition.hpp" -#ifndef MODM_LU_DECOMPOSITION_HPP - #error "Don't include this file directly, use 'lu_decomposition.hpp' instead!" -#endif +#include -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::decompose( const modm::Matrix &matrix, @@ -29,8 +27,7 @@ modm::LUDecomposition::decompose( return LUSubDecomposition::decomposeRecur(u->ptr(), l->ptr()); } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::decompose( const modm::Matrix &matrix, @@ -38,16 +35,15 @@ modm::LUDecomposition::decompose( modm::Matrix *u, modm::Vector *p) { - for (uint_fast8_t i = 0; i < SIZE; ++i) { + for (uint_fast8_t i = 0; i < SIZE; ++i) (*p)[i] = i; - } *u = matrix; *l = modm::Matrix::identityMatrix(); return LUSubDecomposition::decomposeRecur(u->ptr(), l->ptr(), p->ptr()); } -// ---------------------------------------------------------------------------- -template + +template bool modm::LUDecomposition::decompose( const modm::Matrix &matrix, @@ -56,16 +52,18 @@ modm::LUDecomposition::decompose( modm::Matrix *p) { modm::Vector pv; - if (not(decompose(matrix, l, u, &pv))){ - return false;} + + if (not(decompose(matrix, l, u, &pv))) + return false; + *p = modm::Matrix::zeroMatrix(); - for (int i=0; i +template bool modm::LUDecomposition::solve( const modm::Matrix &l, @@ -75,8 +73,7 @@ modm::LUDecomposition::solve( return LUSubDecomposition::solve(l, u, xb); } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::solve( const modm::Matrix &A, @@ -85,12 +82,14 @@ modm::LUDecomposition::solve( modm::Matrix l; modm::Matrix u; modm::Matrix p; - if(not(decompose(A, &l, &u, &p))){ + + if(not(decompose(A, &l, &u, &p))) return false; - } + *xb = (p * (*xb)); - if(not(solve(l, u, xb))){ - return false;} + if(not(solve(l, u, xb))) + return false; + return true; } @@ -98,71 +97,60 @@ modm::LUDecomposition::solve( // PRIVATE CLASS modm::LUDecomposition::RowOperation //============================================================================= -// ---------------------------------------------------------------------------- -template +template void modm::LUDecomposition::RowOperation::multiply(T *intoRow, const T *row, const T &factor) { - for (uint_fast8_t i = 0; i < SIZE; ++i) { + for (uint_fast8_t i = 0; i < SIZE; ++i) intoRow[i] = row[i] * factor; - } } -// ---------------------------------------------------------------------------- -template +template void modm::LUDecomposition::RowOperation::addRowTimesFactor(T *intoRow, const T *srcRow, const T *addRow, const T ×Factor) { - for (uint_fast8_t i = 0; i < SIZE; ++i) { + for (uint_fast8_t i = 0; i < SIZE; ++i) intoRow[i] = srcRow[i] + addRow[i] * timesFactor; - } } -// ---------------------------------------------------------------------------- -template +template void modm::LUDecomposition::RowOperation::swap(T *row1, T *row2) { - T tmp[SIZE]; + // TODO prefer std::swap - memcpy(tmp, row1, SIZE*sizeof(T)); - memcpy(row1, row2, SIZE*sizeof(T)); - memcpy(row2, tmp, SIZE*sizeof(T)); + T tmp[SIZE]; + std::copy(row1, row1 + SIZE, tmp); + std::copy(row2, row2 + SIZE, row1); + std::copy(tmp, tmp + SIZE, row2); } //============================================================================= // PRIVATE CLASS modm::LUDecomposition::RowOperation //============================================================================= -// ---------------------------------------------------------------------------- template void modm::LUDecomposition::RowOperation::multiply( T * /* intoRow */, const T * /* row */, const T & /* factor */) -{ -} +{} -// ---------------------------------------------------------------------------- template void modm::LUDecomposition::RowOperation::addRowTimesFactor( T * /* intoRow */, const T * /* srcRow */, const T * /* addRow */, const T & /* timesFactor */) -{ -} +{} -// ---------------------------------------------------------------------------- template void modm::LUDecomposition::RowOperation::swap(T * /* row1 */, T * /* row2 */) -{ -} +{} //============================================================================= // PRIVATE CLASS modm::LUDecomposition::LUSubDecomposition //============================================================================= -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::LUSubDecomposition::decomposeRecur(T * u, T * l) { @@ -172,34 +160,29 @@ modm::LUDecomposition::LUSubDecomposition::decomposeRe return LUSubDecomposition::decomposeRecur(u, l); } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::LUSubDecomposition::decompose(T * u, T * l) { - const uint8_t width = WIDTH; - const uint8_t height = HEIGHT; - // normalize the row - T factor = u[OFFSET*width + OFFSET]; - l[OFFSET*width + OFFSET] = factor; + T factor = u[OFFSET*WIDTH + OFFSET]; + l[OFFSET*WIDTH + OFFSET] = factor; - u[OFFSET*width + OFFSET] = 1; - RowOperation::multiply(&u[OFFSET*width + OFFSET+1], &u[OFFSET*width + OFFSET+1], T(1.0)/factor); + u[OFFSET*WIDTH + OFFSET] = 1; + RowOperation::multiply(&u[OFFSET*WIDTH + OFFSET+1], &u[OFFSET*WIDTH + OFFSET+1], T(1.0)/factor); - for (uint_fast8_t j = OFFSET+1; j < height; ++j) + for (uint_fast8_t j = OFFSET+1; j < HEIGHT; ++j) { - factor = u[j*width + OFFSET]; - l[j*width + OFFSET] = factor; - u[j*width + OFFSET] = 0; - RowOperation::addRowTimesFactor(&u[j*width + OFFSET+1], &u[j*width + OFFSET+1], &u[OFFSET*width + OFFSET+1], -factor); + factor = u[j*WIDTH + OFFSET]; + l[j*WIDTH + OFFSET] = factor; + u[j*WIDTH + OFFSET] = 0; + RowOperation::addRowTimesFactor(&u[j*WIDTH + OFFSET+1], &u[j*WIDTH + OFFSET+1], &u[OFFSET*WIDTH + OFFSET+1], -factor); } return true; } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::LUSubDecomposition::decomposeRecur(T *u, T *l, int8_t *p) { @@ -209,21 +192,17 @@ modm::LUDecomposition::LUSubDecomposition::decomposeRe return LUSubDecomposition::decomposeRecur(u, l, p); } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::LUSubDecomposition::decompose(T *u, T *l, int8_t *p) { - const uint8_t width = WIDTH; - const uint8_t height = HEIGHT; - // swap with a lower row so that we have the highest value factor // FIXME: we need to use something other than fabs here - T max = fabs(u[OFFSET*width + OFFSET]); - uint8_t maxRow = OFFSET; - for (uint_fast8_t j = OFFSET+1; j < height; ++j) + T max = fabs(u[OFFSET*WIDTH + OFFSET]); + std::size_t maxRow = OFFSET; + for (uint_fast8_t j = OFFSET+1; j < HEIGHT; ++j) { - T v = fabs(u[j*width + OFFSET]); + T v = fabs(u[j*WIDTH + OFFSET]); if (v > max) { max = v; @@ -236,16 +215,15 @@ modm::LUDecomposition::LUSubDecomposition::decompose(T uint16_t temp = p[OFFSET]; p[OFFSET] = p[maxRow]; p[maxRow] = temp; - RowOperation::swap(&u[maxRow*width+OFFSET], &u[OFFSET*width+OFFSET]); - RowOperation::swap(&l[maxRow*width], &l[OFFSET*width]); + RowOperation::swap(&u[maxRow*WIDTH+OFFSET], &u[OFFSET*WIDTH+OFFSET]); + RowOperation::swap(&l[maxRow*WIDTH], &l[OFFSET*WIDTH]); } return decompose(u, l); } -// ---------------------------------------------------------------------------- -template template +template template bool modm::LUDecomposition::LUSubDecomposition::solveLyEqualsB( modm::Matrix *l, @@ -255,9 +233,8 @@ modm::LUDecomposition::LUSubDecomposition::solveLyEqua RowOperation::multiply((*bx)[OFFSET], (*bx)[OFFSET], 1.0/factor); // make sure there is a row under us - if (OFFSET >= HEIGHT-1) { + if (OFFSET >= HEIGHT-1) return true; - } // substract the row so that all lower rows have a 0 at OFFSET for (uint_fast8_t j = OFFSET+1; j < HEIGHT; ++j) @@ -272,23 +249,21 @@ modm::LUDecomposition::LUSubDecomposition::solveLyEqua return true; } -// ---------------------------------------------------------------------------- -template template +template template bool modm::LUDecomposition::LUSubDecomposition::solveUxEqualsY( modm::Matrix *u, modm::Matrix *bx) { // make sure there is a row under us - if (OFFSET >= HEIGHT-1) { + if (OFFSET >= HEIGHT-1) return true; - } // solve the problem for SIZE-1 LUSubDecomposition::solveUxEqualsY(u, bx); // substract the row so that all upper rows have a 0 at OFFSET - for (uint8_t j = 0; j < OFFSET+1; ++j) + for (std::size_t j = 0; j < OFFSET+1; ++j) { T factor = (*u)[j][OFFSET+1]; RowOperation::addRowTimesFactor((*bx)[j], (*bx)[j], (*bx)[OFFSET+1], -factor); @@ -298,8 +273,7 @@ modm::LUDecomposition::LUSubDecomposition::solveUxEqua return true; } -// ---------------------------------------------------------------------------- -template template +template template bool modm::LUDecomposition::LUSubDecomposition::solve( const modm::Matrix &l, @@ -316,36 +290,31 @@ modm::LUDecomposition::LUSubDecomposition::solve( // start solving Ly = b modm::Matrix lCopy(l); - if (!solveLyEqualsB(&lCopy, bx)) { + if (!solveLyEqualsB(&lCopy, bx)) return false; - } modm::Matrix uCopy(u); - if (!solveUxEqualsY(&uCopy, bx)) { + if (!solveUxEqualsY(&uCopy, bx)) return false; - } return true; } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::LUSubDecomposition::decomposeRecur(T * /* u */, T * /* l */, int8_t * /* p */) { return true; } -// ---------------------------------------------------------------------------- -template +template bool modm::LUDecomposition::LUSubDecomposition::decomposeRecur(T * /* u */, T * /* l */) { return true; } -// ---------------------------------------------------------------------------- -template template +template template bool modm::LUDecomposition::LUSubDecomposition::solveUxEqualsY( modm::Matrix * /* u */, @@ -354,8 +323,7 @@ modm::LUDecomposition::LUSubDecomposition::solveUxEqua return true; } -// ---------------------------------------------------------------------------- -template template +template template bool modm::LUDecomposition::LUSubDecomposition::solveLyEqualsB( modm::Matrix * /* l */, diff --git a/src/modm/math/matrix.hpp b/src/modm/math/matrix.hpp index 1b2396773e..0d90f5bc81 100644 --- a/src/modm/math/matrix.hpp +++ b/src/modm/math/matrix.hpp @@ -11,11 +11,10 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_MATRIX_HPP -#define MODM_MATRIX_HPP +#pragma once #include -#include // for memset() and memcmp() +#include #include #include @@ -28,7 +27,7 @@ namespace modm * Having the width and height as template parameters has several * advantages over the tradition dynamic matrix class: * - * - The compiler knows how many elements you have in your matrix and can + * - The compiler knows how many ElementCount you have in your matrix and can * unroll and optimize loops * - You can ensure that you are not doing operations on matrices with * incompatible sizes (multiplication for example). The compiler will @@ -48,33 +47,40 @@ namespace modm * \author Niklas Hauser * \author Fabian Greif */ - template + template class Matrix { public: + static constexpr std::size_t RowCount = ROWS; + static constexpr std::size_t ColumnCount = COLUMNS; + static constexpr std::size_t ElementCount = RowCount * ColumnCount; + + T element[ElementCount]; + /** * \brief Default Constructor * - * Creates a Matrix with uninitialized elements. Use zeroMatrix() to - * create a matrix with all elements set to zero. + * Creates a Matrix with uninitialized ElementCount. Use zeroMatrix() to + * create a matrix with all ElementCount set to zero. */ - Matrix(); + constexpr Matrix() = default; /** * \brief Create a matrix from an array * * Example: * \code - * const int16_t m[6] = { + * + * modm::Matrix a({ * 1, 2, * 3, 4, * 5, 6, - * }; - * - * modm::Matrix a(m); + * }); * \endcode */ - Matrix(const T *data); + constexpr Matrix(const T *data) { + std::copy(data, data + ElementCount, element); + } /** * \brief Get a zero matrix @@ -98,52 +104,49 @@ namespace modm * \brief Create a new sub matrix * */ - template + template Matrix - subMatrix(uint8_t row, uint8_t column) const; + subMatrix(std::size_t row, std::size_t column) const; bool operator == (const Matrix &m) const; bool operator != (const Matrix &m) const; - const T* - operator [] (uint8_t row) const; - - T* - operator [] (uint8_t row); + T* operator [] (std::size_t row); + const T* operator [] (std::size_t row) const; - inline uint8_t - getNumberOfRows() const; + std::size_t getNumberOfRows() const + { return RowCount; } - inline uint8_t - getNumberOfColumns() const; + std::size_t getNumberOfColumns() const + { return ColumnCount; } Matrix - getRow(uint8_t index) const; + getRow(std::size_t index) const; Matrix - getColumn(uint8_t index) const; + getColumn(std::size_t index) const; - // TODO remove these? - const T* ptr() const; - T* ptr(); + // DEPRECATED element is public + T* ptr() { return element; } + const T* ptr() const { return element;} - Matrix operator - (); - Matrix operator + (const Matrix &rhs) const; - Matrix operator - (const Matrix &rhs) const; - Matrix operator * (const T &rhs) const; ///< Scalar multiplication - Matrix operator / (const T &rhs) const; ///< Scalar division + constexpr Matrix operator - (); + constexpr Matrix operator + (const Matrix &rhs) const; + constexpr Matrix operator - (const Matrix &rhs) const; + constexpr Matrix operator * (T rhs) const; ///< Scalar multiplication + constexpr Matrix operator / (T rhs) const; ///< Scalar division Matrix& operator += (const Matrix &rhs); Matrix& operator -= (const Matrix &rhs); - Matrix& operator *= (const T &rhs); ///< Scalar multiplication - Matrix& operator /= (const T &rhs); ///< Scalar division + Matrix& operator *= (T rhs); ///< Scalar multiplication + Matrix& operator /= (T rhs); ///< Scalar division /// Matrix multiplication with matrices with the same size Matrix operator *= (const Matrix &rhs); /// Matrix multiplication with different size matrices - template - Matrix + template + constexpr Matrix operator * (const Matrix &rhs) const; Matrix @@ -154,7 +157,7 @@ namespace modm * * \warning Will only work if the matrix is square! */ - inline void + void transpose(); /** @@ -162,7 +165,7 @@ namespace modm * * Uses modm::determinant(*this); */ - inline T + T determinant() const; // TODO Implement these @@ -181,62 +184,52 @@ namespace modm replace(const U *data); /// - template + template Matrix& - replace(uint8_t row, uint8_t column, const Matrix &m); + replace(std::size_t row, std::size_t column, const Matrix &m); Matrix& - replaceRow(uint8_t index, const Matrix &m); + replaceRow(std::size_t index, const Matrix &m); Matrix& - replaceColumn(uint8_t index, const Matrix &m); + replaceColumn(std::size_t index, const Matrix &m); Matrix - addColumn(uint8_t index, const Matrix &c) const; + addColumn(std::size_t index, const Matrix &c) const; Matrix - addRow(uint8_t index, const Matrix &r) const; + addRow(std::size_t index, const Matrix &r) const; Matrix - removeColumn(uint8_t index) const; + removeColumn(std::size_t index) const; Matrix - removeRow(uint8_t index) const; - - public: - T element[ROWS * COLUMNS]; + removeRow(std::size_t index) const; private: - /// Size of the Matrix in Bytes - inline size_t - getSize() const; - - /// Number of elements in the Matrix (rows * columns) - inline uint8_t - getNumberOfElements() const; + std::size_t getSize() const + { return ElementCount * sizeof(T); } }; - template + template IOStream& operator << (IOStream&, const Matrix&); - typedef Matrix Matrix1f; - typedef Matrix Matrix2f; - typedef Matrix Matrix3f; - typedef Matrix Matrix4f; + using Matrix1f = Matrix; + using Matrix2f = Matrix; + using Matrix3f = Matrix; + using Matrix4f = Matrix; // ------------------------------------------------------------------------ /// \internal template - T - determinant(const modm::Matrix &m); + T determinant(const modm::Matrix &m); /// \internal template - T - determinant(const modm::Matrix &m); + T determinant(const modm::Matrix &m); /** * \brief Calculate the determinant @@ -244,11 +237,8 @@ namespace modm * \param m Matrix * \ingroup modm_math_matrix */ - template - T - determinant(const modm::Matrix &m); + template + T determinant(const modm::Matrix &m); } -#include "matrix_impl.hpp" - -#endif // MODM_MATRIX_HPP +#include "matrix_impl.hpp" \ No newline at end of file diff --git a/src/modm/math/matrix_impl.hpp b/src/modm/math/matrix_impl.hpp index ebb25d4af3..afabda163e 100644 --- a/src/modm/math/matrix_impl.hpp +++ b/src/modm/math/matrix_impl.hpp @@ -9,29 +9,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// ---------------------------------------------------------------------------- - -#ifndef MODM_MATRIX_HPP -# error "Don't include this file directly, use 'matrix.hpp' instead!" -#endif - -// ---------------------------------------------------------------------------- -template -modm::Matrix::Matrix() -{ -} +#pragma once +#include "matrix.hpp" -// ---------------------------------------------------------------------------- -template -modm::Matrix::Matrix(const T *data) -{ - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - element[i] = data[i]; - } -} +#include -// ---------------------------------------------------------------------------- -template +template const modm::Matrix& modm::Matrix::identityMatrix() { @@ -41,17 +24,11 @@ modm::Matrix::identityMatrix() if (!hasIdentityMatrix) { if (ROWS < COLUMNS) - { - for (uint_fast8_t i = 0; i < ROWS; ++i) { + for (std::size_t i = 0; i < ROWS; ++i) matrix[i][i] = 1; - } - } else - { - for (uint_fast8_t i = 0; i < COLUMNS; ++i) { + for (std::size_t i = 0; i < COLUMNS; ++i) matrix[i][i] = 1; - } - } hasIdentityMatrix = true; } @@ -60,7 +37,7 @@ modm::Matrix::identityMatrix() } // ---------------------------------------------------------------------------- -template +template const modm::Matrix& modm::Matrix::zeroMatrix() { @@ -69,7 +46,7 @@ modm::Matrix::zeroMatrix() if (!hasZeroMatrix) { - memset(matrix.ptr(), 0, matrix.getSize()); + std::fill(matrix.element, matrix.element + ElementCount, 0); hasZeroMatrix = true; } @@ -77,252 +54,196 @@ modm::Matrix::zeroMatrix() } // ---------------------------------------------------------------------------- -template +template bool modm::Matrix::operator == (const modm::Matrix &m) const { - return memcmp(element, m.element, getSize()) == 0; + return std::equal(element, element + ElementCount, m.element); } -// ---------------------------------------------------------------------------- -template +template bool modm::Matrix::operator != (const modm::Matrix &m) const { - return memcmp(element, m.element, getSize()) != 0; + return !std::equal(element, element + ElementCount, m.element); } // ---------------------------------------------------------------------------- -template +template modm::Matrix -modm::Matrix::getRow(uint8_t index) const +modm::Matrix::getRow(std::size_t index) const { return subMatrix<1, COLUMNS>(index, 0); } -// ---------------------------------------------------------------------------- -template +template modm::Matrix -modm::Matrix::getColumn(uint8_t index) const +modm::Matrix::getColumn(std::size_t index) const { return subMatrix(0, index); } // ---------------------------------------------------------------------------- -template +template T* -modm::Matrix::operator [] (uint8_t row) +modm::Matrix::operator [] (std::size_t row) { return &element[row * COLUMNS]; } -template +template const T* -modm::Matrix::operator [] (uint8_t row) const +modm::Matrix::operator [] (std::size_t row) const { return &element[row * COLUMNS]; } // ---------------------------------------------------------------------------- -template -uint8_t -modm::Matrix::getNumberOfRows() const -{ - return ROWS; -} - -// ---------------------------------------------------------------------------- -template -uint8_t -modm::Matrix::getNumberOfColumns() const -{ - return COLUMNS; -} - -// ---------------------------------------------------------------------------- -template -const T* -modm::Matrix::ptr() const -{ - return element; -} - -template -T* -modm::Matrix::ptr() -{ - return element; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix +template +constexpr modm::Matrix modm::Matrix::operator - () { modm::Matrix m; - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - m.element[i] = -this->element[i]; - } + for (std::size_t i = 0; i < ElementCount; ++i) + m.element[i] = -element[i]; return m; } -// ---------------------------------------------------------------------------- -template -modm::Matrix +template +constexpr modm::Matrix modm::Matrix::operator - (const modm::Matrix &rhs) const { modm::Matrix m; - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { + for (std::size_t i = 0; i < ElementCount; ++i) m.element[i] = element[i] - rhs.element[i]; - } return m; } -// ---------------------------------------------------------------------------- -template -modm::Matrix +template +constexpr modm::Matrix modm::Matrix::operator + (const modm::Matrix &rhs) const { modm::Matrix m; - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { + for (std::size_t i = 0; i < ElementCount; ++i) m.element[i] = element[i] + rhs.element[i]; - } return m; } -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Matrix::operator += (const modm::Matrix &rhs) -{ - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - element[i] += rhs.element[i]; - } - - return *this; -} - -// ---------------------------------------------------------------------------- -template -modm::Matrix& -modm::Matrix::operator -= (const modm::Matrix &rhs) -{ - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - element[i] -= rhs.element[i]; - } - - return *this; -} - -// ---------------------------------------------------------------------------- -template -template -modm::Matrix +template +template +constexpr modm::Matrix modm::Matrix::operator * (const Matrix &rhs) const { modm::Matrix m; - for (uint_fast8_t i = 0; i < ROWS; ++i) + for (std::size_t i = 0; i < ROWS; ++i) { - for (uint_fast8_t j = 0; j < RHSCOL; ++j) + for (std::size_t j = 0; j < RHSCOL; ++j) { m[i][j] = element[i * COLUMNS] * rhs[0][j]; - for (uint_fast8_t x = 1; x < COLUMNS; ++x) - { + for (std::size_t x = 1; x < COLUMNS; ++x) m[i][j] += element[i * COLUMNS + x] * rhs[x][j]; - } } } return m; } -// ---------------------------------------------------------------------------- -template -modm::Matrix -modm::Matrix::operator *= (const modm::Matrix &rhs) +template +constexpr modm::Matrix +modm::Matrix::operator * (T rhs) const { - (*this) = (*this) * rhs; - return *this; + modm::Matrix m; + for (std::size_t i = 0; i < ElementCount; ++i) + m.element[i] = element[i] * rhs; + + return m; } -// ---------------------------------------------------------------------------- -template -modm::Matrix -modm::Matrix::operator * (const T &rhs) const +template +constexpr modm::Matrix +modm::Matrix::operator / (T rhs) const { modm::Matrix m; - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - m.element[i] = element[i] * rhs; - } + + float oneOverRhs = 1.0f / rhs; + + for (std::size_t i = 0; i < ElementCount; ++i) + m.element[i] = element[i] * oneOverRhs; return m; } // ---------------------------------------------------------------------------- -template +template modm::Matrix& -modm::Matrix::operator *= (const T &rhs) +modm::Matrix::operator += (const modm::Matrix &rhs) { - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - element[i] *= rhs; - } + for (std::size_t i = 0; i < ElementCount; ++i) + element[i] += rhs.element[i]; return *this; } -// ---------------------------------------------------------------------------- -template -modm::Matrix -modm::Matrix::operator / (const T &rhs) const +template +modm::Matrix& +modm::Matrix::operator -= (const modm::Matrix &rhs) { - modm::Matrix m; + for (std::size_t i = 0; i < ElementCount; ++i) + element[i] -= rhs.element[i]; - float oneOverRhs = 1.0f / rhs; + return *this; +} - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - m.element[i] = element[i] * oneOverRhs; - } +template +modm::Matrix +modm::Matrix::operator *= (const modm::Matrix &rhs) +{ + (*this) = (*this) * rhs; + return *this; +} - return m; +template +modm::Matrix& +modm::Matrix::operator *= (T rhs) +{ + for (std::size_t i = 0; i < ElementCount; ++i) + element[i] *= rhs; + + return *this; } -// ---------------------------------------------------------------------------- -template +template modm::Matrix& -modm::Matrix::operator /= (const T &rhs) +modm::Matrix::operator /= (T rhs) { float oneOverRhs = 1.0f / rhs; - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { + for (std::size_t i = 0; i < ElementCount; ++i) element[i] *= oneOverRhs; - } return *this; } // ---------------------------------------------------------------------------- -template +template modm::Matrix modm::Matrix::asTransposed() const { modm::Matrix m; - for (uint_fast8_t i = 0; i < ROWS; ++i) { - for (uint_fast8_t j = 0; j < COLUMNS; ++j) { + for (std::size_t i = 0; i < ROWS; ++i) + for (std::size_t j = 0; j < COLUMNS; ++j) m.element[j * ROWS + i] = element[i * COLUMNS + j]; - } - } return m; } -// ---------------------------------------------------------------------------- -template +template void modm::Matrix::transpose() { @@ -332,7 +253,7 @@ modm::Matrix::transpose() } // ---------------------------------------------------------------------------- -template +template inline T modm::Matrix::determinant() const { @@ -342,43 +263,37 @@ modm::Matrix::determinant() const } // ---------------------------------------------------------------------------- -template +template bool modm::Matrix::hasNan() const { - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - if (isnan(element[i])) { + for (std::size_t i = 0; i < ElementCount; ++i) + if (isnan(element[i])) return true; - } - } return false; } -// ---------------------------------------------------------------------------- -template +template bool modm::Matrix::hasInf() const { - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { - if (isinf(element[i])) { + for (std::size_t i = 0; i < ElementCount; ++i) + if (isinf(element[i])) return true; - } - } return false; } // ---------------------------------------------------------------------------- -template +template modm::Matrix operator * (int8_t lhs, const modm::Matrix &m) { return m * lhs; } -// ---------------------------------------------------------------------------- -template +template modm::Matrix operator * (float lhs, const modm::Matrix &m) { @@ -386,15 +301,14 @@ operator * (float lhs, const modm::Matrix &m) } // ---------------------------------------------------------------------------- -/*template +/*template void modm::Matrix::inverse() { *this = inversed(); } -// ---------------------------------------------------------------------------- -template +template modm::Matrix modm::Matrix::inversed() const { @@ -404,210 +318,169 @@ modm::Matrix::inversed() const }*/ // ---------------------------------------------------------------------------- -template -size_t -modm::Matrix::getSize() const -{ - return getNumberOfElements() * sizeof(T); -} - -// ---------------------------------------------------------------------------- -template -uint8_t -modm::Matrix::getNumberOfElements() const -{ - return ROWS * COLUMNS; -} - -// ---------------------------------------------------------------------------- -template -template +template +template modm::Matrix -modm::Matrix::subMatrix(uint8_t row, uint8_t column) const +modm::Matrix::subMatrix(std::size_t row, std::size_t column) const { static_assert(MR <= ROWS, "sub matrix must be smaller than the original"); static_assert(MC <= COLUMNS, "sub matrix must be smaller than the original"); Matrix sub; - for (uint_fast8_t i = 0; i < MR; ++i) { - for (uint_fast8_t j = 0; j < MC; ++j) { + for (std::size_t i = 0; i < MR; ++i) + for (std::size_t j = 0; j < MC; ++j) sub[i][j] = (*this)[i + row][j + column]; - } - } return sub; } // ---------------------------------------------------------------------------- -template template +template template modm::Matrix& modm::Matrix::replace(const U *data) { - for (uint_fast8_t i = 0; i < getNumberOfElements(); ++i) { + for (std::size_t i = 0; i < ElementCount; ++i) element[i] = data[i]; - } return *this; } // ---------------------------------------------------------------------------- -template -template +template +template modm::Matrix& -modm::Matrix::replace(uint8_t row, uint8_t column, const modm::Matrix &m) +modm::Matrix::replace(std::size_t row, std::size_t column, const modm::Matrix &m) { static_assert(MR <= ROWS, "replacement matrix can't be larger than the original"); static_assert(MC <= COLUMNS, "replacement matrix can't be larger than the original"); - for (uint_fast8_t i = 0; i < MR && (i + row) < ROWS; ++i) - { - for (uint_fast8_t j = 0; j < MC && (j + column) < COLUMNS; ++j) - { + for (std::size_t i = 0; i < MR && (i + row) < ROWS; ++i) + for (std::size_t j = 0; j < MC && (j + column) < COLUMNS; ++j) element[(i + row) * COLUMNS + (j + column)] = m[i][j]; - } - } return *this; } -// ---------------------------------------------------------------------------- -template +template modm::Matrix& -modm::Matrix::replaceRow(uint8_t index, const modm::Matrix &m) +modm::Matrix::replaceRow(std::size_t index, const modm::Matrix &m) { return replace(index, 0, m); } -// ---------------------------------------------------------------------------- -template +template modm::Matrix& -modm::Matrix::replaceColumn(uint8_t index, const modm::Matrix &m) +modm::Matrix::replaceColumn(std::size_t index, const modm::Matrix &m) { return replace(0, index, m); } -// ---------------------------------------------------------------------------- -template +template modm::Matrix -modm::Matrix::addRow(uint8_t index, const modm::Matrix &r) const +modm::Matrix::addRow(std::size_t index, const modm::Matrix &r) const { modm::Matrix m; - uint_fast8_t i = 0, ri = 0; + std::size_t i = 0, ri = 0; - for (; i < index; ++i) { + for (; i < index; ++i) m.replaceRow(ri++, getRow(i)); - } + m.replaceRow(ri++, r); - for (; i < ROWS+1; ++i) { + + for (; i < ROWS+1; ++i) m.replaceRow(ri++, getRow(i)); - } return m; } -// ---------------------------------------------------------------------------- -template +template modm::Matrix -modm::Matrix::addColumn(uint8_t index, const modm::Matrix &c) const +modm::Matrix::addColumn(std::size_t index, const modm::Matrix &c) const { modm::Matrix m; - uint_fast8_t i = 0, ci = 0; + std::size_t i = 0, ci = 0; - for (; i < index; ++i) { + for (; i < index; ++i) m.replaceColumn(ci++, getColumn(i)); - } + m.replaceColumn(ci++, c); - for (; i < COLUMNS+1; ++i) { + + for (; i < COLUMNS+1; ++i) m.replaceColumn(ci++, getColumn(i)); - } return m; } -// ---------------------------------------------------------------------------- -template +template modm::Matrix -modm::Matrix::removeRow(uint8_t index ) const +modm::Matrix::removeRow(std::size_t index ) const { if (index == 0) - { return subMatrix(1, 0); - } else if (index == (ROWS - 1)) - { return subMatrix(0, 0); - } else { Matrix m; - uint_fast8_t i = 0, ri = 0; + std::size_t i = 0, ri = 0; - for (; i < index; ++i) { + for (; i < index; ++i) m.replaceRow(ri++, getRow(i)); - } + ++i; // skip one row - for (; i < ROWS; ++i) { + + for (; i < ROWS; ++i) m.replaceRow(ri++, getRow(i)); - } return m; } } -// ---------------------------------------------------------------------------- -template +template modm::Matrix -modm::Matrix::removeColumn(uint8_t index) const +modm::Matrix::removeColumn(std::size_t index) const { if (index == 0) - { return subMatrix(0, 1); - } else if (index == (COLUMNS - 1)) - { return subMatrix(0, 0); - } else { Matrix m; - uint_fast8_t i = 0, ci = 0; + std::size_t i = 0, ci = 0; - for (; i < index; ++i) { + for (; i < index; ++i) m.replaceColumn(ci++, getColumn(i)); - } + ++i; // skip one column - for (; i < COLUMNS; ++i) { + + for (; i < COLUMNS; ++i) m.replaceColumn(ci++, getColumn(i)); - } return m; } } // ---------------------------------------------------------------------------- -template +template modm::IOStream& modm::operator << (modm::IOStream& os, const modm::Matrix &m) { os << "{ "; - for (uint_fast8_t i = 0; i < ROWS; ++i) + for (std::size_t i = 0; i < ROWS; ++i) { os << "{ "; - for (uint_fast8_t j = 0; j < COLUMNS; ++j) + for (std::size_t j = 0; j < COLUMNS; ++j) { os << m.element[i * COLUMNS + j]; if (j < COLUMNS-1) - { os << ", "; - } } os << " }"; if (i < ROWS-1) - { os << ", \n"; - } } os << " }"; return os; @@ -621,7 +494,6 @@ modm::determinant(const modm::Matrix &m) return m[0][0]; } -// ---------------------------------------------------------------------------- template T modm::determinant(const modm::Matrix &m) @@ -629,35 +501,29 @@ modm::determinant(const modm::Matrix &m) return (m[0][0] * m[1][1] - m[0][1] * m[1][0]); } -// ---------------------------------------------------------------------------- -template +template T modm::determinant(const modm::Matrix &m) { // not the most efficient way, but should work for now... T value = 0; int8_t factor = 1; - for (uint_fast8_t i = 0; i < N; ++i) + for (std::size_t i = 0; i < N; ++i) { T coeff = m[0][i]; modm::Matrix subM; - for (uint_fast8_t x = 0; x < i; ++x) { - for (uint_fast8_t y = 1; y < N; ++y) { + for (std::size_t x = 0; x < i; ++x) + for (std::size_t y = 1; y < N; ++y) subM[y-1][x] = m[y][x]; - } - } - for (uint_fast8_t x = i+1; x < N; ++x) { - for (uint_fast8_t y = 1; y < N; ++y) { + for (std::size_t x = i+1; x < N; ++x) + for (std::size_t y = 1; y < N; ++y) subM[y-1][x-1] = m[y][x]; - } - } value += coeff * factor * determinant(subM); factor *= -1; } return value; -} - +} \ No newline at end of file diff --git a/test/config/hosted.xml b/test/config/hosted.xml index 660ea5c22f..ff96334d73 100644 --- a/test/config/hosted.xml +++ b/test/config/hosted.xml @@ -7,6 +7,6 @@ modm:platform:core modm:driver:terminal - modm-test:test:** + modm-test:test:math diff --git a/test/modm/math/geometry/location_2d_test.cpp b/test/modm/math/geometry/location_2d_test.cpp index b40322855f..e32ebc4e8f 100644 --- a/test/modm/math/geometry/location_2d_test.cpp +++ b/test/modm/math/geometry/location_2d_test.cpp @@ -45,7 +45,7 @@ Location2DTest::testAccessors() TEST_ASSERT_EQUALS(location.getPosition(), modm::Vector2i(30, 40)); - location.setPosition(50, 60); + location.setPosition({50, 60}); TEST_ASSERT_EQUALS(location.getPosition(), modm::Vector2i(50, 60)); @@ -110,11 +110,9 @@ Location2DTest::testMove() void Location2DTest::testConvert() { - modm::Location2D a( - modm::Vector(-10.65, 20.31), - M_PI); + modm::Location2D a({-10.65, 20.31}, M_PI); - modm::Location2D b = a.convert(); + modm::Location2D b(a); TEST_ASSERT_EQUALS(b.getX(), -11); TEST_ASSERT_EQUALS(b.getY(), 20); diff --git a/test/modm/math/geometry/vector2_test.cpp b/test/modm/math/geometry/vector2_test.cpp index c788deb84b..8c12b65757 100644 --- a/test/modm/math/geometry/vector2_test.cpp +++ b/test/modm/math/geometry/vector2_test.cpp @@ -134,8 +134,8 @@ Vector2Test::testOperators() TEST_ASSERT_EQUALS((a * 3).getY(), 5*3); TEST_ASSERT_EQUALS((3 * a).getX(), 3*7); TEST_ASSERT_EQUALS((3 * a).getY(), 3*5); - TEST_ASSERT_EQUALS((b / 2).getX(), -18/2); - TEST_ASSERT_EQUALS((b / 2).getY(), 4); // 3.5 -> rounded 4 + TEST_ASSERT_EQUALS((b / 2.0).getX(), -18/2); + TEST_ASSERT_EQUALS((b / 2.0).getY(), 4); // 3.5 -> rounded 4 -b; TEST_ASSERT_EQUALS(b.getX(), -18); @@ -322,7 +322,7 @@ Vector2Test::testConversion() TEST_ASSERT_EQUALS(a.getX(), 12.763f); TEST_ASSERT_EQUALS(a.getY(), -13.3123f); - modm::Vector2i b = a.convert(); + modm::Vector2i b(a); TEST_ASSERT_EQUALS(b.getX(), 13); TEST_ASSERT_EQUALS(b.getY(), -13); diff --git a/test/modm/math/geometry/vector_test.cpp b/test/modm/math/geometry/vector_test.cpp index 9e2ada7597..354533f15f 100644 --- a/test/modm/math/geometry/vector_test.cpp +++ b/test/modm/math/geometry/vector_test.cpp @@ -199,6 +199,24 @@ void VectorTest::testConvert() modm::Vector f(1.3, 2.7); modm::Vector d(1.3, 2.7); + // convert() is deprecated but we still test for b.c. + modm::Vector d2 = f.convert(); + TEST_ASSERT_EQUALS_FLOAT(d2.x, 1.3); + TEST_ASSERT_EQUALS_FLOAT(d2.y, 2.7); + // convert() is deprecated but we still test for b.c. + modm::Vector f2 = d.convert(); + TEST_ASSERT_EQUALS_FLOAT(f2.x, 1.3); + TEST_ASSERT_EQUALS_FLOAT(f2.y, 2.7); + + // Conversion constructor replaces convert() + modm::Vector d3(f); + TEST_ASSERT_EQUALS_FLOAT(d3.x, 1.3); + TEST_ASSERT_EQUALS_FLOAT(d3.y, 2.7); + // Conversion constructor replaces convert() + modm::Vector f3(d); + TEST_ASSERT_EQUALS_FLOAT(f3.x, 1.3); + TEST_ASSERT_EQUALS_FLOAT(f3.y, 2.7); + modm::Vector u8(1.3, 2.7); TEST_ASSERT_EQUALS(u8.x, 1); TEST_ASSERT_EQUALS(u8.y, 3); @@ -207,15 +225,7 @@ void VectorTest::testConvert() TEST_ASSERT_EQUALS(i8.x, 1); TEST_ASSERT_EQUALS(i8.y, 3); - modm::Vector u16(1.3, 2.7); - TEST_ASSERT_EQUALS(u16.x, 1); - TEST_ASSERT_EQUALS(u16.y, 3); - - modm::Vector i16(1.3, 2.7); - TEST_ASSERT_EQUALS(i16.x, 1); - TEST_ASSERT_EQUALS(i16.y, 3); - - modm::Vector d2 = f.convert(); - - modm::Vector f2 = f.convert(); + modm::Vector i82(f); + TEST_ASSERT_EQUALS(i82.x, 1); + TEST_ASSERT_EQUALS(i82.y, 3); } diff --git a/test/modm/math/geometry/vector_test.hpp b/test/modm/math/geometry/vector_test.hpp index 4ffb83e8a2..262b416b39 100644 --- a/test/modm/math/geometry/vector_test.hpp +++ b/test/modm/math/geometry/vector_test.hpp @@ -34,4 +34,7 @@ class VectorTest : public unittest::TestSuite void testLength(); + + void + testConvert(); }; diff --git a/test/modm/math/matrix_test.cpp b/test/modm/math/matrix_test.cpp index 77f5ee3737..0119c3fd11 100644 --- a/test/modm/math/matrix_test.cpp +++ b/test/modm/math/matrix_test.cpp @@ -44,8 +44,8 @@ MatrixTest::testConstruction() modm::Matrix b(n); - TEST_ASSERT_EQUALS(b.getNumberOfRows(), 3); - TEST_ASSERT_EQUALS(b.getNumberOfColumns(), 2); + TEST_ASSERT_EQUALS(b.getNumberOfRows(), std::size_t(3)); + TEST_ASSERT_EQUALS(b.getNumberOfColumns(), std::size_t(2)); TEST_ASSERT_EQUALS(b[0][0], 1); TEST_ASSERT_EQUALS(b[0][1], 2);