From d95473e3a3024d061d9425aa0124e322237c585b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Tue, 21 Feb 2017 17:43:42 +0100 Subject: [PATCH 01/11] Improved math::Vector code and added tests. --- include/cece/math/Vector.hpp | 1042 ++++++++++++++++++++++--------- include/cece/math/Zero.hpp | 6 +- include/cece/math/constants.hpp | 6 +- unittests/math/CMakeLists.txt | 3 +- unittests/math/Vector_test.cpp | 650 +++++++++++++++++++ 5 files changed, 1421 insertions(+), 286 deletions(-) create mode 100644 unittests/math/Vector_test.cpp diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index 23c4480..c3537b6 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -1,5 +1,5 @@ /* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2016 */ +/* Georgiev Lab (c) 2015-2017 */ /* ************************************************************************ */ /* Department of Cybernetics */ /* Faculty of Applied Sciences */ @@ -29,6 +29,7 @@ // C++ #include +#include #include // CeCe @@ -49,14 +50,16 @@ namespace math { /* ************************************************************************ */ /** - * @brief N dimensional vector. + * @brief N dimensional vector. * - * @tparam T Element type. - * @tparam N Number of elements. + * @tparam T Element type. + * @tparam N Number of elements. */ -template +template class BasicVector { + static_assert(N > 0, "Cannot create empty vector"); + // Public Types public: @@ -65,62 +68,77 @@ class BasicVector /// BasicVector value type. using ValueType = T; + /// Element type squared. + using ValueTypeSq = decltype(std::declval() * std::declval()); -// Public Contants + +// Public Ctors public: - /// Number of elements - static constexpr unsigned SIZE = N; + /** + * @brief Default constructor. + */ + BasicVector() noexcept; -// Public Ctors -public: + /** + * @brief Constructor. + * + * @param data The source data. + */ + BasicVector(std::initializer_list data) noexcept; /** - * @brief Default constructor. + * @brief Constructor. + * + * @param data The source data. */ - BasicVector() noexcept - : m_data{} - { - // Nothing to do - } + explicit BasicVector(T (&data)[N]) noexcept; /** - * @brief Constructor. + * @brief Constructor. * - * @param data + * @param data The source data. */ - explicit BasicVector(StaticArray data) noexcept - : m_data(data) - { - // Nothing to do - } + explicit BasicVector(StaticArray data) noexcept; /** - * @brief Zero value constructor. + * @brief Zero value constructor. + * + * @param[in] zero The zero value. */ - BasicVector(Zero_t) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] = T{}; - } + BasicVector(Zero_t zero) noexcept; /** - * @brief Copy constructor. + * @brief Copy constructor. * - * @param v Source vector. + * @param[in] src The source vector. */ - template - explicit BasicVector(const BasicVector& v) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] = static_cast(v[i]); - } + BasicVector(const BasicVector& src) noexcept; + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + */ + BasicVector(BasicVector&& src) noexcept; + + + /** + * @brief Copy constructor. + * + * @param v The source vector. + * + * @tparam T2 The source vector element type. + */ + template::value>::type* = nullptr> + explicit BasicVector(const BasicVector& src) noexcept; // Public Operators @@ -128,170 +146,220 @@ class BasicVector /** - * @brief Unary plus operator. + * @brief Copy constructor. * - * @return + * @param[in] zero The zero value. + * + * @return *this. */ - BasicVector operator+() const noexcept - { - return *this; - } + BasicVector& operator=(Zero_t zero) noexcept; /** - * @brief Unary minus operator. + * @brief Copy constructor. * - * @return + * @param[in] data The source data. + * + * @return *this. */ - BasicVector operator-() const noexcept - { - BasicVector res; + BasicVector& operator=(std::initializer_list data) noexcept; - for (unsigned i = 0; i < N; ++i) - res[i] = -m_data[i]; - return res; - } + /** + * @brief Copy constructor. + * + * @param[in] data The source data. + * + * @return *this. + */ + BasicVector& operator=(T (&data)[N]) noexcept; /** - * @brief Addition operator. + * @brief Copy constructor. * - * @tparam T1 Type of right operand. + * @param[in] data The source data. * - * @param rhs Right operand. + * @return *this. + */ + BasicVector& operator=(StaticArray data) noexcept; + + + /** + * @brief Copy constructor. * - * @return *this. + * @param[in] src The source vector. + * + * @return *this. */ - template::value>::type* = nullptr> - BasicVector& operator+=(const BasicVector& rhs) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] += rhs[i]; + BasicVector& operator=(const BasicVector& src) noexcept; - return *this; - } + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + BasicVector& operator=(BasicVector&& src) noexcept; /** - * @brief Subtraction operator. + * @brief Copy constructor. * - * @tparam T1 Type of value in BasicVector operand. + * @param v The source vector. * - * @param rhs Right operand. + * @tparam T2 The source vector element type. * - * @return *this. + * @return *this. */ - template::value>::type* = nullptr> - BasicVector& operator-=(const BasicVector& rhs) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] -= rhs[i]; + template::value>::type* = nullptr> + BasicVector& operator=(const BasicVector& src) noexcept; - return *this; - } + + /** + * @brief Unary plus operator. + * + * @return Vector. + */ + BasicVector operator+() const noexcept; /** - * @brief Multiplication operator. + * @brief Unary minus operator. * - * @tparam T1 Type of right operand. + * @return Vector. + */ + BasicVector operator-() const noexcept; + + + /** + * @brief Addition operator. * - * @param rhs Right operand. + * @param rhs Right operand. * - * @return *this. + * @tparam T1 Type of right operand. + * + * @return *this. */ - template::value>::type* = nullptr> - BasicVector& operator*=(T1 rhs) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] *= rhs; - - return *this; - } + template() + std::declval()), + T + >::value>::type* = nullptr> + BasicVector& operator+=(const BasicVector& rhs) noexcept; /** - * @brief Multiplication operator. + * @brief Subtraction operator. * - * @tparam T1 Type of value in BasicVector operand. + * @param rhs Right operand. * - * @param rhs Right operand. + * @tparam T1 Type of value in BasicVector operand. * - * @return *this. + * @return *this. */ - template::value>::type* = nullptr> - BasicVector& operator*=(const BasicVector& rhs) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] *= rhs[i]; - - return *this; - } + template() - std::declval()), + T + >::value>::type* = nullptr> + BasicVector& operator-=(const BasicVector& rhs) noexcept; /** - * @brief Division operator. + * @brief Multiplication operator. * - * @tparam T1 Type of right operand. + * @param rhs Right operand. * - * @param rhs Right operand. + * @tparam T1 Type of right operand. * - * @return *this. + * @return *this. */ - template::value>::type* = nullptr> - BasicVector& operator/=(T1 rhs) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] /= rhs; + template() * std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector& operator*=(T1 rhs) noexcept; - return *this; - } + + /** + * @brief Multiplication operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector operand. + * + * @return *this. + */ + template() * std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector& operator*=(const BasicVector& rhs) noexcept; /** - * @brief Division operator. + * @brief Division operator. * - * @tparam T1 Type of value in BasicVector operand. + * @param rhs Right operand. * - * @param rhs Right operand. + * @tparam T1 Type of right operand. * - * @return *this. + * @return *this. */ - template::value>::type* = nullptr> - BasicVector& operator/=(const BasicVector& rhs) noexcept - { - for (unsigned i = 0; i < N; ++i) - m_data[i] /= rhs[i]; + template() / std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector& operator/=(T1 rhs) noexcept; - return *this; - } + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector operand. + * + * @return *this. + */ + template() / std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector& operator/=(const BasicVector& rhs) noexcept; /** - * @brief Access operator. + * @brief Access operator. * - * @param pos + * @param pos The position. * - * @return + * @return Reference to the element. */ - T& operator[](unsigned pos) noexcept - { - return m_data[pos]; - } + T& operator[](int pos) noexcept; /** - * @brief Access operator. + * @brief Access operator. * - * @param pos + * @param pos The position. * - * @return + * @return Reference to the element. */ - const T& operator[](unsigned pos) const noexcept - { - return m_data[pos]; - } + const T& operator[](int pos) const noexcept; // Public Accessors @@ -299,37 +367,45 @@ class BasicVector /** - * @brief Check if given value is in given range. + * @brief Returns vector size. * - * @param value Given value. - * @param low Minimum value (>=). - * @param high Maximum value (<). + * @return The size. + */ + int getSize() const noexcept; + + + /** + * @brief Check if given value is in given range. * - * @return + * @param value Given value. + * @param low Minimum value (>=). + * @param high Maximum value (<). + * + * @return If given value is in given range. */ - static bool inRange(T value, T low, T high) noexcept - { - return value >= low && value < high; - } + static bool inRange(T value, T low, T high) noexcept; /** - * @brief Check if current vector is in given range. + * @brief Check if current vector is in given range. * - * @param low Minimum coordinates (>=). - * @param high Maximum coordinates (<). + * @param low Minimum coordinates (>=). + * @param high Maximum coordinates (<). * - * @return + * @return If current value is in given range. */ - bool inRange(const BasicVector& low, const BasicVector& high) const noexcept - { - bool res = true; + bool inRange(const BasicVector& low, const BasicVector& high) const noexcept; - for (unsigned i = 0; i < N; ++i) - res = res && inRange(m_data[i], low[i], high[i]); - return res; - } + /** + * @brief Check if current vector is in given range where the low range + * is Zero vector. + * + * @param high Maximum coordinates (<). + * + * @return If current value is in given range. + */ + bool inRange(const BasicVector& high) const noexcept; // Public Operations @@ -337,87 +413,60 @@ class BasicVector /** - * @brief Calculate vector length. + * @brief Calculate vector length. * - * @return + * @return The length. */ - T getLength() const noexcept - { - using std::sqrt; - return static_cast(sqrt(getLengthSquared())); - } + ValueType getLength() const noexcept; /** - * @brief Calculate vector length - squared. + * @brief Calculate vector length - squared. * - * @return + * @return The length squared. */ - decltype(T{} * T{}) getLengthSquared() const noexcept - { - return dot(*this); - } + ValueTypeSq getLengthSquared() const noexcept; /** - * @brief Calculate dot of two vectors. + * @brief Calculate dot of two vectors. * - * @param rhs Second vector. + * @param rhs Second vector. * - * @return Dot product. + * @return Dot product. */ - decltype(T{} * T{}) dot(const BasicVector& rhs) const noexcept - { - decltype(T{} * T{}) res{}; - - for (unsigned i = 0; i < N; ++i) - res += m_data[i] * rhs[i]; - - return res; - } + ValueTypeSq dot(const BasicVector& rhs) const noexcept; /** - * @brief Calculate vectors squared distance. + * @brief Calculate vectors squared distance. * - * @param rhs Second vector. + * @param rhs Second vector. * - * @return Distance. + * @return Distance. */ - decltype(std::declval() * std::declval()) distanceSquared(const BasicVector& rhs) const noexcept - { - return (*this - rhs).getLengthSquared(); - } + ValueTypeSq distanceSquared(const BasicVector& rhs) const noexcept; /** - * @brief Calculate vectors distance. + * @brief Calculate vectors distance. * - * @param rhs Second vector. + * @param rhs Second vector. * - * @return Distance. + * @return Distance. */ - T distance(const BasicVector& rhs) const noexcept - { - return (*this - rhs).getLength(); - } + ValueType distance(const BasicVector& rhs) const noexcept; /** - * @brief Inverse current vector (1 / *this). + * @brief Inverse current vector (1 / *this). * - * @return + * @tparam T2 Type of result vector's element. + * + * @return Inversed vector. */ - template - BasicVector inversed() const noexcept - { - BasicVector res; - - for (unsigned i = 0; i < N; ++i) - res[i] = T2(1) / m_data[i]; - - return res; - } + template + BasicVector inversed() const noexcept; // Public Operations @@ -431,23 +480,15 @@ class BasicVector * * @return */ - static BasicVector createSingle(T val) noexcept - { - BasicVector res; - - for (unsigned i = 0; i < N; ++i) - res[i] = val; - - return res; - } + static BasicVector createSingle(T val) noexcept; // Private Data Members private: - /// BasicVector data. StaticArray m_data; + }; /* ************************************************************************ */ @@ -472,7 +513,7 @@ class BasicVector /// Number of elements - static constexpr unsigned SIZE = 2; + static constexpr int SIZE = 2; // Public Ctors @@ -540,7 +581,7 @@ class BasicVector * * @return */ - T& operator[](unsigned pos) noexcept + T& operator[](int pos) noexcept { CECE_ASSERT(pos < SIZE); return (&m_x)[pos]; @@ -554,7 +595,7 @@ class BasicVector * * @return */ - const T& operator[](unsigned pos) const noexcept + const T& operator[](int pos) const noexcept { CECE_ASSERT(pos < SIZE); return (&m_x)[pos]; @@ -700,7 +741,7 @@ class BasicVector * * @return */ - unsigned getSize() const noexcept + int getSize() const noexcept { return SIZE; } @@ -992,7 +1033,7 @@ class BasicVector /// Number of elements - static constexpr unsigned SIZE = 3; + static constexpr int SIZE = 3; // Public Ctors @@ -1065,7 +1106,7 @@ class BasicVector * * @return */ - T& operator[](unsigned pos) noexcept + T& operator[](int pos) noexcept { CECE_ASSERT(pos < SIZE); return (&m_x)[pos]; @@ -1079,7 +1120,7 @@ class BasicVector * * @return */ - const T& operator[](unsigned pos) const noexcept + const T& operator[](int pos) const noexcept { CECE_ASSERT(pos < SIZE); return (&m_x)[pos]; @@ -1231,7 +1272,7 @@ class BasicVector * * @return */ - unsigned getSize() const noexcept + int getSize() const noexcept { return SIZE; } @@ -1586,16 +1627,30 @@ using VectorInt = Vector; /* ************************************************************************ */ /** - * @brief Vector of unsigned int. + * @brief Vector of float. + */ +using VectorFloat = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of float. + */ +using VectorDouble = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of float. */ -using VectorUint = Vector; +using VectorLongDouble = Vector; /* ************************************************************************ */ /** * @brief Vector of float. */ -using VectorFloat = Vector; +using VectorReal = Vector; /* ************************************************************************ */ @@ -1611,12 +1666,12 @@ using VectorFloat = Vector; * * @return Result vector. */ -template +template inline BasicVector operator+(const BasicVector& lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] + rhs[i]; return res; @@ -1658,12 +1713,12 @@ inline BasicVector operator+(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator+(const BasicVector& lhs, T2 rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] + rhs; return res; @@ -1705,12 +1760,12 @@ inline BasicVector operator+(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator+(T1 lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs + rhs[i]; return res; @@ -1751,12 +1806,12 @@ inline BasicVector operator+(T1 lhs, const BasicVector * * @return Result vector. */ -template +template inline BasicVector operator-(const BasicVector& lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] - rhs[i]; return res; @@ -1797,12 +1852,12 @@ inline BasicVector operator-(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator-(const BasicVector& lhs, T2 rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] - rhs; return res; @@ -1843,12 +1898,12 @@ inline BasicVector operator-(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator-(T1 lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs - rhs[i]; return res; @@ -1889,12 +1944,12 @@ inline BasicVector operator-(T1 lhs, const BasicVector * * @return Result vector. */ -template +template inline BasicVector operator*(const BasicVector& lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] * rhs[i]; return res; @@ -1935,12 +1990,12 @@ inline BasicVector operator*(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator*(const BasicVector& lhs, T2 rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] * rhs; return res; @@ -1981,12 +2036,12 @@ inline BasicVector operator*(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator*(T1 lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs * rhs[i]; return res; @@ -2027,12 +2082,12 @@ inline BasicVector operator*(T1 lhs, const BasicVector * * @return Result vector. */ -template +template inline BasicVector operator/(const BasicVector& lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] / rhs[i]; return res; @@ -2073,12 +2128,12 @@ inline BasicVector operator/(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator/(const BasicVector& lhs, T2 rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] / rhs; return res; @@ -2119,12 +2174,12 @@ inline BasicVector operator/(const BasicVector& * * @return Result vector. */ -template +template inline BasicVector operator/(T1 lhs, const BasicVector& rhs) noexcept { BasicVector res; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res[i] = lhs / rhs[i]; return res; @@ -2162,12 +2217,12 @@ inline BasicVector operator/(T1 lhs, const BasicVector * * @return */ -template +template inline bool operator==(const BasicVector& lhs, const BasicVector& rhs) noexcept { bool res = true; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res = res && lhs[i] == rhs[i]; return res; @@ -2202,7 +2257,7 @@ inline bool operator==(const BasicVector& lhs, const BasicVector& * * @return */ -template +template inline bool operator==(const BasicVector& lhs, Zero_t rhs) noexcept { return lhs == BasicVector(Zero); @@ -2218,7 +2273,7 @@ inline bool operator==(const BasicVector& lhs, Zero_t rhs) noexcept * * @return */ -template +template inline bool operator==(Zero_t lhs, const BasicVector& rhs) noexcept { return BasicVector(Zero) == rhs; @@ -2234,7 +2289,7 @@ inline bool operator==(Zero_t lhs, const BasicVector& rhs) noexcept * * @return */ -template +template inline bool operator!=(const BasicVector& lhs, const BasicVector& rhs) noexcept { return !operator==(lhs, rhs); @@ -2250,7 +2305,7 @@ inline bool operator!=(const BasicVector& lhs, const BasicVector& * * @return */ -template +template inline bool operator!=(const BasicVector& lhs, Zero_t rhs) noexcept { return !operator==(lhs, rhs); @@ -2266,7 +2321,7 @@ inline bool operator!=(const BasicVector& lhs, Zero_t rhs) noexcept * * @return */ -template +template inline bool operator!=(Zero_t lhs, const BasicVector& rhs) noexcept { return !operator==(lhs, rhs); @@ -2282,12 +2337,12 @@ inline bool operator!=(Zero_t lhs, const BasicVector& rhs) noexcept * * @return */ -template +template inline bool operator<(const BasicVector& lhs, const BasicVector& rhs) noexcept { bool res = true; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res = res && ((lhs[i] < rhs[i]) || !(rhs[i] < lhs[i])); return res; @@ -2303,7 +2358,7 @@ inline bool operator<(const BasicVector& lhs, const BasicVector& r * * @return */ -template +template inline bool operator<(const BasicVector& lhs, Zero_t rhs) noexcept { return lhs < BasicVector{Zero}; @@ -2319,7 +2374,7 @@ inline bool operator<(const BasicVector& lhs, Zero_t rhs) noexcept * * @return */ -template +template inline bool operator<(Zero_t lhs, const BasicVector& rhs) noexcept { return BasicVector{Zero} < rhs; @@ -2335,7 +2390,7 @@ inline bool operator<(Zero_t lhs, const BasicVector& rhs) noexcept * * @return */ -template +template inline bool operator<=(const BasicVector& lhs, const BasicVector& rhs) noexcept { return !operator>(lhs, rhs); @@ -2351,7 +2406,7 @@ inline bool operator<=(const BasicVector& lhs, const BasicVector& * * @return */ -template +template inline bool operator<=(const BasicVector& lhs, Zero_t rhs) noexcept { return !operator>(lhs, rhs); @@ -2367,7 +2422,7 @@ inline bool operator<=(const BasicVector& lhs, Zero_t rhs) noexcept * * @return */ -template +template inline bool operator<=(Zero_t lhs, const BasicVector& rhs) noexcept { return !operator>(lhs, rhs); @@ -2383,7 +2438,7 @@ inline bool operator<=(Zero_t lhs, const BasicVector& rhs) noexcept * * @return */ -template +template inline bool operator>(const BasicVector& lhs, const BasicVector& rhs) noexcept { // Reversed operands @@ -2400,7 +2455,7 @@ inline bool operator>(const BasicVector& lhs, const BasicVector& r * * @return */ -template +template inline bool operator>(const BasicVector& lhs, Zero_t rhs) noexcept { // Reversed operands @@ -2417,7 +2472,7 @@ inline bool operator>(const BasicVector& lhs, Zero_t rhs) noexcept * * @return */ -template +template inline bool operator>(Zero_t lhs, const BasicVector& rhs) noexcept { // Reversed operands @@ -2434,7 +2489,7 @@ inline bool operator>(Zero_t lhs, const BasicVector& rhs) noexcept * * @return */ -template +template inline bool operator>=(const BasicVector& lhs, const BasicVector& rhs) noexcept { return !operator<(lhs, rhs); @@ -2450,7 +2505,7 @@ inline bool operator>=(const BasicVector& lhs, const BasicVector& * * @return */ -template +template inline bool operator>=(const BasicVector& lhs, Zero_t rhs) noexcept { return !operator<(lhs, rhs); @@ -2466,7 +2521,7 @@ inline bool operator>=(const BasicVector& lhs, Zero_t rhs) noexcept * * @return */ -template +template inline bool operator>=(Zero_t lhs, const BasicVector& rhs) noexcept { return !operator<(lhs, rhs); @@ -2482,12 +2537,12 @@ inline bool operator>=(Zero_t lhs, const BasicVector& rhs) noexcept * * @return Dot product. */ -template +template inline decltype(T1{} * T2{}) dot(const BasicVector& lhs, const BasicVector& rhs) noexcept { decltype(T1{} * T2{}) res{}; - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) res += lhs[i] * rhs[i]; return res; @@ -2557,10 +2612,10 @@ cross(const T1& lhs, const BasicVector& rhs) noexcept * * @return is. */ -template +template io::InStream& operator>>(io::InStream& is, BasicVector& vector) { - unsigned i = 0; + int i = 0; for (; i < N; ++i) { @@ -2573,7 +2628,7 @@ io::InStream& operator>>(io::InStream& is, BasicVector& vector) // Copy missing values // TODO: have this feature? - for (unsigned j = i; j < N; ++j) + for (int j = i; j < N; ++j) vector[j] = vector[i - 1]; return is; @@ -2589,10 +2644,10 @@ io::InStream& operator>>(io::InStream& is, BasicVector& vector) * * @return os. */ -template +template io::OutStream& operator<<(io::OutStream& os, const BasicVector& vector) noexcept { - for (unsigned i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) { if (i != 0) os << " "; @@ -2606,8 +2661,437 @@ io::OutStream& operator<<(io::OutStream& os, const BasicVector& vector) no /* ************************************************************************ */ extern template class BasicVector; -extern template class BasicVector; -extern template class BasicVector; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector() noexcept + : m_data{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector(std::initializer_list data) noexcept +{ + CECE_ASSERT(data.size() == N); + + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m_data[i] = *it; +} + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector(T (&data)[N]) noexcept +{ + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m_data[i] = *it; +} + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector(StaticArray data) noexcept + : m_data(data) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector(Zero_t zero) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = T{}; +} + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector(const BasicVector& src) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = src.m_data[i]; +} + +/* ************************************************************************ */ + +template +inline BasicVector::BasicVector(BasicVector&& src) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = std::move(src.m_data[i]); +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline BasicVector::BasicVector(const BasicVector& src) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = T(src[i]); +} + +/* ************************************************************************ */ + +template +inline BasicVector& BasicVector::operator=(Zero_t zero) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = T{}; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector& BasicVector::operator=(std::initializer_list data) noexcept +{ + CECE_ASSERT(data.size() == N); + + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m_data[i] = *it; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector& BasicVector::operator=(T (&data)[N]) noexcept +{ + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m_data[i] = *it; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector& BasicVector::operator=(StaticArray data) noexcept +{ + m_data = data; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector& BasicVector::operator=(const BasicVector& src) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = src.m_data[i]; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector& BasicVector::operator=(BasicVector&& src) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = std::move(src.m_data[i]); + + return *this; +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline BasicVector& BasicVector::operator=(const BasicVector& src) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] = T(src[i]); + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector BasicVector::operator+() const noexcept +{ + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector BasicVector::operator-() const noexcept +{ + BasicVector res; + + for (int i = 0; i < N; ++i) + res[i] = -m_data[i]; + + return res; +} + +/* ************************************************************************ */ + +template +template() + std::declval()), + T +>::value>::type*> +inline BasicVector& BasicVector::operator+=(const BasicVector& rhs) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] += rhs[i]; + + return *this; +} + +/* ************************************************************************ */ + +template +template() - std::declval()), + T +>::value>::type*> +inline BasicVector& BasicVector::operator-=(const BasicVector& rhs) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] -= rhs[i]; + + return *this; +} + +/* ************************************************************************ */ + +template +template() * std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector& BasicVector::operator*=(T1 rhs) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] *= rhs; + + return *this; +} + +/* ************************************************************************ */ + +template +template() * std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector& BasicVector::operator*=(const BasicVector& rhs) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] *= rhs[i]; + + return *this; +} + +/* ************************************************************************ */ + +template +template() / std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector& BasicVector::operator/=(T1 rhs) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] /= rhs; + + return *this; +} + +/* ************************************************************************ */ + +template +template() / std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector& BasicVector::operator/=(const BasicVector& rhs) noexcept +{ + for (int i = 0; i < N; ++i) + m_data[i] /= rhs[i]; + + return *this; +} + +/* ************************************************************************ */ + +template +inline T& BasicVector::operator[](int pos) noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < N); + return m_data[pos]; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector::operator[](int pos) const noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < N); + return m_data[pos]; +} + +/* ************************************************************************ */ + +template +int BasicVector::getSize() const noexcept +{ + return N; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector::inRange(T value, T low, T high) noexcept +{ + return value >= low && value < high; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector::inRange(const BasicVector& low, const BasicVector& high) const noexcept +{ + bool res = true; + + for (int i = 0; i < N; ++i) + res = res && inRange(m_data[i], low[i], high[i]); + + return res; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector::inRange(const BasicVector& high) const noexcept +{ + return inRange(Zero, high); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector::ValueType BasicVector::getLength() const noexcept +{ + using std::sqrt; + return static_cast(sqrt(getLengthSquared())); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector::ValueTypeSq BasicVector::getLengthSquared() const noexcept +{ + return dot(*this); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector::ValueTypeSq BasicVector::dot(const BasicVector& rhs) const noexcept +{ + ValueTypeSq res{}; + + for (int i = 0; i < N; ++i) + res += m_data[i] * rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template +inline typename BasicVector::ValueTypeSq BasicVector::distanceSquared(const BasicVector& rhs) const noexcept +{ + return (*this - rhs).getLengthSquared(); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector::ValueType BasicVector::distance(const BasicVector& rhs) const noexcept +{ + return (*this - rhs).getLength(); +} + +/* ************************************************************************ */ + +template +template +inline BasicVector BasicVector::inversed() const noexcept +{ + BasicVector res; + + for (int i = 0; i < N; ++i) + res[i] = T2(1) / m_data[i]; + + return res; +} + +/* ************************************************************************ */ + +template +inline BasicVector BasicVector::createSingle(T val) noexcept +{ + BasicVector res; + + for (int i = 0; i < N; ++i) + res[i] = val; + + return res; +} /* ************************************************************************ */ diff --git a/include/cece/math/Zero.hpp b/include/cece/math/Zero.hpp index b02b3ca..7b13f36 100644 --- a/include/cece/math/Zero.hpp +++ b/include/cece/math/Zero.hpp @@ -1,5 +1,5 @@ /* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2016 */ +/* Georgiev Lab (c) 2015-2017 */ /* ************************************************************************ */ /* Department of Cybernetics */ /* Faculty of Applied Sciences */ @@ -33,8 +33,8 @@ namespace math { /* ************************************************************************ */ /** - * @brief Special value used by other types to check if value is zero. The idea is - * similar with nullptr (nullptr_t). + * @brief Special value used by other types to check if value is zero. The + * idea is similar with nullptr (nullptr_t). */ constexpr struct Zero_t {} Zero{}; diff --git a/include/cece/math/constants.hpp b/include/cece/math/constants.hpp index 18a6a27..1e97488 100644 --- a/include/cece/math/constants.hpp +++ b/include/cece/math/constants.hpp @@ -1,5 +1,5 @@ /* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2016 */ +/* Georgiev Lab (c) 2015-2017 */ /* ************************************************************************ */ /* Department of Cybernetics */ /* Faculty of Applied Sciences */ @@ -38,14 +38,14 @@ namespace math { /* ************************************************************************ */ /** - * @brief PI constant. + * @brief PI constant. */ constexpr RealType PI = 3.14159265359; /* ************************************************************************ */ /** - * @brief Euler number constant. + * @brief Euler number constant. */ constexpr RealType E = 2.718281828459; diff --git a/unittests/math/CMakeLists.txt b/unittests/math/CMakeLists.txt index 03f6f4e..dc505b8 100644 --- a/unittests/math/CMakeLists.txt +++ b/unittests/math/CMakeLists.txt @@ -1,5 +1,5 @@ # ######################################################################### # -# Georgiev Lab (c) 2015-2016 # +# Georgiev Lab (c) 2015-2017 # # ######################################################################### # # Department of Cybernetics # # Faculty of Applied Sciences # @@ -25,6 +25,7 @@ cece_add_test(core SOURCES + Vector_test.cpp VectorRangeTest.cpp ) diff --git a/unittests/math/Vector_test.cpp b/unittests/math/Vector_test.cpp new file mode 100644 index 0000000..e4ce1f2 --- /dev/null +++ b/unittests/math/Vector_test.cpp @@ -0,0 +1,650 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +// GTest +#include "gtest/gtest.h" + +// CeCe +#include "cece/math/Vector.hpp" + +/* ************************************************************************ */ + +using namespace cece; +using namespace cece::math; + +/* ************************************************************************ */ + +TEST(Vector, ctor) +{ + { + BasicVector vec; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + EXPECT_EQ(0, vec[3]); + EXPECT_EQ(0, vec[4]); + } + + { + BasicVector vec(Zero); + + EXPECT_EQ(10, vec.getSize()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + EXPECT_EQ(0, vec[3]); + EXPECT_EQ(0, vec[4]); + EXPECT_EQ(0, vec[5]); + EXPECT_EQ(0, vec[6]); + EXPECT_EQ(0, vec[7]); + EXPECT_EQ(0, vec[8]); + EXPECT_EQ(0, vec[9]); + } + + { + BasicVector vec = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + EXPECT_FLOAT_EQ(45.1f, vec[3]); + EXPECT_FLOAT_EQ(-34.0f, vec[4]); + } + + { + float data[5] = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + BasicVector vec(data); + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + EXPECT_FLOAT_EQ(45.1f, vec[3]); + EXPECT_FLOAT_EQ(-34.0f, vec[4]); + } + + { + StaticArray data = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + BasicVector vec(data); + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + EXPECT_FLOAT_EQ(45.1f, vec[3]); + EXPECT_FLOAT_EQ(-34.0f, vec[4]); + } + + { + const BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(0.0f, vec1[2]); + EXPECT_FLOAT_EQ(45.1f, vec1[3]); + EXPECT_FLOAT_EQ(-34.0f, vec1[4]); + + BasicVector vec2(vec1); + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(0.0f, vec2[2]); + EXPECT_FLOAT_EQ(45.1f, vec2[3]); + EXPECT_FLOAT_EQ(-34.0f, vec2[4]); + } + + { + BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(0.0f, vec1[2]); + EXPECT_FLOAT_EQ(45.1f, vec1[3]); + EXPECT_FLOAT_EQ(-34.0f, vec1[4]); + + BasicVector vec2(std::move(vec1)); + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(0.0f, vec2[2]); + EXPECT_FLOAT_EQ(45.1f, vec2[3]); + EXPECT_FLOAT_EQ(-34.0f, vec2[4]); + } + + { + const BasicVector vec1 = {1, 3, 0, 45, -34}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(0, vec1[2]); + EXPECT_EQ(45, vec1[3]); + EXPECT_EQ(-34, vec1[4]); + + BasicVector vec2(vec1); + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.0, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(0.0f, vec2[2]); + EXPECT_FLOAT_EQ(45.0f, vec2[3]); + EXPECT_FLOAT_EQ(-34.0f, vec2[4]); + } +} + +/* ************************************************************************ */ + +TEST(Vector, assignment) +{ + { + BasicVector vec{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + EXPECT_EQ(10, vec.getSize()); + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(1, vec[1]); + EXPECT_EQ(1, vec[2]); + EXPECT_EQ(1, vec[3]); + EXPECT_EQ(1, vec[4]); + EXPECT_EQ(1, vec[5]); + EXPECT_EQ(1, vec[6]); + EXPECT_EQ(1, vec[7]); + EXPECT_EQ(1, vec[8]); + EXPECT_EQ(1, vec[9]); + + vec = Zero; + + EXPECT_EQ(10, vec.getSize()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + EXPECT_EQ(0, vec[3]); + EXPECT_EQ(0, vec[4]); + EXPECT_EQ(0, vec[5]); + EXPECT_EQ(0, vec[6]); + EXPECT_EQ(0, vec[7]); + EXPECT_EQ(0, vec[8]); + EXPECT_EQ(0, vec[9]); + } + + { + BasicVector vec; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + EXPECT_EQ(0, vec[3]); + EXPECT_EQ(0, vec[4]); + + vec = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + EXPECT_FLOAT_EQ(45.1f, vec[3]); + EXPECT_FLOAT_EQ(-34.0f, vec[4]); + } + + { + BasicVector vec; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + EXPECT_EQ(0, vec[3]); + EXPECT_EQ(0, vec[4]); + + float data[5] = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + vec = data; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + EXPECT_FLOAT_EQ(45.1f, vec[3]); + EXPECT_FLOAT_EQ(-34.0f, vec[4]); + } + + { + BasicVector vec; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + EXPECT_EQ(0, vec[3]); + EXPECT_EQ(0, vec[4]); + + StaticArray data = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + vec = data; + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + EXPECT_FLOAT_EQ(45.1f, vec[3]); + EXPECT_FLOAT_EQ(-34.0f, vec[4]); + } + + { + const BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(0.0f, vec1[2]); + EXPECT_FLOAT_EQ(45.1f, vec1[3]); + EXPECT_FLOAT_EQ(-34.0f, vec1[4]); + + BasicVector vec2; + + vec2 = vec1; + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(0.0f, vec2[2]); + EXPECT_FLOAT_EQ(45.1f, vec2[3]); + EXPECT_FLOAT_EQ(-34.0f, vec2[4]); + } + + { + BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(0.0f, vec1[2]); + EXPECT_FLOAT_EQ(45.1f, vec1[3]); + EXPECT_FLOAT_EQ(-34.0f, vec1[4]); + + BasicVector vec2; + + vec2 = std::move(vec1); + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(0.0f, vec2[2]); + EXPECT_FLOAT_EQ(45.1f, vec2[3]); + EXPECT_FLOAT_EQ(-34.0f, vec2[4]); + } + + { + const BasicVector vec1 = {1, 3, 0, 45, -34}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(0, vec1[2]); + EXPECT_EQ(45, vec1[3]); + EXPECT_EQ(-34, vec1[4]); + + BasicVector vec2; + + vec2 = vec1; + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.0, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(0.0f, vec2[2]); + EXPECT_FLOAT_EQ(45.0f, vec2[3]); + EXPECT_FLOAT_EQ(-34.0f, vec2[4]); + } +} + +/* ************************************************************************ */ + +TEST(Vector, operators) +{ + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -300.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-300.8f, vec1[4]); + + BasicVector vec2 = +vec1; + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(2.0f, vec2[1]); + EXPECT_FLOAT_EQ(-5.0f, vec2[2]); + EXPECT_FLOAT_EQ(0.0f, vec2[3]); + EXPECT_FLOAT_EQ(-300.8f, vec2[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -300.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-300.8f, vec1[4]); + + BasicVector vec2 = -vec1; + + EXPECT_EQ(5, vec2.getSize()); + EXPECT_FLOAT_EQ(-1.0f, vec2[0]); + EXPECT_FLOAT_EQ(-2.0f, vec2[1]); + EXPECT_FLOAT_EQ(5.0f, vec2[2]); + EXPECT_FLOAT_EQ(0.0f, vec2[3]); + EXPECT_FLOAT_EQ(300.8f, vec2[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f, vec1[4]); + + BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + vec1 += vec2; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + EXPECT_FLOAT_EQ(-2.0f, vec1[2]); + EXPECT_FLOAT_EQ(4.0f, vec1[3]); + EXPECT_FLOAT_EQ(1.2f, vec1[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f, vec1[4]); + + BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + vec1 -= vec2; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(0.0f, vec1[0]); + EXPECT_FLOAT_EQ(0.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.0f, vec1[2]); + EXPECT_FLOAT_EQ(-4.0f, vec1[3]); + EXPECT_FLOAT_EQ(-8.8f, vec1[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f, vec1[4]); + + vec1 *= 2.0; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + EXPECT_FLOAT_EQ(-10.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-7.6f, vec1[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f, vec1[4]); + + BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + vec1 *= vec2; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + EXPECT_FLOAT_EQ(-15.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-19.0f, vec1[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f, vec1[4]); + + vec1 /= 2.0; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(0.5f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + EXPECT_FLOAT_EQ(-2.5f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-1.9f, vec1[4]); + } + + { + BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f, vec1[4]); + + BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + vec1 /= vec2; + + EXPECT_EQ(5, vec1.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + EXPECT_FLOAT_EQ(-5.0f / 3.0f, vec1[2]); + EXPECT_FLOAT_EQ(0.0f, vec1[3]); + EXPECT_FLOAT_EQ(-3.8f / 5.0f, vec1[4]); + } +} + +/* ************************************************************************ */ + +TEST(Vector, inRange) +{ + { + const BasicVector vecMin{-10.0f, -5.0f, 0.0f, 5.0f, 10.0f}; + const BasicVector vecMax{10.0f, 20.0f, 30.0f, 40.0f, 50.0f}; + + BasicVector vec1; + BasicVector vec2{-15.0f, 0.0f, 0.0f, 0.0f, 0.0f}; + BasicVector vec3{5.0f, 0.0f, 0.0f, 10.0f, 40.0f}; + BasicVector vec4{5.0f, 0.0f, 0.0f, 5.0f, 40.0f}; + + EXPECT_FALSE(vec1.inRange(vecMin, vecMax)); + EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); + EXPECT_TRUE(vec3.inRange(vecMin, vecMax)); + EXPECT_TRUE(vec4.inRange(vecMin, vecMax)); + } + + { + const BasicVector vecMax{10.0f, 20.0f, 30.0f, 40.0f, 50.0f}; + + BasicVector vec1; + BasicVector vec2{-15.0f, 0.0f, 0.0f, 0.0f, 0.0f}; + BasicVector vec3{5.0f, 0.0f, -3.0f, 0.0f, 40.0f}; + BasicVector vec4{5.0f, 0.0f, 0.0f, 5.0f, 40.0f}; + + EXPECT_TRUE(vec1.inRange(vecMax)); + EXPECT_FALSE(vec2.inRange(vecMax)); + EXPECT_FALSE(vec3.inRange(vecMax)); + EXPECT_TRUE(vec4.inRange(vecMax)); + } +} + +/* ************************************************************************ */ + +TEST(Vector, memberFunctions) +{ + { + const BasicVector vec; + + EXPECT_FLOAT_EQ(0, vec.getLength()); + } + + { + const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + + EXPECT_FLOAT_EQ(7.4162f, vec.getLength()); + } + + { + const BasicVector vec; + + EXPECT_FLOAT_EQ(0, vec.getLengthSquared()); + } + + { + const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + + EXPECT_FLOAT_EQ(55, vec.getLengthSquared()); + } + + { + const BasicVector vec; + + EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + } + + { + const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + + EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + } + + { + const BasicVector vec1; + const BasicVector vec2; + + EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); + } + + { + const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + + EXPECT_FLOAT_EQ(35, vec1.dot(vec2)); + } + + { + const BasicVector vec; + + EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + } + + { + const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + + EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + } + + { + const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + + EXPECT_FLOAT_EQ(40.0f, vec1.distanceSquared(vec2)); + } + + { + const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + + EXPECT_FLOAT_EQ(6.3245554f, vec1.distance(vec2)); + } + + { + const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + + auto inv = vec.inversed(); + + EXPECT_EQ(5, inv.getSize()); + EXPECT_FLOAT_EQ(1.0f, inv[0]); + EXPECT_FLOAT_EQ(0.5f, inv[1]); + EXPECT_FLOAT_EQ(1.0f / 3.0f, inv[2]); + EXPECT_FLOAT_EQ(0.25f, inv[3]); + EXPECT_FLOAT_EQ(0.2f, inv[4]); + } + + { + auto vec = BasicVector::createSingle(1); + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(1.0f, vec[0]); + EXPECT_FLOAT_EQ(1.0f, vec[1]); + EXPECT_FLOAT_EQ(1.0f, vec[2]); + EXPECT_FLOAT_EQ(1.0f, vec[3]); + EXPECT_FLOAT_EQ(1.0f, vec[4]); + } + + { + auto vec = BasicVector::createSingle(375.1721f); + + EXPECT_EQ(5, vec.getSize()); + EXPECT_FLOAT_EQ(375.1721f, vec[0]); + EXPECT_FLOAT_EQ(375.1721f, vec[1]); + EXPECT_FLOAT_EQ(375.1721f, vec[2]); + EXPECT_FLOAT_EQ(375.1721f, vec[3]); + EXPECT_FLOAT_EQ(375.1721f, vec[4]); + } +} + +/* ************************************************************************ */ From a76650de97ba33eae1ed03d371cddf51e0128678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Tue, 7 Mar 2017 16:29:38 +0100 Subject: [PATCH 02/11] Created specialized Vector2 and Vector3 types. --- include/cece/math/Vector.hpp | 1464 +------------------------------ include/cece/math/Vector2.hpp | 1365 ++++++++++++++++++++++++++++ include/cece/math/Vector3.hpp | 1392 +++++++++++++++++++++++++++++ src/math/CMakeLists.txt | 4 +- src/math/Vector2.cpp | 46 + src/math/Vector3.cpp | 46 + unittests/math/CMakeLists.txt | 1 + unittests/math/Vector2_test.cpp | 427 +++++++++ 8 files changed, 3312 insertions(+), 1433 deletions(-) create mode 100644 include/cece/math/Vector2.hpp create mode 100644 include/cece/math/Vector3.hpp create mode 100644 src/math/Vector2.cpp create mode 100644 src/math/Vector3.cpp create mode 100644 unittests/math/Vector2_test.cpp diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index c3537b6..0282e53 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -41,6 +41,8 @@ #include "cece/io/OutStream.hpp" #include "cece/unit/math.hpp" #include "cece/unit/Units.hpp" +#include "cece/math/Vector2.hpp" +#include "cece/math/Vector3.hpp" /* ************************************************************************ */ @@ -474,11 +476,11 @@ class BasicVector /** - * @brief Create from single value. + * @brief Create from single value. * - * @param val + * @param val The value. * - * @return + * @return Vector of vals. */ static BasicVector createSingle(T val) noexcept; @@ -493,1106 +495,41 @@ class BasicVector /* ************************************************************************ */ -/** - * @brief Two dimensional vector. - */ -template -class BasicVector -{ - -// Public Types -public: - - - /// BasicVector value type. - using ValueType = T; - - -// Public Contants -public: - - - /// Number of elements - static constexpr int SIZE = 2; - - -// Public Ctors -public: - - - /** - * @brief Default constructor. - */ - BasicVector() noexcept - : m_x{} - , m_y{} - { - // Nothing to do - } - - - /** - * @brief Constructor. - * - * @param x - * @param y - */ - BasicVector(T x, T y) noexcept - : m_x(x) - , m_y(y) - { - // Nothing to do - } - - - /** - * @brief Zero value constructor. - */ - BasicVector(Zero_t) noexcept - : m_x{} - , m_y{} - { - // Nothing to do - } - - - /** - * @brief Copy constructor. - * - * @param rhs Source vector. - */ - template - explicit BasicVector(const BasicVector& rhs) noexcept - : m_x(static_cast(rhs.getX())) - , m_y(static_cast(rhs.getY())) - { - // Nothing to do - } - - -// Public Operators -public: - - - /** - * @brief Access operator. - * - * @param pos - * - * @return - */ - T& operator[](int pos) noexcept - { - CECE_ASSERT(pos < SIZE); - return (&m_x)[pos]; - } - - - /** - * @brief Access operator. - * - * @param pos - * - * @return - */ - const T& operator[](int pos) const noexcept - { - CECE_ASSERT(pos < SIZE); - return (&m_x)[pos]; - } - - - /** - * @brief Unary plus operator. - * - * @return - */ - BasicVector operator+() const noexcept - { - return *this; - } - - - /** - * @brief Unary minus operator. - * - * @return - */ - BasicVector operator-() const noexcept - { - return BasicVector{-getX(), -getY()}; - } - - - /** - * @brief Addition operator. - * - * @tparam T1 Type of right operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template - BasicVector& operator+=(const BasicVector& rhs) noexcept - { - m_x += rhs.getX(); - m_y += rhs.getY(); - return *this; - } - - - /** - * @brief Subtraction operator. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template - BasicVector& operator-=(const BasicVector& rhs) noexcept - { - m_x -= rhs.getX(); - m_y -= rhs.getY(); - return *this; - } - - - /** - * @brief Multiplication operator. - * - * @tparam T1 Type of right operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template - BasicVector& operator*=(T1 rhs) noexcept - { - m_x *= rhs; - m_y *= rhs; - return *this; - } - - - /** - * @brief Multiplication operator. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template - BasicVector& operator*=(const BasicVector& rhs) noexcept - { - m_x *= rhs.getX(); - m_y *= rhs.getY(); - return *this; - } - - - /** - * @brief Division operator. - * - * @tparam T1 Type of right operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template - BasicVector& operator/=(T1 rhs) noexcept - { - m_x /= rhs; - m_y /= rhs; - return *this; - } - - - /** - * @brief Division operator. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template - BasicVector& operator/=(const BasicVector& rhs) noexcept - { - m_x /= rhs.getX(); - m_y /= rhs.getY(); - return *this; - } - - -// Public Accessors -public: - - - /** - * @brief Returns vector size. - * - * @return - */ - int getSize() const noexcept - { - return SIZE; - } - - - /** - * @brief Returns X coordinate. - * - * @return - */ - T& x() noexcept - { - return m_x; - } - - - /** - * @brief Returns X coordinate. - * - * @return - */ - const T& getX() const noexcept - { - return m_x; - } - - - /** - * @brief Returns Y coordinate. - * - * @return - */ - T& y() noexcept - { - return m_y; - } - - - /** - * @brief Returns Y coordinate. - * - * @return - */ - const T& getY() const noexcept - { - return m_y; - } - - - /** - * @brief Returns width. - * - * @return - */ - T& width() noexcept - { - return m_x; - } - - - /** - * @brief Returns width. - * - * @return - */ - const T& getWidth() const noexcept - { - return m_x; - } - - - /** - * @brief Returns height. - * - * @return - */ - T& height() noexcept - { - return m_y; - } - - - /** - * @brief Returns height. - * - * @return - */ - const T& getHeight() const noexcept - { - return m_y; - } - - -// Public Mutators -public: - - - /** - * @brief Set X coordinate. - * - * @param x - */ - void setX(T x) noexcept - { - m_x = x; - } - - - /** - * @brief Set Y coordinate. - * - * @param y - */ - void setY(T y) noexcept - { - m_y = y; - } - - - /** - * @brief Check if given value is in given range. - * - * @param value Given value. - * @param low Minimum value (>=). - * @param high Maximum value (<). - * - * @return - */ - static bool inRange(T value, T low, T high) noexcept - { - return value >= low && value < high; - } - - - /** - * @brief Check if current vector is in given range. - * - * @param low Minimum coordinates (>=). - * @param high Maximum coordinates (<). - * - * @return - */ - bool inRange(const BasicVector& low, const BasicVector& high) const noexcept - { - return ( - inRange(getX(), low.getX(), high.getX()) && - inRange(getY(), low.getY(), high.getY()) - ); - } - - -// Public Operations -public: - - - /** - * @brief Calculate vector length. - * - * @return - */ - T getLength() const noexcept - { - using std::sqrt; - return static_cast(sqrt(getLengthSquared())); - } - - - /** - * @brief Calculate vector length - squared. - * - * @return - */ - decltype(T{} * T{}) getLengthSquared() const noexcept - { - return dot(*this); - } - - - /** - * @brief Calculate dot of two vectors. - * - * @param rhs Second vector. - * - * @return Dot product. - */ - decltype(T{} * T{}) dot(const BasicVector& rhs) const noexcept - { - return {getX() * rhs.getX() + getY() * rhs.getY()}; - } - - - /** - * @brief Calculate vectors squared distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - decltype(std::declval() * std::declval()) distanceSquared(const BasicVector& rhs) const noexcept - { - return (*this - rhs).getLengthSquared(); - } - - - /** - * @brief Calculate vectors distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - T distance(const BasicVector& rhs) const noexcept - { - return (*this - rhs).getLength(); - } - - - /** - * @brief Inverse current vector (1 / *this). - * - * @return - */ - template - BasicVector inversed() const noexcept - { - return BasicVector{T2(1) / getX(), T2(1) / getY()}; - } - - - /** - * @brief Rotate current vector and return rotated version. - * - * @param angle Rotation angle. - * - * @return - */ - BasicVector rotated(unit::Angle angle) const noexcept - { - return BasicVector( - static_cast(getX() * cos(static_cast(angle)) - getY() * sin(static_cast(angle))), - static_cast(getX() * sin(static_cast(angle)) + getY() * cos(static_cast(angle))) - ); - } - - - /** - * @brief Create from single value. - * - * @param val - * - * @return - */ - static BasicVector createSingle(T val) noexcept - { - return BasicVector{val, val}; - } - - -// Private Data Members -private: - - /// X coordinate. - T m_x{}; - - /// Y coordinate. - T m_y{}; - -}; - -/* ************************************************************************ */ - -/** - * @brief Three dimensional vector. - */ -template -class BasicVector -{ - -// Public Types -public: - - - /// BasicVector value type. - using ValueType = T; - - -// Public Contants -public: - - - /// Number of elements - static constexpr int SIZE = 3; - - -// Public Ctors -public: - - - /** - * @brief Default constructor. - */ - BasicVector() noexcept - : m_x{} - , m_y{} - , m_z{} - { - // Nothing to do - } - - - /** - * @brief Constructor. - * - * @param x - * @param y - * @param z - */ - BasicVector(T x, T y, T z) noexcept - : m_x(x) - , m_y(y) - , m_z(z) - { - // Nothing to do - } - - - /** - * @brief Zero value constructor. - */ - BasicVector(Zero_t) noexcept - : m_x{} - , m_y{} - , m_z{} - { - // Nothing to do - } - - - /** - * @brief Copy constructor. - * - * @param rhs Source vector. - */ - template - explicit BasicVector(const BasicVector& rhs) noexcept - : m_x(static_cast(rhs.getX())) - , m_y(static_cast(rhs.getY())) - , m_z(static_cast(rhs.getZ())) - { - // Nothing to do - } - - -// Public Operators -public: - - - /** - * @brief Access operator. - * - * @param pos - * - * @return - */ - T& operator[](int pos) noexcept - { - CECE_ASSERT(pos < SIZE); - return (&m_x)[pos]; - } - - - /** - * @brief Access operator. - * - * @param pos - * - * @return - */ - const T& operator[](int pos) const noexcept - { - CECE_ASSERT(pos < SIZE); - return (&m_x)[pos]; - } - - - /** - * @brief Unary plus operator. - * - * @return - */ - BasicVector operator+() const noexcept - { - return *this; - } - - - /** - * @brief Unary minus operator. - * - * @return - */ - BasicVector operator-() const noexcept - { - return BasicVector{-getX(), -getY(), -getZ()}; - } - - - /** - * @brief Addition operator. - * - * @tparam T1 Type of right operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template::value>::type* = nullptr> - BasicVector& operator+=(const BasicVector& rhs) noexcept - { - m_x += rhs.getX(); - m_y += rhs.getY(); - m_z += rhs.getZ(); - return *this; - } - - - /** - * @brief Subtraction operator. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template::value>::type* = nullptr> - BasicVector& operator-=(const BasicVector& rhs) noexcept - { - m_x -= rhs.getX(); - m_y -= rhs.getY(); - m_z -= rhs.getZ(); - return *this; - } - - - /** - * @brief Multiplication operator. - * - * @tparam T1 Type of right operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template::value>::type* = nullptr> - BasicVector& operator*=(T1 rhs) noexcept - { - m_x *= rhs; - m_y *= rhs; - m_z *= rhs; - return *this; - } - - - /** - * @brief Multiplication operator. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template::value>::type* = nullptr> - BasicVector& operator*=(const BasicVector& rhs) noexcept - { - m_x *= rhs.getX(); - m_y *= rhs.getY(); - m_z *= rhs.getZ(); - return *this; - } - - - /** - * @brief Division operator. - * - * @tparam T1 Type of right operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template::value>::type* = nullptr> - BasicVector& operator/=(T1 rhs) noexcept - { - m_x /= rhs; - m_y /= rhs; - m_z /= rhs; - return *this; - } - - - /** - * @brief Division operator. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @param rhs Right operand. - * - * @return *this. - */ - template::value>::type* = nullptr> - BasicVector& operator/=(const BasicVector& rhs) noexcept - { - m_x /= rhs.getX(); - m_y /= rhs.getY(); - m_z /= rhs.getZ(); - return *this; - } - - -// Public Accessors -public: - - - /** - * @brief Returns vector size. - * - * @return - */ - int getSize() const noexcept - { - return SIZE; - } - - - /** - * @brief Returns X coordinate. - * - * @return - */ - T& x() noexcept - { - return m_x; - } - - - /** - * @brief Returns X coordinate. - * - * @return - */ - const T& getX() const noexcept - { - return m_x; - } - - - /** - * @brief Returns Y coordinate. - * - * @return - */ - T& y() noexcept - { - return m_y; - } - - - /** - * @brief Returns Y coordinate. - * - * @return - */ - const T& getY() const noexcept - { - return m_y; - } - - - /** - * @brief Returns Z coordinate. - * - * @return - */ - T& z() noexcept - { - return m_z; - } - - - /** - * @brief Returns Z coordinate. - * - * @return - */ - const T& getZ() const noexcept - { - return m_z; - } - - - /** - * @brief Returns width. - * - * @return - */ - T& width() noexcept - { - return m_x; - } - - - /** - * @brief Returns width. - * - * @return - */ - const T& getWidth() const noexcept - { - return m_x; - } - - - /** - * @brief Returns height. - * - * @return - */ - T& height() noexcept - { - return m_y; - } - - - /** - * @brief Returns height. - * - * @return - */ - const T& getHeight() const noexcept - { - return m_y; - } - - - /** - * @brief Returns depth. - * - * @return - */ - T& depth() noexcept - { - return m_z; - } - - - /** - * @brief Returns depth. - * - * @return - */ - const T& getDepth() const noexcept - { - return m_z; - } - - - /** - * @brief Check if given value is in given range. - * - * @param value Given value. - * @param low Minimum value (>=). - * @param high Maximum value (<). - * - * @return - */ - static bool inRange(T value, T low, T high) noexcept - { - return value >= low && value < high; - } - - - /** - * @brief Check if current vector is in given range. - * - * @param low Minimum coordinates (>=). - * @param high Maximum coordinates (<). - * - * @return - */ - bool inRange(const BasicVector& low, const BasicVector& high) const noexcept - { - return ( - inRange(getX(), low.getX(), high.getX()) && - inRange(getY(), low.getY(), high.getY()) && - inRange(getZ(), low.getZ(), high.getZ()) - ); - } - - - -// Public Mutators -public: - - - /** - * @brief Set X coordinate. - * - * @param x - */ - void setX(T x) noexcept - { - m_x = x; - } - - - /** - * @brief Set Y coordinate. - * - * @param y - */ - void setY(T y) noexcept - { - m_y = y; - } - - - /** - * @brief Set Z coordinate. - * - * @param z - */ - void setZ(T z) noexcept - { - m_z = z; - } - - -// Public Operations -public: - - - /** - * @brief Calculate vector length. - * - * @return - */ - template::value>::type* = nullptr> - T getLength() const noexcept - { - using std::sqrt; - return static_cast(sqrt(getLengthSquared())); - } - - - /** - * @brief Calculate vector length - squared. - * - * @return - */ - decltype(T{} * T{}) getLengthSquared() const noexcept - { - return dot(*this); - } - - - /** - * @brief Calculate dot of two vectors. - * - * @param rhs Second vector. - * - * @return Dot product. - */ - decltype(T{} * T{}) dot(const BasicVector& rhs) const noexcept - { - return { - getX() * rhs.getX() + - getY() * rhs.getY() + - getZ() * rhs.getZ() - }; - } - - - /** - * @brief Calculate vectors squared distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - decltype(std::declval() * std::declval()) distanceSquared(const BasicVector& rhs) const noexcept - { - return (*this - rhs).getLengthSquared(); - } - - - /** - * @brief Calculate vectors distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - T distance(const BasicVector& rhs) const noexcept - { - return (*this - rhs).getLength(); - } - - - /** - * @brief Inverse current vector (1 / *this). - * - * @return - */ - template - BasicVector inversed() const noexcept - { - return BasicVector{ - T2(1) / getX(), - T2(1) / getY(), - T2(1) / getZ() - }; - } - +// TODO: rework +template +struct BasicVector : public BasicVector2 +{ + using BasicVector2::BasicVector2; - /** - * @brief Create from single value. - * - * @param val - * - * @return - */ - static BasicVector createSingle(T val) noexcept + BasicVector() {}; + BasicVector(const BasicVector2& src) + : BasicVector2(src) { - return {val, val, val}; + // } + const T& getWidth() const noexcept { return BasicVector2::getX(); } + const T& getHeight() const noexcept { return BasicVector2::getY(); } +}; -// Private Data Members -private: - - /// X coordinate. - T m_x{}; +/* ************************************************************************ */ - /// Y coordinate. - T m_y{}; +// TODO: rework +template +struct BasicVector : public BasicVector3 +{ + using BasicVector3::BasicVector3; - /// Z coordinate. - T m_z{}; + BasicVector() {}; + BasicVector(const BasicVector3& src) + : BasicVector3(src) + { + // + } + const T& getWidth() const noexcept { return BasicVector3::getX(); } + const T& getHeight() const noexcept { return BasicVector3::getY(); } + const T& getDepth() const noexcept { return BasicVector3::getZ(); } }; /* ************************************************************************ */ @@ -1679,28 +616,6 @@ inline BasicVector operator+(const BasicVector& /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator+(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs.getX() + rhs.getX(), - lhs.getY() + rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Addition operator. * @@ -1726,28 +641,6 @@ inline BasicVector operator+(const BasicVector& /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator+(const BasicVector& lhs, T2 rhs) noexcept -{ - return BasicVector{ - lhs.getX() + rhs, - lhs.getY() + rhs - }; -} - -/* ************************************************************************ */ - /** * @brief Addition operator. * @@ -1773,28 +666,6 @@ inline BasicVector operator+(T1 lhs, const BasicVector /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator+(T1 lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs + rhs.getX(), - lhs + rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Substract operator. * @@ -1819,28 +690,6 @@ inline BasicVector operator-(const BasicVector& /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator-(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs.getX() - rhs.getX(), - lhs.getY() - rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Substract operator. * @@ -1865,28 +714,6 @@ inline BasicVector operator-(const BasicVector& /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator-(const BasicVector& lhs, T2 rhs) noexcept -{ - return BasicVector{ - lhs.getX() - rhs, - lhs.getY() - rhs - }; -} - -/* ************************************************************************ */ - /** * @brief Substract operator. * @@ -1911,28 +738,6 @@ inline BasicVector operator-(T1 lhs, const BasicVector /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator-(T1 lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs - rhs.getX(), - lhs - rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -1957,28 +762,6 @@ inline BasicVector operator*(const BasicVector& /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator*(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs.getX() * rhs.getX(), - lhs.getY() * rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -2003,28 +786,6 @@ inline BasicVector operator*(const BasicVector& /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator*(const BasicVector& lhs, T2 rhs) noexcept -{ - return BasicVector{ - lhs.getX() * rhs, - lhs.getY() * rhs - }; -} - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -2049,28 +810,6 @@ inline BasicVector operator*(T1 lhs, const BasicVector /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator*(T1 lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs * rhs.getX(), - lhs * rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Division operator. * @@ -2095,28 +834,6 @@ inline BasicVector operator/(const BasicVector& /* ************************************************************************ */ -/** - * @brief Division operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator/(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs.getX() / rhs.getX(), - lhs.getY() / rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Division operator. * @@ -2141,28 +858,6 @@ inline BasicVector operator/(const BasicVector& /* ************************************************************************ */ -/** - * @brief Division operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator/(const BasicVector& lhs, T2 rhs) noexcept -{ - return BasicVector{ - lhs.getX() / rhs, - lhs.getY() / rhs - }; -} - -/* ************************************************************************ */ - /** * @brief Division operator. * @@ -2187,28 +882,6 @@ inline BasicVector operator/(T1 lhs, const BasicVector /* ************************************************************************ */ -/** - * @brief Division operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator/(T1 lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{ - lhs / rhs.getX(), - lhs / rhs.getY() - }; -} - -/* ************************************************************************ */ - /** * @brief Compare vectors. * @@ -2230,25 +903,6 @@ inline bool operator==(const BasicVector& lhs, const BasicVector& /* ************************************************************************ */ -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator==(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return - lhs.getX() == rhs.getX() && - lhs.getY() == rhs.getY() - ; -} - -/* ************************************************************************ */ - /** * @brief Compare vectors. * @@ -2550,60 +1204,6 @@ inline decltype(T1{} * T2{}) dot(const BasicVector& lhs, const BasicVecto /* ************************************************************************ */ -/** - * @brief Calculate cross product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Cross product. - */ -template -inline -decltype(std::declval() * std::declval()) -cross(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return {lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX()}; -} - -/* ************************************************************************ */ - -/** - * @brief Calculate cross product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Cross product. - */ -template -inline -BasicVector() * std::declval()), 2> -cross(const BasicVector& lhs, const T2& rhs) noexcept -{ - return {rhs * lhs.getY(), -rhs * lhs.getX()}; -} - -/* ************************************************************************ */ - -/** - * @brief Calculate cross product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Cross product. - */ -template -inline -BasicVector() * std::declval()), 2> -cross(const T1& lhs, const BasicVector& rhs) noexcept -{ - return {-lhs * rhs.getY(), lhs * rhs.getX()}; -} - -/* ************************************************************************ */ - /** * @brief Input stream operator. * diff --git a/include/cece/math/Vector2.hpp b/include/cece/math/Vector2.hpp new file mode 100644 index 0000000..679992c --- /dev/null +++ b/include/cece/math/Vector2.hpp @@ -0,0 +1,1365 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +#pragma once + +/* ************************************************************************ */ + +// C++ +#include +#include + +// CeCe +#include "cece/common.hpp" +#include "cece/Assert.hpp" +#include "cece/math/Zero.hpp" +#include "cece/unit/math.hpp" +#include "cece/unit/Units.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +/** + * @brief Two dimensional vector. + * + * @tparam T Element type. + */ +template +class BasicVector2 +{ + + +// Public Types +public: + + + /// BasicVector2 value type. + using ValueType = T; + + /// Element type squared. + using ValueTypeSq = decltype(std::declval() * std::declval()); + + +// Public Ctors +public: + + + /** + * @brief Default constructor. + */ + BasicVector2() noexcept; + + + /** + * @brief Constructor. + * + * @param x The X coordinate. + * @param y The Y coordinate. + */ + BasicVector2(T x, T y) noexcept; + + + /** + * @brief Zero value constructor. + * + * @param[in] zero The zero value. + */ + BasicVector2(Zero_t zero) noexcept; + + + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + */ + BasicVector2(const BasicVector2& src) noexcept; + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + */ + BasicVector2(BasicVector2&& src) noexcept; + + + /** + * @brief Copy constructor. + * + * @param rhs Source vector. + * + * @tparam T2 The source vector element type. + */ + template::value>::type* = nullptr> + BasicVector2(const BasicVector2& rhs) noexcept; + + +// Public Operators +public: + + + /** + * @brief Copy constructor. + * + * @param[in] zero The zero value. + * + * @return *this. + */ + BasicVector2& operator=(Zero_t zero) noexcept; + + + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + BasicVector2& operator=(const BasicVector2& src) noexcept; + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + BasicVector2& operator=(BasicVector2&& src) noexcept; + + + /** + * @brief Copy constructor. + * + * @param v The source vector. + * + * @tparam T2 The source vector element type. + * + * @return *this. + */ + template::value>::type* = nullptr> + BasicVector2& operator=(const BasicVector2& src) noexcept; + + + /** + * @brief Unary plus operator. + * + * @return Vector. + */ + BasicVector2 operator+() const noexcept; + + + /** + * @brief Unary minus operator. + * + * @return Vector. + */ + BasicVector2 operator-() const noexcept; + + + /** + * @brief Addition operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template() + std::declval()), + T + >::value>::type* = nullptr> + BasicVector2& operator+=(const BasicVector2& rhs) noexcept; + + + /** + * @brief Subtraction operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector2 operand. + * + * @return *this. + */ + template() - std::declval()), + T + >::value>::type* = nullptr> + BasicVector2& operator-=(const BasicVector2& rhs) noexcept; + + + /** + * @brief Multiplication operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template() * std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector2& operator*=(T1 rhs) noexcept; + + + /** + * @brief Multiplication operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector2 operand. + * + * @return *this. + */ + template() * std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector2& operator*=(const BasicVector2& rhs) noexcept; + + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template() / std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector2& operator/=(T1 rhs) noexcept; + + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector2 operand. + * + * @return *this. + */ + template() / std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector2& operator/=(const BasicVector2& rhs) noexcept; + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + T& operator[](int pos) noexcept; + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + const T& operator[](int pos) const noexcept; + + +// Public Accessors +public: + + + /** + * @brief Returns X coordinate. + * + * @return Reference to X coordinate. + */ + T& x() noexcept; + + + /** + * @brief Returns X coordinate. + * + * @return The X coordinate. + */ + const T& getX() const noexcept; + + + /** + * @brief Set X coordinate. + * + * @param x The X coordinate. + */ + void setX(T x) noexcept; + + + /** + * @brief Returns Y coordinate. + * + * @return Referent co Y coordinate. + */ + T& y() noexcept; + + + /** + * @brief Returns Y coordinate. + * + * @return The Y coordinate. + */ + const T& getY() const noexcept; + + + /** + * @brief Set Y coordinate. + * + * @param y The Y coordinate. + */ + void setY(T y) noexcept; + + + /** + * @brief Check if given value is in given range. + * + * @param value Given value. + * @param low Minimum value (>=). + * @param high Maximum value (<). + * + * @return If given value is in given range. + */ + static bool inRange(T value, T low, T high) noexcept; + + + /** + * @brief Check if current vector is in given range. + * + * @param low Minimum coordinates (>=). + * @param high Maximum coordinates (<). + * + * @return If current value is in given range. + */ + bool inRange(const BasicVector2& low, const BasicVector2& high) const noexcept; + + + /** + * @brief Check if current vector is in given range where the low range + * is Zero vector. + * + * @param high Maximum coordinates (<). + * + * @return If current value is in given range. + */ + bool inRange(const BasicVector2& high) const noexcept; + + +// Public Operations +public: + + + /** + * @brief Calculate vector length. + * + * @return The length. + */ + ValueType getLength() const noexcept; + + + /** + * @brief Calculate vector length - squared. + * + * @return The length squared. + */ + ValueTypeSq getLengthSquared() const noexcept; + + + /** + * @brief Calculate dot of two vectors. + * + * @param rhs Second vector. + * + * @return Dot product. + */ + ValueTypeSq dot(const BasicVector2& rhs) const noexcept; + + + /** + * @brief Calculate vectors squared distance. + * + * @param rhs Second vector. + * + * @return Distance. + */ + ValueTypeSq distanceSquared(const BasicVector2& rhs) const noexcept; + + + /** + * @brief Calculate vectors distance. + * + * @param rhs Second vector. + * + * @return Distance. + */ + ValueType distance(const BasicVector2& rhs) const noexcept; + + + /** + * @brief Inverse current vector (1 / *this). + * + * @tparam T2 Type of result vector's element. + * + * @return Inversed vector. + */ + template + BasicVector2 inversed() const noexcept; + + + /** + * @brief Rotate current vector and return rotated version. + * + * @param angle Rotation angle. + * + * @return Rotated vector. + */ + BasicVector2 rotated(unit::Angle angle) const noexcept; + + + /** + * @brief Create from single value. + * + * @param val The value + * + * @return Vector of {val, val}. + */ + static BasicVector2 createSingle(T val) noexcept; + + +// Private Data Members +private: + + /// X coordinate. + T m_x; + + /// Y coordinate. + T m_y; + +}; + +/* ************************************************************************ */ + +extern template class BasicVector2; +extern template class BasicVector2; +extern template class BasicVector2; +extern template class BasicVector2; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() + std::declval())> +operator+(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector2() + std::declval())> +operator+(const BasicVector2& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() + std::declval())> +operator+(T1 lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() - std::declval())> +operator-(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector2() - std::declval())> +operator-(const BasicVector2& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() - std::declval())> +operator-(T1 lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() * std::declval())> +operator*(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector2() * std::declval())> +operator*(const BasicVector2& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() * std::declval())> +operator*(T1 lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() / std::declval())> +operator/(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector2. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector2() / std::declval())> +operator/(const BasicVector2& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector2. + * + * @return Result vector. + */ +template +inline BasicVector2() / std::declval())> +operator/(T1 lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Comparision result. + */ +template +inline bool operator==(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Calculate cross product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Cross product. + */ +template +inline +decltype(std::declval() * std::declval()) +cross(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Calculate cross product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Cross product. + */ +template +inline +BasicVector2() * std::declval())> +cross(const BasicVector2& lhs, const T2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Calculate cross product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Cross product. + */ +template +inline +BasicVector2() * std::declval())> +cross(const T1& lhs, const BasicVector2& rhs) noexcept; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template +inline BasicVector2::BasicVector2() noexcept + : m_x{} + , m_y{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector2::BasicVector2(T x, T y) noexcept + : m_x(x) + , m_y(y) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector2::BasicVector2(Zero_t zero) noexcept + : m_x{} + , m_y{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector2::BasicVector2(const BasicVector2& src) noexcept + : m_x{src.getX()} + , m_y{src.getY()} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector2::BasicVector2(BasicVector2&& src) noexcept + : m_x{std::move(src.m_x)} + , m_y{std::move(src.m_y)} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline BasicVector2::BasicVector2(const BasicVector2& rhs) noexcept + : m_x(rhs.getX()) + , m_y(rhs.getY()) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector2& BasicVector2::operator=(Zero_t zero) noexcept +{ + m_x = T{}; + m_y = T{}; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector2& BasicVector2::operator=(const BasicVector2& src) noexcept +{ + m_x = src.m_x; + m_y = src.m_y; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector2& BasicVector2::operator=(BasicVector2&& src) noexcept +{ + m_x = std::move(src.m_x); + m_y = std::move(src.m_y); + + return *this; +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline BasicVector2& BasicVector2::operator=(const BasicVector2& src) noexcept +{ + m_x = T(src.getX()); + m_y = T(src.getY()); + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector2 BasicVector2::operator+() const noexcept +{ + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector2 BasicVector2::operator-() const noexcept +{ + return {-m_x, -m_y}; +} + +/* ************************************************************************ */ + +template +template() + std::declval()), + T +>::value>::type*> +inline BasicVector2& BasicVector2::operator+=(const BasicVector2& rhs) noexcept +{ + m_x += rhs.getX(); + m_y += rhs.getY(); + + return *this; +} + +/* ************************************************************************ */ + +template +template() - std::declval()), + T +>::value>::type*> +inline BasicVector2& BasicVector2::operator-=(const BasicVector2& rhs) noexcept +{ + m_x -= rhs.getX(); + m_y -= rhs.getY(); + + return *this; +} + +/* ************************************************************************ */ + +template +template() * std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector2& BasicVector2::operator*=(T1 rhs) noexcept +{ + m_x *= rhs; + m_y *= rhs; + + return *this; +} + +/* ************************************************************************ */ + +template +template() * std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector2& BasicVector2::operator*=(const BasicVector2& rhs) noexcept +{ + m_x *= rhs.getX(); + m_y *= rhs.getY(); + + return *this; +} + +/* ************************************************************************ */ + +template +template() / std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector2& BasicVector2::operator/=(T1 rhs) noexcept +{ + m_x /= rhs; + m_y /= rhs; + + return *this; +} + +/* ************************************************************************ */ + +template +template() / std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector2& BasicVector2::operator/=(const BasicVector2& rhs) noexcept +{ + m_x /= rhs.getX(); + m_y /= rhs.getY(); + + return *this; +} + +/* ************************************************************************ */ + +template +inline T& BasicVector2::operator[](int pos) noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < 2); + return (&m_x)[pos]; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector2::operator[](int pos) const noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < 2); + return (&m_x)[pos]; +} + +/* ************************************************************************ */ + +template +inline T& BasicVector2::x() noexcept +{ + return m_x; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector2::getX() const noexcept +{ + return m_x; +} + +/* ************************************************************************ */ + +template +inline void BasicVector2::setX(T x) noexcept +{ + m_x = std::move(x); +} + +/* ************************************************************************ */ + +template +inline T& BasicVector2::y() noexcept +{ + return m_y; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector2::getY() const noexcept +{ + return m_y; +} + +/* ************************************************************************ */ + +template +inline void BasicVector2::setY(T y) noexcept +{ + m_y = std::move(y); +} + +/* ************************************************************************ */ + +template +inline bool BasicVector2::inRange(T value, T low, T high) noexcept +{ + return value >= low && value < high; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector2::inRange(const BasicVector2& low, const BasicVector2& high) const noexcept +{ + bool res = true; + + res = res && inRange(getX(), low.getX(), high.getX()); + res = res && inRange(getY(), low.getY(), high.getY()); + + return res; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector2::inRange(const BasicVector2& high) const noexcept +{ + return inRange(Zero, high); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector2::ValueType BasicVector2::getLength() const noexcept +{ + using std::sqrt; + return static_cast(sqrt(getLengthSquared())); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector2::ValueTypeSq BasicVector2::getLengthSquared() const noexcept +{ + return dot(*this); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector2::ValueTypeSq BasicVector2::dot(const BasicVector2& rhs) const noexcept +{ + return getX() * rhs.getX() + getY() * rhs.getY(); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector2::ValueTypeSq BasicVector2::distanceSquared(const BasicVector2& rhs) const noexcept +{ + return (*this - rhs).getLengthSquared(); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector2::ValueType BasicVector2::distance(const BasicVector2& rhs) const noexcept +{ + return (*this - rhs).getLength(); +} + +/* ************************************************************************ */ + +template +template +inline BasicVector2 BasicVector2::inversed() const noexcept +{ + return {T2(1) / getX(), T2(1) / getY()}; +} + +/* ************************************************************************ */ + +template +inline BasicVector2 BasicVector2::rotated(unit::Angle angle) const noexcept +{ + return { + static_cast(getX() * cos(static_cast(angle)) - getY() * sin(static_cast(angle))), + static_cast(getX() * sin(static_cast(angle)) + getY() * cos(static_cast(angle))) + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2 BasicVector2::createSingle(T val) noexcept +{ + return {val, val}; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() + std::declval())> +operator+(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs.getX() + rhs.getX(), + lhs.getY() + rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() + std::declval())> +operator+(const BasicVector2& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() + rhs, + lhs.getY() + rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() + std::declval())> +operator+(T1 lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs + rhs.getX(), + lhs + rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() - std::declval())> +operator-(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs.getX() - rhs.getX(), + lhs.getY() - rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() - std::declval())> +operator-(const BasicVector2& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() - rhs, + lhs.getY() - rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() - std::declval())> +operator-(T1 lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs - rhs.getX(), + lhs - rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() * std::declval())> +operator*(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs.getX() * rhs.getX(), + lhs.getY() * rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() * std::declval())> +operator*(const BasicVector2& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() * rhs, + lhs.getY() * rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() * std::declval())> +operator*(T1 lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs * rhs.getX(), + lhs * rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() / std::declval())> +operator/(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs.getX() / rhs.getX(), + lhs.getY() / rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() / std::declval())> +operator/(const BasicVector2& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() / rhs, + lhs.getY() / rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector2() / std::declval())> +operator/(T1 lhs, const BasicVector2& rhs) noexcept +{ + return { + lhs / rhs.getX(), + lhs / rhs.getY() + }; +} + +/* ************************************************************************ */ + +template +inline bool operator==(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +{ + return + lhs.getX() == rhs.getX() && + lhs.getY() == rhs.getY() + ; +} + +/* ************************************************************************ */ + +template +inline +decltype(std::declval() * std::declval()) +cross(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +{ + return {lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX()}; +} + +/* ************************************************************************ */ + +template +inline +BasicVector2() * std::declval())> +cross(const BasicVector2& lhs, const T2& rhs) noexcept +{ + return {rhs * lhs.getY(), -rhs * lhs.getX()}; +} + +/* ************************************************************************ */ + +template +inline +BasicVector2() * std::declval())> +cross(const T1& lhs, const BasicVector2& rhs) noexcept +{ + return {-lhs * rhs.getY(), lhs * rhs.getX()}; +} + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ diff --git a/include/cece/math/Vector3.hpp b/include/cece/math/Vector3.hpp new file mode 100644 index 0000000..54ca338 --- /dev/null +++ b/include/cece/math/Vector3.hpp @@ -0,0 +1,1392 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +#pragma once + +/* ************************************************************************ */ + +// C++ +#include +#include + +// CeCe +#include "cece/common.hpp" +#include "cece/Assert.hpp" +#include "cece/math/Zero.hpp" +#include "cece/unit/math.hpp" +#include "cece/unit/Units.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +/** + * @brief Three dimensional vector. + * + * @tparam T Element type. + */ +template +class BasicVector3 +{ + + +// Public Types +public: + + + /// BasicVector3 value type. + using ValueType = T; + + /// Element type squared. + using ValueTypeSq = decltype(std::declval() * std::declval()); + + +// Public Ctors +public: + + + /** + * @brief Default constructor. + */ + BasicVector3() noexcept; + + + /** + * @brief Constructor. + * + * @param x The X coordinate. + * @param y The Y coordinate. + * @param y The Z coordinate. + */ + BasicVector3(T x, T y, T z) noexcept; + + + /** + * @brief Zero value constructor. + * + * @param[in] zero The zero value. + */ + BasicVector3(Zero_t zero) noexcept; + + + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + */ + BasicVector3(const BasicVector3& src) noexcept; + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + */ + BasicVector3(BasicVector3&& src) noexcept; + + + /** + * @brief Copy constructor. + * + * @param rhs Source vector. + * + * @tparam T2 The source vector element type. + */ + template::value>::type* = nullptr> + BasicVector3(const BasicVector3& rhs) noexcept; + + +// Public Operators +public: + + + /** + * @brief Copy constructor. + * + * @param[in] zero The zero value. + * + * @return *this. + */ + BasicVector3& operator=(Zero_t zero) noexcept; + + + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + BasicVector3& operator=(const BasicVector3& src) noexcept; + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + BasicVector3& operator=(BasicVector3&& src) noexcept; + + + /** + * @brief Copy constructor. + * + * @param v The source vector. + * + * @tparam T2 The source vector element type. + * + * @return *this. + */ + template::value>::type* = nullptr> + BasicVector3& operator=(const BasicVector3& src) noexcept; + + + /** + * @brief Unary plus operator. + * + * @return Vector. + */ + BasicVector3 operator+() const noexcept; + + + /** + * @brief Unary minus operator. + * + * @return Vector. + */ + BasicVector3 operator-() const noexcept; + + + /** + * @brief Addition operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template() + std::declval()), + T + >::value>::type* = nullptr> + BasicVector3& operator+=(const BasicVector3& rhs) noexcept; + + + /** + * @brief Subtraction operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector3 operand. + * + * @return *this. + */ + template() - std::declval()), + T + >::value>::type* = nullptr> + BasicVector3& operator-=(const BasicVector3& rhs) noexcept; + + + /** + * @brief Multiplication operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template() * std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector3& operator*=(T1 rhs) noexcept; + + + /** + * @brief Multiplication operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector3 operand. + * + * @return *this. + */ + template() * std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector3& operator*=(const BasicVector3& rhs) noexcept; + + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template() / std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector3& operator/=(T1 rhs) noexcept; + + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 Type of value in BasicVector3 operand. + * + * @return *this. + */ + template() / std::declval()), + T + >::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) + >::value>::type* = nullptr> + BasicVector3& operator/=(const BasicVector3& rhs) noexcept; + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + T& operator[](int pos) noexcept; + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + const T& operator[](int pos) const noexcept; + + +// Public Accessors +public: + + + /** + * @brief Returns X coordinate. + * + * @return Reference to X coordinate. + */ + T& x() noexcept; + + + /** + * @brief Returns X coordinate. + * + * @return The X coordinate. + */ + const T& getX() const noexcept; + + + /** + * @brief Set X coordinate. + * + * @param x The X coordinate. + */ + void setX(T x) noexcept; + + + /** + * @brief Returns Y coordinate. + * + * @return Referent co Y coordinate. + */ + T& y() noexcept; + + + /** + * @brief Returns Y coordinate. + * + * @return The Y coordinate. + */ + const T& getY() const noexcept; + + + /** + * @brief Set Y coordinate. + * + * @param y The Y coordinate. + */ + void setY(T y) noexcept; + + + /** + * @brief Returns Z coordinate. + * + * @return Referent co Z coordinate. + */ + T& z() noexcept; + + + /** + * @brief Returns Z coordinate. + * + * @return The Z coordinate. + */ + const T& getZ() const noexcept; + + + /** + * @brief Set Z coordinate. + * + * @param z The Z coordinate. + */ + void setZ(T z) noexcept; + + + /** + * @brief Check if given value is in given range. + * + * @param value Given value. + * @param low Minimum value (>=). + * @param high Maximum value (<). + * + * @return If given value is in given range. + */ + static bool inRange(T value, T low, T high) noexcept; + + + /** + * @brief Check if current vector is in given range. + * + * @param low Minimum coordinates (>=). + * @param high Maximum coordinates (<). + * + * @return If current value is in given range. + */ + bool inRange(const BasicVector3& low, const BasicVector3& high) const noexcept; + + + /** + * @brief Check if current vector is in given range where the low range + * is Zero vector. + * + * @param high Maximum coordinates (<). + * + * @return If current value is in given range. + */ + bool inRange(const BasicVector3& high) const noexcept; + + +// Public Operations +public: + + + /** + * @brief Calculate vector length. + * + * @return The length. + */ + ValueType getLength() const noexcept; + + + /** + * @brief Calculate vector length - squared. + * + * @return The length squared. + */ + ValueTypeSq getLengthSquared() const noexcept; + + + /** + * @brief Calculate dot of two vectors. + * + * @param rhs Second vector. + * + * @return Dot product. + */ + ValueTypeSq dot(const BasicVector3& rhs) const noexcept; + + + /** + * @brief Calculate vectors squared distance. + * + * @param rhs Second vector. + * + * @return Distance. + */ + ValueTypeSq distanceSquared(const BasicVector3& rhs) const noexcept; + + + /** + * @brief Calculate vectors distance. + * + * @param rhs Second vector. + * + * @return Distance. + */ + ValueType distance(const BasicVector3& rhs) const noexcept; + + + /** + * @brief Inverse current vector (1 / *this). + * + * @tparam T2 Type of result vector's element. + * + * @return Inversed vector. + */ + template + BasicVector3 inversed() const noexcept; + + + /** + * @brief Rotate current vector and return rotated version. + * + * @param angle Rotation angle. + * + * @return Rotated vector. + */ + BasicVector3 rotated(unit::Angle angle) const noexcept; + + + /** + * @brief Create from single value. + * + * @param val The value + * + * @return Vector of {val, val}. + */ + static BasicVector3 createSingle(T val) noexcept; + + +// Private Data Members +private: + + /// X coordinate. + T m_x; + + /// Y coordinate. + T m_y; + + /// Z coordinate. + T m_z; + +}; + +/* ************************************************************************ */ + +extern template class BasicVector3; +extern template class BasicVector3; +extern template class BasicVector3; +extern template class BasicVector3; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() + std::declval())> +operator+(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector3() + std::declval())> +operator+(const BasicVector3& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() + std::declval())> +operator+(T1 lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() - std::declval())> +operator-(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector3() - std::declval())> +operator-(const BasicVector3& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() - std::declval())> +operator-(T1 lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() * std::declval())> +operator*(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector3() * std::declval())> +operator*(const BasicVector3& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() * std::declval())> +operator*(T1 lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() / std::declval())> +operator/(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first BasicVector3. + * @tparam T2 Type of second operand. + * + * @return Result vector. + */ +template +inline BasicVector3() / std::declval())> +operator/(const BasicVector3& lhs, T2 rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of first operand. + * @tparam T2 Type of value in second BasicVector3. + * + * @return Result vector. + */ +template +inline BasicVector3() / std::declval())> +operator/(T1 lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Comparision result. + */ +template +inline bool operator==(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Calculate cross product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Cross product. + */ +template +inline +BasicVector3() * std::declval())> +cross(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template +inline BasicVector3::BasicVector3() noexcept + : m_x{} + , m_y{} + , m_z{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector3::BasicVector3(T x, T y, T z) noexcept + : m_x(x) + , m_y(y) + , m_z(y) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector3::BasicVector3(Zero_t zero) noexcept + : m_x{} + , m_y{} + , m_z{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector3::BasicVector3(const BasicVector3& src) noexcept + : m_x{src.getX()} + , m_y{src.getY()} + , m_z{src.getZ()} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector3::BasicVector3(BasicVector3&& src) noexcept + : m_x{std::move(src.m_x)} + , m_y{std::move(src.m_y)} + , m_z{std::move(src.m_z)} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline BasicVector3::BasicVector3(const BasicVector3& rhs) noexcept + : m_x(rhs.getX()) + , m_y(rhs.getY()) + , m_z(rhs.getZ()) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline BasicVector3& BasicVector3::operator=(Zero_t zero) noexcept +{ + m_x = T{}; + m_y = T{}; + m_z = T{}; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector3& BasicVector3::operator=(const BasicVector3& src) noexcept +{ + m_x = src.m_x; + m_y = src.m_y; + m_z = src.m_z; + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector3& BasicVector3::operator=(BasicVector3&& src) noexcept +{ + m_x = std::move(src.m_x); + m_y = std::move(src.m_y); + m_z = std::move(src.m_z); + + return *this; +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline BasicVector3& BasicVector3::operator=(const BasicVector3& src) noexcept +{ + m_x = T(src.getX()); + m_y = T(src.getY()); + m_z = T(src.getZ()); + + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector3 BasicVector3::operator+() const noexcept +{ + return *this; +} + +/* ************************************************************************ */ + +template +inline BasicVector3 BasicVector3::operator-() const noexcept +{ + return {-m_x, -m_y, -m_z}; +} + +/* ************************************************************************ */ + +template +template() + std::declval()), + T +>::value>::type*> +inline BasicVector3& BasicVector3::operator+=(const BasicVector3& rhs) noexcept +{ + m_x += rhs.getX(); + m_y += rhs.getY(); + m_z += rhs.getZ(); + + return *this; +} + +/* ************************************************************************ */ + +template +template() - std::declval()), + T +>::value>::type*> +inline BasicVector3& BasicVector3::operator-=(const BasicVector3& rhs) noexcept +{ + m_x -= rhs.getX(); + m_y -= rhs.getY(); + m_z -= rhs.getZ(); + + return *this; +} + +/* ************************************************************************ */ + +template +template() * std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector3& BasicVector3::operator*=(T1 rhs) noexcept +{ + m_x *= rhs; + m_y *= rhs; + m_z *= rhs; + + return *this; +} + +/* ************************************************************************ */ + +template +template() * std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector3& BasicVector3::operator*=(const BasicVector3& rhs) noexcept +{ + m_x *= rhs.getX(); + m_y *= rhs.getY(); + m_z *= rhs.getZ(); + + return *this; +} + +/* ************************************************************************ */ + +template +template() / std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector3& BasicVector3::operator/=(T1 rhs) noexcept +{ + m_x /= rhs; + m_y /= rhs; + m_z /= rhs; + + return *this; +} + +/* ************************************************************************ */ + +template +template() / std::declval()), + T +>::value || std::is_constructible< + T, + decltype(std::declval() * std::declval()) +>::value>::type*> +inline BasicVector3& BasicVector3::operator/=(const BasicVector3& rhs) noexcept +{ + m_x /= rhs.getX(); + m_y /= rhs.getY(); + m_z /= rhs.getZ(); + + return *this; +} + +/* ************************************************************************ */ + +template +inline T& BasicVector3::operator[](int pos) noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < 3); + return (&m_x)[pos]; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector3::operator[](int pos) const noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < 3); + return (&m_x)[pos]; +} + +/* ************************************************************************ */ + +template +inline T& BasicVector3::x() noexcept +{ + return m_x; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector3::getX() const noexcept +{ + return m_x; +} + +/* ************************************************************************ */ + +template +inline void BasicVector3::setX(T x) noexcept +{ + m_x = std::move(x); +} + +/* ************************************************************************ */ + +template +inline T& BasicVector3::y() noexcept +{ + return m_y; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector3::getY() const noexcept +{ + return m_y; +} + +/* ************************************************************************ */ + +template +inline void BasicVector3::setY(T y) noexcept +{ + m_y = std::move(y); +} + +/* ************************************************************************ */ + +template +inline T& BasicVector3::z() noexcept +{ + return m_z; +} + +/* ************************************************************************ */ + +template +inline const T& BasicVector3::getZ() const noexcept +{ + return m_z; +} + +/* ************************************************************************ */ + +template +inline void BasicVector3::setZ(T z) noexcept +{ + m_z = std::move(z); +} + +/* ************************************************************************ */ + +template +inline bool BasicVector3::inRange(T value, T low, T high) noexcept +{ + return value >= low && value < high; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector3::inRange(const BasicVector3& low, const BasicVector3& high) const noexcept +{ + bool res = true; + + res = res && inRange(getX(), low.getX(), high.getX()); + res = res && inRange(getY(), low.getY(), high.getY()); + res = res && inRange(getZ(), low.getZ(), high.getZ()); + + return res; +} + +/* ************************************************************************ */ + +template +inline bool BasicVector3::inRange(const BasicVector3& high) const noexcept +{ + return inRange(Zero, high); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector3::ValueType BasicVector3::getLength() const noexcept +{ + using std::sqrt; + return static_cast(sqrt(getLengthSquared())); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector3::ValueTypeSq BasicVector3::getLengthSquared() const noexcept +{ + return dot(*this); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector3::ValueTypeSq BasicVector3::dot(const BasicVector3& rhs) const noexcept +{ + return + getX() * rhs.getX() + + getY() * rhs.getY() + + getZ() * rhs.getZ() + ; +} + +/* ************************************************************************ */ + +template +inline typename BasicVector3::ValueTypeSq BasicVector3::distanceSquared(const BasicVector3& rhs) const noexcept +{ + return (*this - rhs).getLengthSquared(); +} + +/* ************************************************************************ */ + +template +inline typename BasicVector3::ValueType BasicVector3::distance(const BasicVector3& rhs) const noexcept +{ + return (*this - rhs).getLength(); +} + +/* ************************************************************************ */ + +template +template +inline BasicVector3 BasicVector3::inversed() const noexcept +{ + return { + T2(1) / getX(), + T2(1) / getY(), + T2(1) / getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3 BasicVector3::createSingle(T val) noexcept +{ + return {val, val, val}; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() + std::declval())> +operator+(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs.getX() + rhs.getX(), + lhs.getY() + rhs.getY(), + lhs.getZ() + rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() + std::declval())> +operator+(const BasicVector3& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() + rhs, + lhs.getY() + rhs, + lhs.getZ() + rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() + std::declval())> +operator+(T1 lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs + rhs.getX(), + lhs + rhs.getY(), + lhs + rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() - std::declval())> +operator-(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs.getX() - rhs.getX(), + lhs.getY() - rhs.getY(), + lhs.getZ() - rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() - std::declval())> +operator-(const BasicVector3& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() - rhs, + lhs.getY() - rhs, + lhs.getZ() - rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() - std::declval())> +operator-(T1 lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs - rhs.getX(), + lhs - rhs.getY(), + lhs - rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() * std::declval())> +operator*(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs.getX() * rhs.getX(), + lhs.getY() * rhs.getY(), + lhs.getZ() * rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() * std::declval())> +operator*(const BasicVector3& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() * rhs, + lhs.getY() * rhs, + lhs.getZ() * rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() * std::declval())> +operator*(T1 lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs * rhs.getX(), + lhs * rhs.getY(), + lhs * rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() / std::declval())> +operator/(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs.getX() / rhs.getX(), + lhs.getY() / rhs.getY(), + lhs.getZ() / rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() / std::declval())> +operator/(const BasicVector3& lhs, T2 rhs) noexcept +{ + return { + lhs.getX() / rhs, + lhs.getY() / rhs, + lhs.getZ() / rhs + }; +} + +/* ************************************************************************ */ + +template +inline BasicVector3() / std::declval())> +operator/(T1 lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs / rhs.getX(), + lhs / rhs.getY(), + lhs / rhs.getZ() + }; +} + +/* ************************************************************************ */ + +template +inline bool operator==(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +{ + return + lhs.getX() == rhs.getX() && + lhs.getY() == rhs.getY() && + lhs.getZ() == rhs.getZ() + ; +} + +/* ************************************************************************ */ + +template +inline +BasicVector3() * std::declval())> +cross(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +{ + return { + lhs.getY() * rhs.getZ() - lhs.getZ() * rhs.getY(), + lhs.getZ() * rhs.getX() - lhs.getX() * rhs.getZ(), + lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX() + }; +} + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ diff --git a/src/math/CMakeLists.txt b/src/math/CMakeLists.txt index 526f590..ca0401b 100644 --- a/src/math/CMakeLists.txt +++ b/src/math/CMakeLists.txt @@ -1,5 +1,5 @@ # ######################################################################### # -# Georgiev Lab (c) 2015-2016 # +# Georgiev Lab (c) 2015-2017 # # ######################################################################### # # Department of Cybernetics # # Faculty of Applied Sciences # @@ -25,6 +25,8 @@ set(SRCS Vector.cpp + Vector2.cpp + Vector3.cpp Grid.cpp ) diff --git a/src/math/Vector2.cpp b/src/math/Vector2.cpp new file mode 100644 index 0000000..69745c6 --- /dev/null +++ b/src/math/Vector2.cpp @@ -0,0 +1,46 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +// Declaration +#include "cece/math/Vector2.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template class BasicVector2; +template class BasicVector2; +template class BasicVector2; +template class BasicVector2; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ diff --git a/src/math/Vector3.cpp b/src/math/Vector3.cpp new file mode 100644 index 0000000..c8d3a51 --- /dev/null +++ b/src/math/Vector3.cpp @@ -0,0 +1,46 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +// Declaration +#include "cece/math/Vector3.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template class BasicVector3; +template class BasicVector3; +template class BasicVector3; +template class BasicVector3; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ diff --git a/unittests/math/CMakeLists.txt b/unittests/math/CMakeLists.txt index dc505b8..6574948 100644 --- a/unittests/math/CMakeLists.txt +++ b/unittests/math/CMakeLists.txt @@ -26,6 +26,7 @@ cece_add_test(core SOURCES Vector_test.cpp + Vector2_test.cpp VectorRangeTest.cpp ) diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp new file mode 100644 index 0000000..bc8c62a --- /dev/null +++ b/unittests/math/Vector2_test.cpp @@ -0,0 +1,427 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +// GTest +#include "gtest/gtest.h" + +// CeCe +#include "cece/math/Vector2.hpp" + +/* ************************************************************************ */ + +using namespace cece; +using namespace cece::math; + +/* ************************************************************************ */ + +TEST(Vector2, ctor) +{ + { + BasicVector2 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + } + + { + BasicVector2 vec(Zero); + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + } + + { + BasicVector2 vec = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec.getX()); + EXPECT_FLOAT_EQ(3.0f, vec.getY()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + } + + { + const BasicVector2 vec1 = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec1.getX()); + EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + + BasicVector2 vec2(vec1); + + EXPECT_FLOAT_EQ(1.2f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } + + { + BasicVector2 vec1 = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec1.getX()); + EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + + BasicVector2 vec2(std::move(vec1)); + + EXPECT_FLOAT_EQ(1.2f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } + + { + const BasicVector2 vec1 = {1, 3}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + + BasicVector2 vec2(vec1); + + EXPECT_FLOAT_EQ(1.0f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } +} + +/* ************************************************************************ */ + +TEST(Vector2, assignment) +{ + { + BasicVector2 vec{1, 1}; + + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(1, vec[1]); + + vec = Zero; + + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + } + + { + BasicVector2 vec; + + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + + vec = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + } + + { + const BasicVector2 vec1 = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + + BasicVector2 vec2; + + vec2 = vec1; + + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } + + { + BasicVector2 vec1 = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + + BasicVector2 vec2; + + vec2 = std::move(vec1); + + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } + + { + const BasicVector2 vec1 = {1, 3}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + + BasicVector2 vec2; + + vec2 = vec1; + + EXPECT_FLOAT_EQ(1.0, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } +} + +/* ************************************************************************ */ + +TEST(Vector2, operators) +{ + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + BasicVector2 vec2 = +vec1; + + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(2.0f, vec2[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + BasicVector2 vec2 = -vec1; + + EXPECT_FLOAT_EQ(-1.0f, vec2[0]); + EXPECT_FLOAT_EQ(-2.0f, vec2[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + BasicVector2 vec2{1.0f, 2.0f}; + vec1 += vec2; + + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + BasicVector2 vec2{1.0f, 2.0f}; + vec1 -= vec2; + + EXPECT_FLOAT_EQ(0.0f, vec1[0]); + EXPECT_FLOAT_EQ(0.0f, vec1[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + vec1 *= 2.0; + + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + BasicVector2 vec2{1.0f, 2.0f}; + vec1 *= vec2; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + vec1 /= 2.0; + + EXPECT_FLOAT_EQ(0.5f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + } + + { + BasicVector2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + BasicVector2 vec2{1.0f, 2.0f}; + vec1 /= vec2; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + } +} + +/* ************************************************************************ */ + +TEST(Vector2, inRange) +{ + { + const BasicVector2 vecMin{-10.0f, -5.0f}; + const BasicVector2 vecMax{10.0f, 20.0f}; + + BasicVector2 vec1; + BasicVector2 vec2{-15.0f, 0.0f}; + BasicVector2 vec3{5.0f, 0.0f}; + + EXPECT_TRUE(vec1.inRange(vecMin, vecMax)); + EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); + EXPECT_TRUE(vec3.inRange(vecMin, vecMax)); + } + + { + const BasicVector2 vecMax{10.0f, 20.0f}; + + BasicVector2 vec1; + BasicVector2 vec2{-15.0f, 0.0f}; + BasicVector2 vec3{5.0f, 0.0f}; + + EXPECT_TRUE(vec1.inRange(vecMax)); + EXPECT_FALSE(vec2.inRange(vecMax)); + EXPECT_TRUE(vec3.inRange(vecMax)); + } +} + +/* ************************************************************************ */ + +TEST(Vector2, memberFunctions) +{ + { + const BasicVector2 vec; + + EXPECT_FLOAT_EQ(0, vec.getLength()); + } + + { + const BasicVector2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(2.2360680f, vec.getLength()); + } + + { + const BasicVector2 vec; + + EXPECT_FLOAT_EQ(0, vec.getLengthSquared()); + } + + { + const BasicVector2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(5, vec.getLengthSquared()); + } + + { + const BasicVector2 vec; + + EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + } + + { + const BasicVector2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + } + + { + const BasicVector2 vec1; + const BasicVector2 vec2; + + EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); + } + + { + const BasicVector2 vec1{1.0f, 2.0f}; + const BasicVector2 vec2{5.0f, 4.0f}; + + EXPECT_FLOAT_EQ(13, vec1.dot(vec2)); + } + + { + const BasicVector2 vec; + + EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + } + + { + const BasicVector2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + } + + { + const BasicVector2 vec1{1.0f, 2.0f}; + const BasicVector2 vec2{5.0f, 4.0f}; + + EXPECT_FLOAT_EQ(20.0f, vec1.distanceSquared(vec2)); + } + + { + const BasicVector2 vec1{1.0f, 2.0f}; + const BasicVector2 vec2{5.0f, 4.0f}; + + EXPECT_FLOAT_EQ(4.4721360f, vec1.distance(vec2)); + } + + { + const BasicVector2 vec{1.0f, 2.0f}; + + auto inv = vec.inversed(); + + EXPECT_FLOAT_EQ(1.0f, inv[0]); + EXPECT_FLOAT_EQ(0.5f, inv[1]); + } + + { + auto vec = BasicVector2::createSingle(1); + + EXPECT_FLOAT_EQ(1.0f, vec[0]); + EXPECT_FLOAT_EQ(1.0f, vec[1]); + } + + { + auto vec = BasicVector2::createSingle(375.1721f); + + EXPECT_FLOAT_EQ(375.1721f, vec[0]); + EXPECT_FLOAT_EQ(375.1721f, vec[1]); + } +} + +/* ************************************************************************ */ From 7cc87b16d1fe7071443442db8c209e8d0eeb2a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Thu, 9 Mar 2017 17:28:15 +0100 Subject: [PATCH 03/11] Renamed BasicVector(2/3) to Vector(2/3) and some changes in API. --- include/cece/math/Vector.hpp | 26 +- include/cece/math/Vector2.hpp | 425 +++++++++++++-------------- include/cece/math/Vector3.hpp | 290 +++++++++--------- include/cece/math/VectorRange.hpp | 58 ++-- src/math/Vector2.cpp | 8 +- src/math/Vector3.cpp | 8 +- unittests/math/CMakeLists.txt | 1 + unittests/math/Vector2_test.cpp | 199 +++++++++---- unittests/math/Vector3_test.cpp | 473 ++++++++++++++++++++++++++++++ 9 files changed, 1008 insertions(+), 480 deletions(-) create mode 100644 unittests/math/Vector3_test.cpp diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index 0282e53..ab050e5 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -497,39 +497,39 @@ class BasicVector // TODO: rework template -struct BasicVector : public BasicVector2 +struct BasicVector : public Vector2 { - using BasicVector2::BasicVector2; + using Vector2::Vector2; BasicVector() {}; - BasicVector(const BasicVector2& src) - : BasicVector2(src) + BasicVector(const Vector2& src) + : Vector2(src) { // } - const T& getWidth() const noexcept { return BasicVector2::getX(); } - const T& getHeight() const noexcept { return BasicVector2::getY(); } + const T& getWidth() const noexcept { return Vector2::getX(); } + const T& getHeight() const noexcept { return Vector2::getY(); } }; /* ************************************************************************ */ // TODO: rework template -struct BasicVector : public BasicVector3 +struct BasicVector : public Vector3 { - using BasicVector3::BasicVector3; + using Vector3::Vector3; BasicVector() {}; - BasicVector(const BasicVector3& src) - : BasicVector3(src) + BasicVector(const Vector3& src) + : Vector3(src) { // } - const T& getWidth() const noexcept { return BasicVector3::getX(); } - const T& getHeight() const noexcept { return BasicVector3::getY(); } - const T& getDepth() const noexcept { return BasicVector3::getZ(); } + const T& getWidth() const noexcept { return Vector3::getX(); } + const T& getHeight() const noexcept { return Vector3::getY(); } + const T& getDepth() const noexcept { return Vector3::getZ(); } }; /* ************************************************************************ */ diff --git a/include/cece/math/Vector2.hpp b/include/cece/math/Vector2.hpp index 679992c..32f8970 100644 --- a/include/cece/math/Vector2.hpp +++ b/include/cece/math/Vector2.hpp @@ -51,7 +51,7 @@ namespace math { * @tparam T Element type. */ template -class BasicVector2 +class Vector2 { @@ -59,13 +59,23 @@ class BasicVector2 public: - /// BasicVector2 value type. + /// Vector2 value type. using ValueType = T; /// Element type squared. using ValueTypeSq = decltype(std::declval() * std::declval()); +// Public Data Members +public: + + /// X coordinate. + T x; + + /// Y coordinate. + T y; + + // Public Ctors public: @@ -73,7 +83,7 @@ class BasicVector2 /** * @brief Default constructor. */ - BasicVector2() noexcept; + Vector2() noexcept; /** @@ -82,7 +92,7 @@ class BasicVector2 * @param x The X coordinate. * @param y The Y coordinate. */ - BasicVector2(T x, T y) noexcept; + Vector2(T x, T y) noexcept; /** @@ -90,7 +100,7 @@ class BasicVector2 * * @param[in] zero The zero value. */ - BasicVector2(Zero_t zero) noexcept; + Vector2(Zero_t zero) noexcept; /** @@ -98,7 +108,7 @@ class BasicVector2 * * @param[in] src The source vector. */ - BasicVector2(const BasicVector2& src) noexcept; + Vector2(const Vector2& src) noexcept; /** @@ -106,7 +116,7 @@ class BasicVector2 * * @param[in] src The source vector. */ - BasicVector2(BasicVector2&& src) noexcept; + Vector2(Vector2&& src) noexcept; /** @@ -117,7 +127,7 @@ class BasicVector2 * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - BasicVector2(const BasicVector2& rhs) noexcept; + Vector2(const Vector2& rhs) noexcept; // Public Operators @@ -131,7 +141,7 @@ class BasicVector2 * * @return *this. */ - BasicVector2& operator=(Zero_t zero) noexcept; + Vector2& operator=(Zero_t zero) noexcept; /** @@ -141,7 +151,7 @@ class BasicVector2 * * @return *this. */ - BasicVector2& operator=(const BasicVector2& src) noexcept; + Vector2& operator=(const Vector2& src) noexcept; /** @@ -151,7 +161,7 @@ class BasicVector2 * * @return *this. */ - BasicVector2& operator=(BasicVector2&& src) noexcept; + Vector2& operator=(Vector2&& src) noexcept; /** @@ -164,7 +174,7 @@ class BasicVector2 * @return *this. */ template::value>::type* = nullptr> - BasicVector2& operator=(const BasicVector2& src) noexcept; + Vector2& operator=(const Vector2& src) noexcept; /** @@ -172,7 +182,7 @@ class BasicVector2 * * @return Vector. */ - BasicVector2 operator+() const noexcept; + Vector2 operator+() const noexcept; /** @@ -180,7 +190,7 @@ class BasicVector2 * * @return Vector. */ - BasicVector2 operator-() const noexcept; + Vector2 operator-() const noexcept; /** @@ -196,7 +206,7 @@ class BasicVector2 decltype(std::declval() + std::declval()), T >::value>::type* = nullptr> - BasicVector2& operator+=(const BasicVector2& rhs) noexcept; + Vector2& operator+=(const Vector2& rhs) noexcept; /** @@ -204,7 +214,7 @@ class BasicVector2 * * @param rhs Right operand. * - * @tparam T1 Type of value in BasicVector2 operand. + * @tparam T1 Type of value in Vector2 operand. * * @return *this. */ @@ -212,7 +222,7 @@ class BasicVector2 decltype(std::declval() - std::declval()), T >::value>::type* = nullptr> - BasicVector2& operator-=(const BasicVector2& rhs) noexcept; + Vector2& operator-=(const Vector2& rhs) noexcept; /** @@ -231,7 +241,7 @@ class BasicVector2 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector2& operator*=(T1 rhs) noexcept; + Vector2& operator*=(T1 rhs) noexcept; /** @@ -239,7 +249,7 @@ class BasicVector2 * * @param rhs Right operand. * - * @tparam T1 Type of value in BasicVector2 operand. + * @tparam T1 Type of value in Vector2 operand. * * @return *this. */ @@ -250,7 +260,7 @@ class BasicVector2 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector2& operator*=(const BasicVector2& rhs) noexcept; + Vector2& operator*=(const Vector2& rhs) noexcept; /** @@ -269,7 +279,7 @@ class BasicVector2 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector2& operator/=(T1 rhs) noexcept; + Vector2& operator/=(T1 rhs) noexcept; /** @@ -277,7 +287,7 @@ class BasicVector2 * * @param rhs Right operand. * - * @tparam T1 Type of value in BasicVector2 operand. + * @tparam T1 Type of value in Vector2 operand. * * @return *this. */ @@ -288,7 +298,7 @@ class BasicVector2 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector2& operator/=(const BasicVector2& rhs) noexcept; + Vector2& operator/=(const Vector2& rhs) noexcept; /** @@ -315,14 +325,6 @@ class BasicVector2 public: - /** - * @brief Returns X coordinate. - * - * @return Reference to X coordinate. - */ - T& x() noexcept; - - /** * @brief Returns X coordinate. * @@ -339,14 +341,6 @@ class BasicVector2 void setX(T x) noexcept; - /** - * @brief Returns Y coordinate. - * - * @return Referent co Y coordinate. - */ - T& y() noexcept; - - /** * @brief Returns Y coordinate. * @@ -383,7 +377,7 @@ class BasicVector2 * * @return If current value is in given range. */ - bool inRange(const BasicVector2& low, const BasicVector2& high) const noexcept; + bool inRange(const Vector2& low, const Vector2& high) const noexcept; /** @@ -394,7 +388,7 @@ class BasicVector2 * * @return If current value is in given range. */ - bool inRange(const BasicVector2& high) const noexcept; + bool inRange(const Vector2& high) const noexcept; // Public Operations @@ -424,7 +418,7 @@ class BasicVector2 * * @return Dot product. */ - ValueTypeSq dot(const BasicVector2& rhs) const noexcept; + ValueTypeSq dot(const Vector2& rhs) const noexcept; /** @@ -434,7 +428,7 @@ class BasicVector2 * * @return Distance. */ - ValueTypeSq distanceSquared(const BasicVector2& rhs) const noexcept; + ValueTypeSq distanceSquared(const Vector2& rhs) const noexcept; /** @@ -444,7 +438,7 @@ class BasicVector2 * * @return Distance. */ - ValueType distance(const BasicVector2& rhs) const noexcept; + ValueType distance(const Vector2& rhs) const noexcept; /** @@ -455,17 +449,18 @@ class BasicVector2 * @return Inversed vector. */ template - BasicVector2 inversed() const noexcept; + Vector2 inversed() const noexcept; /** - * @brief Rotate current vector and return rotated version. + * @brief Rotate current vector counter-clockwise and return rotated + * version. * * @param angle Rotation angle. * * @return Rotated vector. */ - BasicVector2 rotated(unit::Angle angle) const noexcept; + Vector2 rotated(unit::Angle angle) const noexcept; /** @@ -475,26 +470,16 @@ class BasicVector2 * * @return Vector of {val, val}. */ - static BasicVector2 createSingle(T val) noexcept; - - -// Private Data Members -private: - - /// X coordinate. - T m_x; - - /// Y coordinate. - T m_y; + static Vector2 createSingle(T val) noexcept; }; /* ************************************************************************ */ -extern template class BasicVector2; -extern template class BasicVector2; -extern template class BasicVector2; -extern template class BasicVector2; +extern template class Vector2; +extern template class Vector2; +extern template class Vector2; +extern template class Vector2; /* ************************************************************************ */ @@ -504,14 +489,14 @@ extern template class BasicVector2; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T1 Type of value in first Vector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() + std::declval())> -operator+(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; +inline Vector2() + std::declval())> +operator+(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -521,14 +506,14 @@ operator+(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. + * @tparam T1 Type of value in first Vector2. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector2() + std::declval())> -operator+(const BasicVector2& lhs, T2 rhs) noexcept; +inline Vector2() + std::declval())> +operator+(const Vector2& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -539,13 +524,13 @@ operator+(const BasicVector2& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() + std::declval())> -operator+(T1 lhs, const BasicVector2& rhs) noexcept; +inline Vector2() + std::declval())> +operator+(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -555,14 +540,14 @@ operator+(T1 lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T1 Type of value in first Vector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() - std::declval())> -operator-(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; +inline Vector2() - std::declval())> +operator-(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -572,14 +557,14 @@ operator-(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. + * @tparam T1 Type of value in first Vector2. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector2() - std::declval())> -operator-(const BasicVector2& lhs, T2 rhs) noexcept; +inline Vector2() - std::declval())> +operator-(const Vector2& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -590,13 +575,13 @@ operator-(const BasicVector2& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() - std::declval())> -operator-(T1 lhs, const BasicVector2& rhs) noexcept; +inline Vector2() - std::declval())> +operator-(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -606,14 +591,14 @@ operator-(T1 lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T1 Type of value in first Vector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() * std::declval())> -operator*(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; +inline Vector2() * std::declval())> +operator*(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -623,14 +608,14 @@ operator*(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. + * @tparam T1 Type of value in first Vector2. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector2() * std::declval())> -operator*(const BasicVector2& lhs, T2 rhs) noexcept; +inline Vector2() * std::declval())> +operator*(const Vector2& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -641,13 +626,13 @@ operator*(const BasicVector2& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() * std::declval())> -operator*(T1 lhs, const BasicVector2& rhs) noexcept; +inline Vector2() * std::declval())> +operator*(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -657,14 +642,14 @@ operator*(T1 lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T1 Type of value in first Vector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() / std::declval())> -operator/(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; +inline Vector2() / std::declval())> +operator/(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -674,14 +659,14 @@ operator/(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector2. + * @tparam T1 Type of value in first Vector2. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector2() / std::declval())> -operator/(const BasicVector2& lhs, T2 rhs) noexcept; +inline Vector2() / std::declval())> +operator/(const Vector2& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -692,13 +677,13 @@ operator/(const BasicVector2& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector2. + * @tparam T2 Type of value in second Vector2. * * @return Result vector. */ template -inline BasicVector2() / std::declval())> -operator/(T1 lhs, const BasicVector2& rhs) noexcept; +inline Vector2() / std::declval())> +operator/(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -714,7 +699,7 @@ operator/(T1 lhs, const BasicVector2& rhs) noexcept; * @return Comparision result. */ template -inline bool operator==(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; +inline bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -732,7 +717,7 @@ inline bool operator==(const BasicVector2& lhs, const BasicVector2& rhs) template inline decltype(std::declval() * std::declval()) -cross(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; +cross(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -749,8 +734,8 @@ cross(const BasicVector2& lhs, const BasicVector2& rhs) noexcept; */ template inline -BasicVector2() * std::declval())> -cross(const BasicVector2& lhs, const T2& rhs) noexcept; +Vector2() * std::declval())> +cross(const Vector2& lhs, const T2& rhs) noexcept; /* ************************************************************************ */ @@ -767,8 +752,8 @@ cross(const BasicVector2& lhs, const T2& rhs) noexcept; */ template inline -BasicVector2() * std::declval())> -cross(const T1& lhs, const BasicVector2& rhs) noexcept; +Vector2() * std::declval())> +cross(const T1& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -785,9 +770,9 @@ namespace math { /* ************************************************************************ */ template -inline BasicVector2::BasicVector2() noexcept - : m_x{} - , m_y{} +inline Vector2::Vector2() noexcept + : x{} + , y{} { // Nothing to do } @@ -795,9 +780,9 @@ inline BasicVector2::BasicVector2() noexcept /* ************************************************************************ */ template -inline BasicVector2::BasicVector2(T x, T y) noexcept - : m_x(x) - , m_y(y) +inline Vector2::Vector2(T x, T y) noexcept + : x{std::move(x)} + , y{std::move(y)} { // Nothing to do } @@ -805,9 +790,9 @@ inline BasicVector2::BasicVector2(T x, T y) noexcept /* ************************************************************************ */ template -inline BasicVector2::BasicVector2(Zero_t zero) noexcept - : m_x{} - , m_y{} +inline Vector2::Vector2(Zero_t zero) noexcept + : x{} + , y{} { // Nothing to do } @@ -815,9 +800,9 @@ inline BasicVector2::BasicVector2(Zero_t zero) noexcept /* ************************************************************************ */ template -inline BasicVector2::BasicVector2(const BasicVector2& src) noexcept - : m_x{src.getX()} - , m_y{src.getY()} +inline Vector2::Vector2(const Vector2& src) noexcept + : x{src.getX()} + , y{src.getY()} { // Nothing to do } @@ -825,9 +810,9 @@ inline BasicVector2::BasicVector2(const BasicVector2& src) noexcept /* ************************************************************************ */ template -inline BasicVector2::BasicVector2(BasicVector2&& src) noexcept - : m_x{std::move(src.m_x)} - , m_y{std::move(src.m_y)} +inline Vector2::Vector2(Vector2&& src) noexcept + : x{std::move(src.x)} + , y{std::move(src.y)} { // Nothing to do } @@ -836,9 +821,9 @@ inline BasicVector2::BasicVector2(BasicVector2&& src) noexcept template template::value>::type*> -inline BasicVector2::BasicVector2(const BasicVector2& rhs) noexcept - : m_x(rhs.getX()) - , m_y(rhs.getY()) +inline Vector2::Vector2(const Vector2& rhs) noexcept + : x(rhs.getX()) + , y(rhs.getY()) { // Nothing to do } @@ -846,10 +831,10 @@ inline BasicVector2::BasicVector2(const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2& BasicVector2::operator=(Zero_t zero) noexcept +inline Vector2& Vector2::operator=(Zero_t zero) noexcept { - m_x = T{}; - m_y = T{}; + x = T{}; + y = T{}; return *this; } @@ -857,10 +842,10 @@ inline BasicVector2& BasicVector2::operator=(Zero_t zero) noexcept /* ************************************************************************ */ template -inline BasicVector2& BasicVector2::operator=(const BasicVector2& src) noexcept +inline Vector2& Vector2::operator=(const Vector2& src) noexcept { - m_x = src.m_x; - m_y = src.m_y; + x = src.x; + y = src.y; return *this; } @@ -868,10 +853,10 @@ inline BasicVector2& BasicVector2::operator=(const BasicVector2& src) noex /* ************************************************************************ */ template -inline BasicVector2& BasicVector2::operator=(BasicVector2&& src) noexcept +inline Vector2& Vector2::operator=(Vector2&& src) noexcept { - m_x = std::move(src.m_x); - m_y = std::move(src.m_y); + x = std::move(src.x); + y = std::move(src.y); return *this; } @@ -880,10 +865,10 @@ inline BasicVector2& BasicVector2::operator=(BasicVector2&& src) noexcept template template::value>::type*> -inline BasicVector2& BasicVector2::operator=(const BasicVector2& src) noexcept +inline Vector2& Vector2::operator=(const Vector2& src) noexcept { - m_x = T(src.getX()); - m_y = T(src.getY()); + x = T(src.getX()); + y = T(src.getY()); return *this; } @@ -891,7 +876,7 @@ inline BasicVector2& BasicVector2::operator=(const BasicVector2& src) /* ************************************************************************ */ template -inline BasicVector2 BasicVector2::operator+() const noexcept +inline Vector2 Vector2::operator+() const noexcept { return *this; } @@ -899,9 +884,9 @@ inline BasicVector2 BasicVector2::operator+() const noexcept /* ************************************************************************ */ template -inline BasicVector2 BasicVector2::operator-() const noexcept +inline Vector2 Vector2::operator-() const noexcept { - return {-m_x, -m_y}; + return {-x, -y}; } /* ************************************************************************ */ @@ -911,10 +896,10 @@ template() + std::declval()), T >::value>::type*> -inline BasicVector2& BasicVector2::operator+=(const BasicVector2& rhs) noexcept +inline Vector2& Vector2::operator+=(const Vector2& rhs) noexcept { - m_x += rhs.getX(); - m_y += rhs.getY(); + x += rhs.getX(); + y += rhs.getY(); return *this; } @@ -926,10 +911,10 @@ template() - std::declval()), T >::value>::type*> -inline BasicVector2& BasicVector2::operator-=(const BasicVector2& rhs) noexcept +inline Vector2& Vector2::operator-=(const Vector2& rhs) noexcept { - m_x -= rhs.getX(); - m_y -= rhs.getY(); + x -= rhs.getX(); + y -= rhs.getY(); return *this; } @@ -944,10 +929,10 @@ template() * std::declval()) >::value>::type*> -inline BasicVector2& BasicVector2::operator*=(T1 rhs) noexcept +inline Vector2& Vector2::operator*=(T1 rhs) noexcept { - m_x *= rhs; - m_y *= rhs; + x *= rhs; + y *= rhs; return *this; } @@ -962,10 +947,10 @@ template() * std::declval()) >::value>::type*> -inline BasicVector2& BasicVector2::operator*=(const BasicVector2& rhs) noexcept +inline Vector2& Vector2::operator*=(const Vector2& rhs) noexcept { - m_x *= rhs.getX(); - m_y *= rhs.getY(); + x *= rhs.getX(); + y *= rhs.getY(); return *this; } @@ -980,10 +965,10 @@ template() * std::declval()) >::value>::type*> -inline BasicVector2& BasicVector2::operator/=(T1 rhs) noexcept +inline Vector2& Vector2::operator/=(T1 rhs) noexcept { - m_x /= rhs; - m_y /= rhs; + x /= rhs; + y /= rhs; return *this; } @@ -998,10 +983,10 @@ template() * std::declval()) >::value>::type*> -inline BasicVector2& BasicVector2::operator/=(const BasicVector2& rhs) noexcept +inline Vector2& Vector2::operator/=(const Vector2& rhs) noexcept { - m_x /= rhs.getX(); - m_y /= rhs.getY(); + x /= rhs.getX(); + y /= rhs.getY(); return *this; } @@ -1009,75 +994,59 @@ inline BasicVector2& BasicVector2::operator/=(const BasicVector2& rhs) /* ************************************************************************ */ template -inline T& BasicVector2::operator[](int pos) noexcept +inline T& Vector2::operator[](int pos) noexcept { CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 2); - return (&m_x)[pos]; + return (&x)[pos]; } /* ************************************************************************ */ template -inline const T& BasicVector2::operator[](int pos) const noexcept +inline const T& Vector2::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 2); - return (&m_x)[pos]; -} - -/* ************************************************************************ */ - -template -inline T& BasicVector2::x() noexcept -{ - return m_x; -} - -/* ************************************************************************ */ - -template -inline const T& BasicVector2::getX() const noexcept -{ - return m_x; + return (&x)[pos]; } /* ************************************************************************ */ template -inline void BasicVector2::setX(T x) noexcept +inline const T& Vector2::getX() const noexcept { - m_x = std::move(x); + return x; } /* ************************************************************************ */ template -inline T& BasicVector2::y() noexcept +inline void Vector2::setX(T x) noexcept { - return m_y; + this->x = std::move(x); } /* ************************************************************************ */ template -inline const T& BasicVector2::getY() const noexcept +inline const T& Vector2::getY() const noexcept { - return m_y; + return y; } /* ************************************************************************ */ template -inline void BasicVector2::setY(T y) noexcept +inline void Vector2::setY(T y) noexcept { - m_y = std::move(y); + this->y = std::move(y); } /* ************************************************************************ */ template -inline bool BasicVector2::inRange(T value, T low, T high) noexcept +inline bool Vector2::inRange(T value, T low, T high) noexcept { return value >= low && value < high; } @@ -1085,7 +1054,7 @@ inline bool BasicVector2::inRange(T value, T low, T high) noexcept /* ************************************************************************ */ template -inline bool BasicVector2::inRange(const BasicVector2& low, const BasicVector2& high) const noexcept +inline bool Vector2::inRange(const Vector2& low, const Vector2& high) const noexcept { bool res = true; @@ -1098,7 +1067,7 @@ inline bool BasicVector2::inRange(const BasicVector2& low, const BasicVector2 /* ************************************************************************ */ template -inline bool BasicVector2::inRange(const BasicVector2& high) const noexcept +inline bool Vector2::inRange(const Vector2& high) const noexcept { return inRange(Zero, high); } @@ -1106,7 +1075,7 @@ inline bool BasicVector2::inRange(const BasicVector2& high) const noexcept /* ************************************************************************ */ template -inline typename BasicVector2::ValueType BasicVector2::getLength() const noexcept +inline typename Vector2::ValueType Vector2::getLength() const noexcept { using std::sqrt; return static_cast(sqrt(getLengthSquared())); @@ -1115,7 +1084,7 @@ inline typename BasicVector2::ValueType BasicVector2::getLength() const no /* ************************************************************************ */ template -inline typename BasicVector2::ValueTypeSq BasicVector2::getLengthSquared() const noexcept +inline typename Vector2::ValueTypeSq Vector2::getLengthSquared() const noexcept { return dot(*this); } @@ -1123,7 +1092,7 @@ inline typename BasicVector2::ValueTypeSq BasicVector2::getLengthSquared() /* ************************************************************************ */ template -inline typename BasicVector2::ValueTypeSq BasicVector2::dot(const BasicVector2& rhs) const noexcept +inline typename Vector2::ValueTypeSq Vector2::dot(const Vector2& rhs) const noexcept { return getX() * rhs.getX() + getY() * rhs.getY(); } @@ -1131,7 +1100,7 @@ inline typename BasicVector2::ValueTypeSq BasicVector2::dot(const BasicVec /* ************************************************************************ */ template -inline typename BasicVector2::ValueTypeSq BasicVector2::distanceSquared(const BasicVector2& rhs) const noexcept +inline typename Vector2::ValueTypeSq Vector2::distanceSquared(const Vector2& rhs) const noexcept { return (*this - rhs).getLengthSquared(); } @@ -1139,7 +1108,7 @@ inline typename BasicVector2::ValueTypeSq BasicVector2::distanceSquared(co /* ************************************************************************ */ template -inline typename BasicVector2::ValueType BasicVector2::distance(const BasicVector2& rhs) const noexcept +inline typename Vector2::ValueType Vector2::distance(const Vector2& rhs) const noexcept { return (*this - rhs).getLength(); } @@ -1148,7 +1117,7 @@ inline typename BasicVector2::ValueType BasicVector2::distance(const Basic template template -inline BasicVector2 BasicVector2::inversed() const noexcept +inline Vector2 Vector2::inversed() const noexcept { return {T2(1) / getX(), T2(1) / getY()}; } @@ -1156,7 +1125,7 @@ inline BasicVector2 BasicVector2::inversed() const noexcept /* ************************************************************************ */ template -inline BasicVector2 BasicVector2::rotated(unit::Angle angle) const noexcept +inline Vector2 Vector2::rotated(unit::Angle angle) const noexcept { return { static_cast(getX() * cos(static_cast(angle)) - getY() * sin(static_cast(angle))), @@ -1167,7 +1136,7 @@ inline BasicVector2 BasicVector2::rotated(unit::Angle angle) const noexcep /* ************************************************************************ */ template -inline BasicVector2 BasicVector2::createSingle(T val) noexcept +inline Vector2 Vector2::createSingle(T val) noexcept { return {val, val}; } @@ -1175,8 +1144,8 @@ inline BasicVector2 BasicVector2::createSingle(T val) noexcept /* ************************************************************************ */ template -inline BasicVector2() + std::declval())> -operator+(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +inline Vector2() + std::declval())> +operator+(const Vector2& lhs, const Vector2& rhs) noexcept { return { lhs.getX() + rhs.getX(), @@ -1187,8 +1156,8 @@ operator+(const BasicVector2& lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() + std::declval())> -operator+(const BasicVector2& lhs, T2 rhs) noexcept +inline Vector2() + std::declval())> +operator+(const Vector2& lhs, T2 rhs) noexcept { return { lhs.getX() + rhs, @@ -1199,8 +1168,8 @@ operator+(const BasicVector2& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() + std::declval())> -operator+(T1 lhs, const BasicVector2& rhs) noexcept +inline Vector2() + std::declval())> +operator+(T1 lhs, const Vector2& rhs) noexcept { return { lhs + rhs.getX(), @@ -1211,8 +1180,8 @@ operator+(T1 lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() - std::declval())> -operator-(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +inline Vector2() - std::declval())> +operator-(const Vector2& lhs, const Vector2& rhs) noexcept { return { lhs.getX() - rhs.getX(), @@ -1223,8 +1192,8 @@ operator-(const BasicVector2& lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() - std::declval())> -operator-(const BasicVector2& lhs, T2 rhs) noexcept +inline Vector2() - std::declval())> +operator-(const Vector2& lhs, T2 rhs) noexcept { return { lhs.getX() - rhs, @@ -1235,8 +1204,8 @@ operator-(const BasicVector2& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() - std::declval())> -operator-(T1 lhs, const BasicVector2& rhs) noexcept +inline Vector2() - std::declval())> +operator-(T1 lhs, const Vector2& rhs) noexcept { return { lhs - rhs.getX(), @@ -1247,8 +1216,8 @@ operator-(T1 lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() * std::declval())> -operator*(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +inline Vector2() * std::declval())> +operator*(const Vector2& lhs, const Vector2& rhs) noexcept { return { lhs.getX() * rhs.getX(), @@ -1259,8 +1228,8 @@ operator*(const BasicVector2& lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() * std::declval())> -operator*(const BasicVector2& lhs, T2 rhs) noexcept +inline Vector2() * std::declval())> +operator*(const Vector2& lhs, T2 rhs) noexcept { return { lhs.getX() * rhs, @@ -1271,8 +1240,8 @@ operator*(const BasicVector2& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() * std::declval())> -operator*(T1 lhs, const BasicVector2& rhs) noexcept +inline Vector2() * std::declval())> +operator*(T1 lhs, const Vector2& rhs) noexcept { return { lhs * rhs.getX(), @@ -1283,8 +1252,8 @@ operator*(T1 lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() / std::declval())> -operator/(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +inline Vector2() / std::declval())> +operator/(const Vector2& lhs, const Vector2& rhs) noexcept { return { lhs.getX() / rhs.getX(), @@ -1295,8 +1264,8 @@ operator/(const BasicVector2& lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() / std::declval())> -operator/(const BasicVector2& lhs, T2 rhs) noexcept +inline Vector2() / std::declval())> +operator/(const Vector2& lhs, T2 rhs) noexcept { return { lhs.getX() / rhs, @@ -1307,8 +1276,8 @@ operator/(const BasicVector2& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector2() / std::declval())> -operator/(T1 lhs, const BasicVector2& rhs) noexcept +inline Vector2() / std::declval())> +operator/(T1 lhs, const Vector2& rhs) noexcept { return { lhs / rhs.getX(), @@ -1319,7 +1288,7 @@ operator/(T1 lhs, const BasicVector2& rhs) noexcept /* ************************************************************************ */ template -inline bool operator==(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +inline bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept { return lhs.getX() == rhs.getX() && @@ -1332,7 +1301,7 @@ inline bool operator==(const BasicVector2& lhs, const BasicVector2& rhs) template inline decltype(std::declval() * std::declval()) -cross(const BasicVector2& lhs, const BasicVector2& rhs) noexcept +cross(const Vector2& lhs, const Vector2& rhs) noexcept { return {lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX()}; } @@ -1341,8 +1310,8 @@ cross(const BasicVector2& lhs, const BasicVector2& rhs) noexcept template inline -BasicVector2() * std::declval())> -cross(const BasicVector2& lhs, const T2& rhs) noexcept +Vector2() * std::declval())> +cross(const Vector2& lhs, const T2& rhs) noexcept { return {rhs * lhs.getY(), -rhs * lhs.getX()}; } @@ -1351,8 +1320,8 @@ cross(const BasicVector2& lhs, const T2& rhs) noexcept template inline -BasicVector2() * std::declval())> -cross(const T1& lhs, const BasicVector2& rhs) noexcept +Vector2() * std::declval())> +cross(const T1& lhs, const Vector2& rhs) noexcept { return {-lhs * rhs.getY(), lhs * rhs.getX()}; } diff --git a/include/cece/math/Vector3.hpp b/include/cece/math/Vector3.hpp index 54ca338..93bce5d 100644 --- a/include/cece/math/Vector3.hpp +++ b/include/cece/math/Vector3.hpp @@ -51,7 +51,7 @@ namespace math { * @tparam T Element type. */ template -class BasicVector3 +class Vector3 { @@ -59,7 +59,7 @@ class BasicVector3 public: - /// BasicVector3 value type. + /// Vector3 value type. using ValueType = T; /// Element type squared. @@ -73,7 +73,7 @@ class BasicVector3 /** * @brief Default constructor. */ - BasicVector3() noexcept; + Vector3() noexcept; /** @@ -83,7 +83,7 @@ class BasicVector3 * @param y The Y coordinate. * @param y The Z coordinate. */ - BasicVector3(T x, T y, T z) noexcept; + Vector3(T x, T y, T z) noexcept; /** @@ -91,7 +91,7 @@ class BasicVector3 * * @param[in] zero The zero value. */ - BasicVector3(Zero_t zero) noexcept; + Vector3(Zero_t zero) noexcept; /** @@ -99,7 +99,7 @@ class BasicVector3 * * @param[in] src The source vector. */ - BasicVector3(const BasicVector3& src) noexcept; + Vector3(const Vector3& src) noexcept; /** @@ -107,7 +107,7 @@ class BasicVector3 * * @param[in] src The source vector. */ - BasicVector3(BasicVector3&& src) noexcept; + Vector3(Vector3&& src) noexcept; /** @@ -118,7 +118,7 @@ class BasicVector3 * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - BasicVector3(const BasicVector3& rhs) noexcept; + Vector3(const Vector3& rhs) noexcept; // Public Operators @@ -132,7 +132,7 @@ class BasicVector3 * * @return *this. */ - BasicVector3& operator=(Zero_t zero) noexcept; + Vector3& operator=(Zero_t zero) noexcept; /** @@ -142,7 +142,7 @@ class BasicVector3 * * @return *this. */ - BasicVector3& operator=(const BasicVector3& src) noexcept; + Vector3& operator=(const Vector3& src) noexcept; /** @@ -152,7 +152,7 @@ class BasicVector3 * * @return *this. */ - BasicVector3& operator=(BasicVector3&& src) noexcept; + Vector3& operator=(Vector3&& src) noexcept; /** @@ -165,7 +165,7 @@ class BasicVector3 * @return *this. */ template::value>::type* = nullptr> - BasicVector3& operator=(const BasicVector3& src) noexcept; + Vector3& operator=(const Vector3& src) noexcept; /** @@ -173,7 +173,7 @@ class BasicVector3 * * @return Vector. */ - BasicVector3 operator+() const noexcept; + Vector3 operator+() const noexcept; /** @@ -181,7 +181,7 @@ class BasicVector3 * * @return Vector. */ - BasicVector3 operator-() const noexcept; + Vector3 operator-() const noexcept; /** @@ -197,7 +197,7 @@ class BasicVector3 decltype(std::declval() + std::declval()), T >::value>::type* = nullptr> - BasicVector3& operator+=(const BasicVector3& rhs) noexcept; + Vector3& operator+=(const Vector3& rhs) noexcept; /** @@ -205,7 +205,7 @@ class BasicVector3 * * @param rhs Right operand. * - * @tparam T1 Type of value in BasicVector3 operand. + * @tparam T1 Type of value in Vector3 operand. * * @return *this. */ @@ -213,7 +213,7 @@ class BasicVector3 decltype(std::declval() - std::declval()), T >::value>::type* = nullptr> - BasicVector3& operator-=(const BasicVector3& rhs) noexcept; + Vector3& operator-=(const Vector3& rhs) noexcept; /** @@ -232,7 +232,7 @@ class BasicVector3 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector3& operator*=(T1 rhs) noexcept; + Vector3& operator*=(T1 rhs) noexcept; /** @@ -240,7 +240,7 @@ class BasicVector3 * * @param rhs Right operand. * - * @tparam T1 Type of value in BasicVector3 operand. + * @tparam T1 Type of value in Vector3 operand. * * @return *this. */ @@ -251,7 +251,7 @@ class BasicVector3 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector3& operator*=(const BasicVector3& rhs) noexcept; + Vector3& operator*=(const Vector3& rhs) noexcept; /** @@ -270,7 +270,7 @@ class BasicVector3 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector3& operator/=(T1 rhs) noexcept; + Vector3& operator/=(T1 rhs) noexcept; /** @@ -278,7 +278,7 @@ class BasicVector3 * * @param rhs Right operand. * - * @tparam T1 Type of value in BasicVector3 operand. + * @tparam T1 Type of value in Vector3 operand. * * @return *this. */ @@ -289,7 +289,7 @@ class BasicVector3 T, decltype(std::declval() * std::declval()) >::value>::type* = nullptr> - BasicVector3& operator/=(const BasicVector3& rhs) noexcept; + Vector3& operator/=(const Vector3& rhs) noexcept; /** @@ -408,7 +408,7 @@ class BasicVector3 * * @return If current value is in given range. */ - bool inRange(const BasicVector3& low, const BasicVector3& high) const noexcept; + bool inRange(const Vector3& low, const Vector3& high) const noexcept; /** @@ -419,7 +419,7 @@ class BasicVector3 * * @return If current value is in given range. */ - bool inRange(const BasicVector3& high) const noexcept; + bool inRange(const Vector3& high) const noexcept; // Public Operations @@ -449,7 +449,7 @@ class BasicVector3 * * @return Dot product. */ - ValueTypeSq dot(const BasicVector3& rhs) const noexcept; + ValueTypeSq dot(const Vector3& rhs) const noexcept; /** @@ -459,7 +459,7 @@ class BasicVector3 * * @return Distance. */ - ValueTypeSq distanceSquared(const BasicVector3& rhs) const noexcept; + ValueTypeSq distanceSquared(const Vector3& rhs) const noexcept; /** @@ -469,7 +469,7 @@ class BasicVector3 * * @return Distance. */ - ValueType distance(const BasicVector3& rhs) const noexcept; + ValueType distance(const Vector3& rhs) const noexcept; /** @@ -480,7 +480,7 @@ class BasicVector3 * @return Inversed vector. */ template - BasicVector3 inversed() const noexcept; + Vector3 inversed() const noexcept; /** @@ -490,7 +490,7 @@ class BasicVector3 * * @return Rotated vector. */ - BasicVector3 rotated(unit::Angle angle) const noexcept; + Vector3 rotated(unit::Angle angle) const noexcept; /** @@ -500,7 +500,7 @@ class BasicVector3 * * @return Vector of {val, val}. */ - static BasicVector3 createSingle(T val) noexcept; + static Vector3 createSingle(T val) noexcept; // Private Data Members @@ -519,10 +519,10 @@ class BasicVector3 /* ************************************************************************ */ -extern template class BasicVector3; -extern template class BasicVector3; -extern template class BasicVector3; -extern template class BasicVector3; +extern template class Vector3; +extern template class Vector3; +extern template class Vector3; +extern template class Vector3; /* ************************************************************************ */ @@ -532,14 +532,14 @@ extern template class BasicVector3; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T1 Type of value in first Vector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() + std::declval())> -operator+(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; +inline Vector3() + std::declval())> +operator+(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -549,14 +549,14 @@ operator+(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. + * @tparam T1 Type of value in first Vector3. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector3() + std::declval())> -operator+(const BasicVector3& lhs, T2 rhs) noexcept; +inline Vector3() + std::declval())> +operator+(const Vector3& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -567,13 +567,13 @@ operator+(const BasicVector3& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() + std::declval())> -operator+(T1 lhs, const BasicVector3& rhs) noexcept; +inline Vector3() + std::declval())> +operator+(T1 lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -583,14 +583,14 @@ operator+(T1 lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T1 Type of value in first Vector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() - std::declval())> -operator-(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; +inline Vector3() - std::declval())> +operator-(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -600,14 +600,14 @@ operator-(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. + * @tparam T1 Type of value in first Vector3. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector3() - std::declval())> -operator-(const BasicVector3& lhs, T2 rhs) noexcept; +inline Vector3() - std::declval())> +operator-(const Vector3& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -618,13 +618,13 @@ operator-(const BasicVector3& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() - std::declval())> -operator-(T1 lhs, const BasicVector3& rhs) noexcept; +inline Vector3() - std::declval())> +operator-(T1 lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -634,14 +634,14 @@ operator-(T1 lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T1 Type of value in first Vector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() * std::declval())> -operator*(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; +inline Vector3() * std::declval())> +operator*(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -651,14 +651,14 @@ operator*(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. + * @tparam T1 Type of value in first Vector3. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector3() * std::declval())> -operator*(const BasicVector3& lhs, T2 rhs) noexcept; +inline Vector3() * std::declval())> +operator*(const Vector3& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -669,13 +669,13 @@ operator*(const BasicVector3& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() * std::declval())> -operator*(T1 lhs, const BasicVector3& rhs) noexcept; +inline Vector3() * std::declval())> +operator*(T1 lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -685,14 +685,14 @@ operator*(T1 lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T1 Type of value in first Vector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() / std::declval())> -operator/(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; +inline Vector3() / std::declval())> +operator/(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -702,14 +702,14 @@ operator/(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; * @param lhs Left operand. * @param rhs Right operand. * - * @tparam T1 Type of value in first BasicVector3. + * @tparam T1 Type of value in first Vector3. * @tparam T2 Type of second operand. * * @return Result vector. */ template -inline BasicVector3() / std::declval())> -operator/(const BasicVector3& lhs, T2 rhs) noexcept; +inline Vector3() / std::declval())> +operator/(const Vector3& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -720,13 +720,13 @@ operator/(const BasicVector3& lhs, T2 rhs) noexcept; * @param rhs Right operand. * * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector3. + * @tparam T2 Type of value in second Vector3. * * @return Result vector. */ template -inline BasicVector3() / std::declval())> -operator/(T1 lhs, const BasicVector3& rhs) noexcept; +inline Vector3() / std::declval())> +operator/(T1 lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -742,7 +742,7 @@ operator/(T1 lhs, const BasicVector3& rhs) noexcept; * @return Comparision result. */ template -inline bool operator==(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; +inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -759,8 +759,8 @@ inline bool operator==(const BasicVector3& lhs, const BasicVector3& rhs) */ template inline -BasicVector3() * std::declval())> -cross(const BasicVector3& lhs, const BasicVector3& rhs) noexcept; +Vector3() * std::declval())> +cross(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ @@ -777,7 +777,7 @@ namespace math { /* ************************************************************************ */ template -inline BasicVector3::BasicVector3() noexcept +inline Vector3::Vector3() noexcept : m_x{} , m_y{} , m_z{} @@ -788,10 +788,10 @@ inline BasicVector3::BasicVector3() noexcept /* ************************************************************************ */ template -inline BasicVector3::BasicVector3(T x, T y, T z) noexcept +inline Vector3::Vector3(T x, T y, T z) noexcept : m_x(x) , m_y(y) - , m_z(y) + , m_z(z) { // Nothing to do } @@ -799,7 +799,7 @@ inline BasicVector3::BasicVector3(T x, T y, T z) noexcept /* ************************************************************************ */ template -inline BasicVector3::BasicVector3(Zero_t zero) noexcept +inline Vector3::Vector3(Zero_t zero) noexcept : m_x{} , m_y{} , m_z{} @@ -810,7 +810,7 @@ inline BasicVector3::BasicVector3(Zero_t zero) noexcept /* ************************************************************************ */ template -inline BasicVector3::BasicVector3(const BasicVector3& src) noexcept +inline Vector3::Vector3(const Vector3& src) noexcept : m_x{src.getX()} , m_y{src.getY()} , m_z{src.getZ()} @@ -821,7 +821,7 @@ inline BasicVector3::BasicVector3(const BasicVector3& src) noexcept /* ************************************************************************ */ template -inline BasicVector3::BasicVector3(BasicVector3&& src) noexcept +inline Vector3::Vector3(Vector3&& src) noexcept : m_x{std::move(src.m_x)} , m_y{std::move(src.m_y)} , m_z{std::move(src.m_z)} @@ -833,7 +833,7 @@ inline BasicVector3::BasicVector3(BasicVector3&& src) noexcept template template::value>::type*> -inline BasicVector3::BasicVector3(const BasicVector3& rhs) noexcept +inline Vector3::Vector3(const Vector3& rhs) noexcept : m_x(rhs.getX()) , m_y(rhs.getY()) , m_z(rhs.getZ()) @@ -844,7 +844,7 @@ inline BasicVector3::BasicVector3(const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3& BasicVector3::operator=(Zero_t zero) noexcept +inline Vector3& Vector3::operator=(Zero_t zero) noexcept { m_x = T{}; m_y = T{}; @@ -856,7 +856,7 @@ inline BasicVector3& BasicVector3::operator=(Zero_t zero) noexcept /* ************************************************************************ */ template -inline BasicVector3& BasicVector3::operator=(const BasicVector3& src) noexcept +inline Vector3& Vector3::operator=(const Vector3& src) noexcept { m_x = src.m_x; m_y = src.m_y; @@ -868,7 +868,7 @@ inline BasicVector3& BasicVector3::operator=(const BasicVector3& src) noex /* ************************************************************************ */ template -inline BasicVector3& BasicVector3::operator=(BasicVector3&& src) noexcept +inline Vector3& Vector3::operator=(Vector3&& src) noexcept { m_x = std::move(src.m_x); m_y = std::move(src.m_y); @@ -881,7 +881,7 @@ inline BasicVector3& BasicVector3::operator=(BasicVector3&& src) noexcept template template::value>::type*> -inline BasicVector3& BasicVector3::operator=(const BasicVector3& src) noexcept +inline Vector3& Vector3::operator=(const Vector3& src) noexcept { m_x = T(src.getX()); m_y = T(src.getY()); @@ -893,7 +893,7 @@ inline BasicVector3& BasicVector3::operator=(const BasicVector3& src) /* ************************************************************************ */ template -inline BasicVector3 BasicVector3::operator+() const noexcept +inline Vector3 Vector3::operator+() const noexcept { return *this; } @@ -901,7 +901,7 @@ inline BasicVector3 BasicVector3::operator+() const noexcept /* ************************************************************************ */ template -inline BasicVector3 BasicVector3::operator-() const noexcept +inline Vector3 Vector3::operator-() const noexcept { return {-m_x, -m_y, -m_z}; } @@ -913,7 +913,7 @@ template() + std::declval()), T >::value>::type*> -inline BasicVector3& BasicVector3::operator+=(const BasicVector3& rhs) noexcept +inline Vector3& Vector3::operator+=(const Vector3& rhs) noexcept { m_x += rhs.getX(); m_y += rhs.getY(); @@ -929,7 +929,7 @@ template() - std::declval()), T >::value>::type*> -inline BasicVector3& BasicVector3::operator-=(const BasicVector3& rhs) noexcept +inline Vector3& Vector3::operator-=(const Vector3& rhs) noexcept { m_x -= rhs.getX(); m_y -= rhs.getY(); @@ -948,7 +948,7 @@ template() * std::declval()) >::value>::type*> -inline BasicVector3& BasicVector3::operator*=(T1 rhs) noexcept +inline Vector3& Vector3::operator*=(T1 rhs) noexcept { m_x *= rhs; m_y *= rhs; @@ -967,7 +967,7 @@ template() * std::declval()) >::value>::type*> -inline BasicVector3& BasicVector3::operator*=(const BasicVector3& rhs) noexcept +inline Vector3& Vector3::operator*=(const Vector3& rhs) noexcept { m_x *= rhs.getX(); m_y *= rhs.getY(); @@ -986,7 +986,7 @@ template() * std::declval()) >::value>::type*> -inline BasicVector3& BasicVector3::operator/=(T1 rhs) noexcept +inline Vector3& Vector3::operator/=(T1 rhs) noexcept { m_x /= rhs; m_y /= rhs; @@ -1005,7 +1005,7 @@ template() * std::declval()) >::value>::type*> -inline BasicVector3& BasicVector3::operator/=(const BasicVector3& rhs) noexcept +inline Vector3& Vector3::operator/=(const Vector3& rhs) noexcept { m_x /= rhs.getX(); m_y /= rhs.getY(); @@ -1017,7 +1017,7 @@ inline BasicVector3& BasicVector3::operator/=(const BasicVector3& rhs) /* ************************************************************************ */ template -inline T& BasicVector3::operator[](int pos) noexcept +inline T& Vector3::operator[](int pos) noexcept { CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 3); @@ -1027,7 +1027,7 @@ inline T& BasicVector3::operator[](int pos) noexcept /* ************************************************************************ */ template -inline const T& BasicVector3::operator[](int pos) const noexcept +inline const T& Vector3::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 3); @@ -1037,7 +1037,7 @@ inline const T& BasicVector3::operator[](int pos) const noexcept /* ************************************************************************ */ template -inline T& BasicVector3::x() noexcept +inline T& Vector3::x() noexcept { return m_x; } @@ -1045,7 +1045,7 @@ inline T& BasicVector3::x() noexcept /* ************************************************************************ */ template -inline const T& BasicVector3::getX() const noexcept +inline const T& Vector3::getX() const noexcept { return m_x; } @@ -1053,7 +1053,7 @@ inline const T& BasicVector3::getX() const noexcept /* ************************************************************************ */ template -inline void BasicVector3::setX(T x) noexcept +inline void Vector3::setX(T x) noexcept { m_x = std::move(x); } @@ -1061,7 +1061,7 @@ inline void BasicVector3::setX(T x) noexcept /* ************************************************************************ */ template -inline T& BasicVector3::y() noexcept +inline T& Vector3::y() noexcept { return m_y; } @@ -1069,7 +1069,7 @@ inline T& BasicVector3::y() noexcept /* ************************************************************************ */ template -inline const T& BasicVector3::getY() const noexcept +inline const T& Vector3::getY() const noexcept { return m_y; } @@ -1077,7 +1077,7 @@ inline const T& BasicVector3::getY() const noexcept /* ************************************************************************ */ template -inline void BasicVector3::setY(T y) noexcept +inline void Vector3::setY(T y) noexcept { m_y = std::move(y); } @@ -1085,7 +1085,7 @@ inline void BasicVector3::setY(T y) noexcept /* ************************************************************************ */ template -inline T& BasicVector3::z() noexcept +inline T& Vector3::z() noexcept { return m_z; } @@ -1093,7 +1093,7 @@ inline T& BasicVector3::z() noexcept /* ************************************************************************ */ template -inline const T& BasicVector3::getZ() const noexcept +inline const T& Vector3::getZ() const noexcept { return m_z; } @@ -1101,7 +1101,7 @@ inline const T& BasicVector3::getZ() const noexcept /* ************************************************************************ */ template -inline void BasicVector3::setZ(T z) noexcept +inline void Vector3::setZ(T z) noexcept { m_z = std::move(z); } @@ -1109,7 +1109,7 @@ inline void BasicVector3::setZ(T z) noexcept /* ************************************************************************ */ template -inline bool BasicVector3::inRange(T value, T low, T high) noexcept +inline bool Vector3::inRange(T value, T low, T high) noexcept { return value >= low && value < high; } @@ -1117,7 +1117,7 @@ inline bool BasicVector3::inRange(T value, T low, T high) noexcept /* ************************************************************************ */ template -inline bool BasicVector3::inRange(const BasicVector3& low, const BasicVector3& high) const noexcept +inline bool Vector3::inRange(const Vector3& low, const Vector3& high) const noexcept { bool res = true; @@ -1131,7 +1131,7 @@ inline bool BasicVector3::inRange(const BasicVector3& low, const BasicVector3 /* ************************************************************************ */ template -inline bool BasicVector3::inRange(const BasicVector3& high) const noexcept +inline bool Vector3::inRange(const Vector3& high) const noexcept { return inRange(Zero, high); } @@ -1139,7 +1139,7 @@ inline bool BasicVector3::inRange(const BasicVector3& high) const noexcept /* ************************************************************************ */ template -inline typename BasicVector3::ValueType BasicVector3::getLength() const noexcept +inline typename Vector3::ValueType Vector3::getLength() const noexcept { using std::sqrt; return static_cast(sqrt(getLengthSquared())); @@ -1148,7 +1148,7 @@ inline typename BasicVector3::ValueType BasicVector3::getLength() const no /* ************************************************************************ */ template -inline typename BasicVector3::ValueTypeSq BasicVector3::getLengthSquared() const noexcept +inline typename Vector3::ValueTypeSq Vector3::getLengthSquared() const noexcept { return dot(*this); } @@ -1156,7 +1156,7 @@ inline typename BasicVector3::ValueTypeSq BasicVector3::getLengthSquared() /* ************************************************************************ */ template -inline typename BasicVector3::ValueTypeSq BasicVector3::dot(const BasicVector3& rhs) const noexcept +inline typename Vector3::ValueTypeSq Vector3::dot(const Vector3& rhs) const noexcept { return getX() * rhs.getX() + @@ -1168,7 +1168,7 @@ inline typename BasicVector3::ValueTypeSq BasicVector3::dot(const BasicVec /* ************************************************************************ */ template -inline typename BasicVector3::ValueTypeSq BasicVector3::distanceSquared(const BasicVector3& rhs) const noexcept +inline typename Vector3::ValueTypeSq Vector3::distanceSquared(const Vector3& rhs) const noexcept { return (*this - rhs).getLengthSquared(); } @@ -1176,7 +1176,7 @@ inline typename BasicVector3::ValueTypeSq BasicVector3::distanceSquared(co /* ************************************************************************ */ template -inline typename BasicVector3::ValueType BasicVector3::distance(const BasicVector3& rhs) const noexcept +inline typename Vector3::ValueType Vector3::distance(const Vector3& rhs) const noexcept { return (*this - rhs).getLength(); } @@ -1185,7 +1185,7 @@ inline typename BasicVector3::ValueType BasicVector3::distance(const Basic template template -inline BasicVector3 BasicVector3::inversed() const noexcept +inline Vector3 Vector3::inversed() const noexcept { return { T2(1) / getX(), @@ -1197,7 +1197,7 @@ inline BasicVector3 BasicVector3::inversed() const noexcept /* ************************************************************************ */ template -inline BasicVector3 BasicVector3::createSingle(T val) noexcept +inline Vector3 Vector3::createSingle(T val) noexcept { return {val, val, val}; } @@ -1205,8 +1205,8 @@ inline BasicVector3 BasicVector3::createSingle(T val) noexcept /* ************************************************************************ */ template -inline BasicVector3() + std::declval())> -operator+(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +inline Vector3() + std::declval())> +operator+(const Vector3& lhs, const Vector3& rhs) noexcept { return { lhs.getX() + rhs.getX(), @@ -1218,8 +1218,8 @@ operator+(const BasicVector3& lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() + std::declval())> -operator+(const BasicVector3& lhs, T2 rhs) noexcept +inline Vector3() + std::declval())> +operator+(const Vector3& lhs, T2 rhs) noexcept { return { lhs.getX() + rhs, @@ -1231,8 +1231,8 @@ operator+(const BasicVector3& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() + std::declval())> -operator+(T1 lhs, const BasicVector3& rhs) noexcept +inline Vector3() + std::declval())> +operator+(T1 lhs, const Vector3& rhs) noexcept { return { lhs + rhs.getX(), @@ -1244,8 +1244,8 @@ operator+(T1 lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() - std::declval())> -operator-(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +inline Vector3() - std::declval())> +operator-(const Vector3& lhs, const Vector3& rhs) noexcept { return { lhs.getX() - rhs.getX(), @@ -1257,8 +1257,8 @@ operator-(const BasicVector3& lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() - std::declval())> -operator-(const BasicVector3& lhs, T2 rhs) noexcept +inline Vector3() - std::declval())> +operator-(const Vector3& lhs, T2 rhs) noexcept { return { lhs.getX() - rhs, @@ -1270,8 +1270,8 @@ operator-(const BasicVector3& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() - std::declval())> -operator-(T1 lhs, const BasicVector3& rhs) noexcept +inline Vector3() - std::declval())> +operator-(T1 lhs, const Vector3& rhs) noexcept { return { lhs - rhs.getX(), @@ -1283,8 +1283,8 @@ operator-(T1 lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() * std::declval())> -operator*(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +inline Vector3() * std::declval())> +operator*(const Vector3& lhs, const Vector3& rhs) noexcept { return { lhs.getX() * rhs.getX(), @@ -1296,8 +1296,8 @@ operator*(const BasicVector3& lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() * std::declval())> -operator*(const BasicVector3& lhs, T2 rhs) noexcept +inline Vector3() * std::declval())> +operator*(const Vector3& lhs, T2 rhs) noexcept { return { lhs.getX() * rhs, @@ -1309,8 +1309,8 @@ operator*(const BasicVector3& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() * std::declval())> -operator*(T1 lhs, const BasicVector3& rhs) noexcept +inline Vector3() * std::declval())> +operator*(T1 lhs, const Vector3& rhs) noexcept { return { lhs * rhs.getX(), @@ -1322,8 +1322,8 @@ operator*(T1 lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() / std::declval())> -operator/(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +inline Vector3() / std::declval())> +operator/(const Vector3& lhs, const Vector3& rhs) noexcept { return { lhs.getX() / rhs.getX(), @@ -1335,8 +1335,8 @@ operator/(const BasicVector3& lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() / std::declval())> -operator/(const BasicVector3& lhs, T2 rhs) noexcept +inline Vector3() / std::declval())> +operator/(const Vector3& lhs, T2 rhs) noexcept { return { lhs.getX() / rhs, @@ -1348,8 +1348,8 @@ operator/(const BasicVector3& lhs, T2 rhs) noexcept /* ************************************************************************ */ template -inline BasicVector3() / std::declval())> -operator/(T1 lhs, const BasicVector3& rhs) noexcept +inline Vector3() / std::declval())> +operator/(T1 lhs, const Vector3& rhs) noexcept { return { lhs / rhs.getX(), @@ -1361,7 +1361,7 @@ operator/(T1 lhs, const BasicVector3& rhs) noexcept /* ************************************************************************ */ template -inline bool operator==(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept { return lhs.getX() == rhs.getX() && @@ -1374,8 +1374,8 @@ inline bool operator==(const BasicVector3& lhs, const BasicVector3& rhs) template inline -BasicVector3() * std::declval())> -cross(const BasicVector3& lhs, const BasicVector3& rhs) noexcept +Vector3() * std::declval())> +cross(const Vector3& lhs, const Vector3& rhs) noexcept { return { lhs.getY() * rhs.getZ() - lhs.getZ() * rhs.getY(), diff --git a/include/cece/math/VectorRange.hpp b/include/cece/math/VectorRange.hpp index 1784654..e9f708e 100644 --- a/include/cece/math/VectorRange.hpp +++ b/include/cece/math/VectorRange.hpp @@ -1,5 +1,5 @@ /* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2016 */ +/* Georgiev Lab (c) 2015-2017 */ /* ************************************************************************ */ /* Department of Cybernetics */ /* Faculty of Applied Sciences */ @@ -39,9 +39,9 @@ namespace math { /* ************************************************************************ */ /** - * @brief Wrapper for vector iterator. + * @brief Wrapper for vector iterator. * - * @tparam T Element type of Vector. + * @tparam T Element type of Vector. */ template struct IteratorVector @@ -64,11 +64,11 @@ struct IteratorVector /** - * @brief Constructor. + * @brief Constructor. * - * @param value Current value. - * @param max Maximum value. - * @param min Minimum value. + * @param value Current value. + * @param max Maximum value. + * @param min Minimum value. */ IteratorVector(Vector value, Vector max, Vector min = Zero) noexcept : m_value(std::move(value)) @@ -84,7 +84,7 @@ struct IteratorVector /** - * @brief Cast to value. + * @brief Cast to value. */ operator Vector() const noexcept { @@ -93,11 +93,11 @@ struct IteratorVector /** - * @brief Compares values. + * @brief Compares values. * - * @param rhs Second value. + * @param rhs Second value. * - * @return Are values equal? + * @return Are values equal? */ bool operator==(const IteratorVector& rhs) const noexcept { @@ -106,11 +106,11 @@ struct IteratorVector /** - * @brief Compares values. + * @brief Compares values. * - * @param rhs Second value. + * @param rhs Second value. * - * @return Aren't values equal? + * @return Aren't values equal? */ bool operator!=(const IteratorVector& rhs) const noexcept { @@ -119,9 +119,9 @@ struct IteratorVector /** - * @brief Dereference operator. + * @brief Dereference operator. * - * @return A reference to the current token. + * @return A reference to the current token. */ reference operator*() const noexcept { @@ -130,9 +130,9 @@ struct IteratorVector /** - * @brief Dereference operator. + * @brief Dereference operator. * - * @return A pointer to the current token. + * @return A pointer to the current token. */ pointer operator->() const noexcept { @@ -141,20 +141,20 @@ struct IteratorVector /** - * @brief Increment operator. + * @brief Increment operator. * - * @return *this. + * @return *this. */ IteratorVector& operator++() noexcept { - if (m_value.x() == m_max.x()) + if (m_value.x == m_max.x) { - m_value.x() = m_min.x(); - ++m_value.y(); + m_value.x = m_min.x; + ++m_value.y; } else { - ++m_value.x(); + ++m_value.x; } return *this; @@ -162,11 +162,15 @@ struct IteratorVector /** - * @brief Post-increment operator. + * @brief Post-increment operator. * - * @note Is deleted (because I'm to lazy to write it). + * @note Is deleted (because I'm to lazy to write it). + * + * @param[in] dummy The dummy. + * + * @return Iterator. */ - IteratorVector operator++(int) = delete; + IteratorVector operator++(int dummy) = delete; // Private Data Members diff --git a/src/math/Vector2.cpp b/src/math/Vector2.cpp index 69745c6..824623e 100644 --- a/src/math/Vector2.cpp +++ b/src/math/Vector2.cpp @@ -33,10 +33,10 @@ namespace math { /* ************************************************************************ */ -template class BasicVector2; -template class BasicVector2; -template class BasicVector2; -template class BasicVector2; +template class Vector2; +template class Vector2; +template class Vector2; +template class Vector2; /* ************************************************************************ */ diff --git a/src/math/Vector3.cpp b/src/math/Vector3.cpp index c8d3a51..8904c16 100644 --- a/src/math/Vector3.cpp +++ b/src/math/Vector3.cpp @@ -33,10 +33,10 @@ namespace math { /* ************************************************************************ */ -template class BasicVector3; -template class BasicVector3; -template class BasicVector3; -template class BasicVector3; +template class Vector3; +template class Vector3; +template class Vector3; +template class Vector3; /* ************************************************************************ */ diff --git a/unittests/math/CMakeLists.txt b/unittests/math/CMakeLists.txt index 6574948..d5a5575 100644 --- a/unittests/math/CMakeLists.txt +++ b/unittests/math/CMakeLists.txt @@ -27,6 +27,7 @@ cece_add_test(core SOURCES Vector_test.cpp Vector2_test.cpp + Vector3_test.cpp VectorRangeTest.cpp ) diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp index bc8c62a..9b45d9b 100644 --- a/unittests/math/Vector2_test.cpp +++ b/unittests/math/Vector2_test.cpp @@ -39,7 +39,7 @@ using namespace cece::math; TEST(Vector2, ctor) { { - BasicVector2 vec; + Vector2 vec; EXPECT_EQ(0, vec.getX()); EXPECT_EQ(0, vec.getY()); @@ -48,7 +48,7 @@ TEST(Vector2, ctor) } { - BasicVector2 vec(Zero); + Vector2 vec(Zero); EXPECT_EQ(0, vec.getX()); EXPECT_EQ(0, vec.getY()); @@ -57,7 +57,7 @@ TEST(Vector2, ctor) } { - BasicVector2 vec = {1.2f, 3.0f}; + Vector2 vec = {1.2f, 3.0f}; EXPECT_FLOAT_EQ(1.2f, vec.getX()); EXPECT_FLOAT_EQ(3.0f, vec.getY()); @@ -66,14 +66,14 @@ TEST(Vector2, ctor) } { - const BasicVector2 vec1 = {1.2f, 3.0f}; + const Vector2 vec1 = {1.2f, 3.0f}; EXPECT_FLOAT_EQ(1.2f, vec1.getX()); EXPECT_FLOAT_EQ(3.0f, vec1.getY()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); EXPECT_FLOAT_EQ(3.0f, vec1[1]); - BasicVector2 vec2(vec1); + Vector2 vec2(vec1); EXPECT_FLOAT_EQ(1.2f, vec2.getX()); EXPECT_FLOAT_EQ(3.0f, vec2.getY()); @@ -82,14 +82,14 @@ TEST(Vector2, ctor) } { - BasicVector2 vec1 = {1.2f, 3.0f}; + Vector2 vec1 = {1.2f, 3.0f}; EXPECT_FLOAT_EQ(1.2f, vec1.getX()); EXPECT_FLOAT_EQ(3.0f, vec1.getY()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); EXPECT_FLOAT_EQ(3.0f, vec1[1]); - BasicVector2 vec2(std::move(vec1)); + Vector2 vec2(std::move(vec1)); EXPECT_FLOAT_EQ(1.2f, vec2.getX()); EXPECT_FLOAT_EQ(3.0f, vec2.getY()); @@ -98,14 +98,14 @@ TEST(Vector2, ctor) } { - const BasicVector2 vec1 = {1, 3}; + const Vector2 vec1 = {1, 3}; EXPECT_EQ(1, vec1.getX()); EXPECT_EQ(3, vec1.getY()); EXPECT_EQ(1, vec1[0]); EXPECT_EQ(3, vec1[1]); - BasicVector2 vec2(vec1); + Vector2 vec2(vec1); EXPECT_FLOAT_EQ(1.0f, vec2.getX()); EXPECT_FLOAT_EQ(3.0f, vec2.getY()); @@ -119,7 +119,7 @@ TEST(Vector2, ctor) TEST(Vector2, assignment) { { - BasicVector2 vec{1, 1}; + Vector2 vec{1, 1}; EXPECT_EQ(1, vec[0]); EXPECT_EQ(1, vec[1]); @@ -131,7 +131,7 @@ TEST(Vector2, assignment) } { - BasicVector2 vec; + Vector2 vec; EXPECT_EQ(0, vec[0]); EXPECT_EQ(0, vec[1]); @@ -143,12 +143,12 @@ TEST(Vector2, assignment) } { - const BasicVector2 vec1 = {1.2f, 3.0f}; + const Vector2 vec1 = {1.2f, 3.0f}; EXPECT_FLOAT_EQ(1.2f, vec1[0]); EXPECT_FLOAT_EQ(3.0f, vec1[1]); - BasicVector2 vec2; + Vector2 vec2; vec2 = vec1; @@ -157,12 +157,12 @@ TEST(Vector2, assignment) } { - BasicVector2 vec1 = {1.2f, 3.0f}; + Vector2 vec1 = {1.2f, 3.0f}; EXPECT_FLOAT_EQ(1.2f, vec1[0]); EXPECT_FLOAT_EQ(3.0f, vec1[1]); - BasicVector2 vec2; + Vector2 vec2; vec2 = std::move(vec1); @@ -171,12 +171,12 @@ TEST(Vector2, assignment) } { - const BasicVector2 vec1 = {1, 3}; + const Vector2 vec1 = {1, 3}; EXPECT_EQ(1, vec1[0]); EXPECT_EQ(3, vec1[1]); - BasicVector2 vec2; + Vector2 vec2; vec2 = vec1; @@ -190,36 +190,36 @@ TEST(Vector2, assignment) TEST(Vector2, operators) { { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); - BasicVector2 vec2 = +vec1; + Vector2 vec2 = +vec1; EXPECT_FLOAT_EQ(1.0f, vec2[0]); EXPECT_FLOAT_EQ(2.0f, vec2[1]); } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); - BasicVector2 vec2 = -vec1; + Vector2 vec2 = -vec1; EXPECT_FLOAT_EQ(-1.0f, vec2[0]); EXPECT_FLOAT_EQ(-2.0f, vec2[1]); } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); - BasicVector2 vec2{1.0f, 2.0f}; + Vector2 vec2{1.0f, 2.0f}; vec1 += vec2; EXPECT_FLOAT_EQ(2.0f, vec1[0]); @@ -227,12 +227,12 @@ TEST(Vector2, operators) } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); - BasicVector2 vec2{1.0f, 2.0f}; + Vector2 vec2{1.0f, 2.0f}; vec1 -= vec2; EXPECT_FLOAT_EQ(0.0f, vec1[0]); @@ -240,7 +240,7 @@ TEST(Vector2, operators) } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); @@ -252,12 +252,12 @@ TEST(Vector2, operators) } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); - BasicVector2 vec2{1.0f, 2.0f}; + Vector2 vec2{1.0f, 2.0f}; vec1 *= vec2; EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -265,7 +265,7 @@ TEST(Vector2, operators) } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); @@ -277,12 +277,12 @@ TEST(Vector2, operators) } { - BasicVector2 vec1{1.0f, 2.0f}; + Vector2 vec1{1.0f, 2.0f}; EXPECT_FLOAT_EQ(1.0f, vec1[0]); EXPECT_FLOAT_EQ(2.0f, vec1[1]); - BasicVector2 vec2{1.0f, 2.0f}; + Vector2 vec2{1.0f, 2.0f}; vec1 /= vec2; EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -295,12 +295,12 @@ TEST(Vector2, operators) TEST(Vector2, inRange) { { - const BasicVector2 vecMin{-10.0f, -5.0f}; - const BasicVector2 vecMax{10.0f, 20.0f}; + const Vector2 vecMin{-10.0f, -5.0f}; + const Vector2 vecMax{10.0f, 20.0f}; - BasicVector2 vec1; - BasicVector2 vec2{-15.0f, 0.0f}; - BasicVector2 vec3{5.0f, 0.0f}; + Vector2 vec1; + Vector2 vec2{-15.0f, 0.0f}; + Vector2 vec3{5.0f, 0.0f}; EXPECT_TRUE(vec1.inRange(vecMin, vecMax)); EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); @@ -308,11 +308,11 @@ TEST(Vector2, inRange) } { - const BasicVector2 vecMax{10.0f, 20.0f}; + const Vector2 vecMax{10.0f, 20.0f}; - BasicVector2 vec1; - BasicVector2 vec2{-15.0f, 0.0f}; - BasicVector2 vec3{5.0f, 0.0f}; + Vector2 vec1; + Vector2 vec2{-15.0f, 0.0f}; + Vector2 vec3{5.0f, 0.0f}; EXPECT_TRUE(vec1.inRange(vecMax)); EXPECT_FALSE(vec2.inRange(vecMax)); @@ -325,83 +325,83 @@ TEST(Vector2, inRange) TEST(Vector2, memberFunctions) { { - const BasicVector2 vec; + const Vector2 vec; EXPECT_FLOAT_EQ(0, vec.getLength()); } { - const BasicVector2 vec{1.0f, 2.0f}; + const Vector2 vec{1.0f, 2.0f}; EXPECT_FLOAT_EQ(2.2360680f, vec.getLength()); } { - const BasicVector2 vec; + const Vector2 vec; EXPECT_FLOAT_EQ(0, vec.getLengthSquared()); } { - const BasicVector2 vec{1.0f, 2.0f}; + const Vector2 vec{1.0f, 2.0f}; EXPECT_FLOAT_EQ(5, vec.getLengthSquared()); } { - const BasicVector2 vec; + const Vector2 vec; EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); } { - const BasicVector2 vec{1.0f, 2.0f}; + const Vector2 vec{1.0f, 2.0f}; EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); } { - const BasicVector2 vec1; - const BasicVector2 vec2; + const Vector2 vec1; + const Vector2 vec2; EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); } { - const BasicVector2 vec1{1.0f, 2.0f}; - const BasicVector2 vec2{5.0f, 4.0f}; + const Vector2 vec1{1.0f, 2.0f}; + const Vector2 vec2{5.0f, 4.0f}; EXPECT_FLOAT_EQ(13, vec1.dot(vec2)); } { - const BasicVector2 vec; + const Vector2 vec; EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); } { - const BasicVector2 vec{1.0f, 2.0f}; + const Vector2 vec{1.0f, 2.0f}; EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); } { - const BasicVector2 vec1{1.0f, 2.0f}; - const BasicVector2 vec2{5.0f, 4.0f}; + const Vector2 vec1{1.0f, 2.0f}; + const Vector2 vec2{5.0f, 4.0f}; EXPECT_FLOAT_EQ(20.0f, vec1.distanceSquared(vec2)); } { - const BasicVector2 vec1{1.0f, 2.0f}; - const BasicVector2 vec2{5.0f, 4.0f}; + const Vector2 vec1{1.0f, 2.0f}; + const Vector2 vec2{5.0f, 4.0f}; EXPECT_FLOAT_EQ(4.4721360f, vec1.distance(vec2)); } { - const BasicVector2 vec{1.0f, 2.0f}; + const Vector2 vec{1.0f, 2.0f}; auto inv = vec.inversed(); @@ -410,14 +410,14 @@ TEST(Vector2, memberFunctions) } { - auto vec = BasicVector2::createSingle(1); + auto vec = Vector2::createSingle(1); EXPECT_FLOAT_EQ(1.0f, vec[0]); EXPECT_FLOAT_EQ(1.0f, vec[1]); } { - auto vec = BasicVector2::createSingle(375.1721f); + auto vec = Vector2::createSingle(375.1721f); EXPECT_FLOAT_EQ(375.1721f, vec[0]); EXPECT_FLOAT_EQ(375.1721f, vec[1]); @@ -425,3 +425,84 @@ TEST(Vector2, memberFunctions) } /* ************************************************************************ */ + +TEST(Vector2, mutators) +{ + { + Vector2 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + vec.setX(100); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + vec.setY(50); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(50, vec.getY()); + } + + { + Vector2 vec; + + EXPECT_EQ(0, vec.x); + EXPECT_EQ(0, vec.y); + + vec.x = 100; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(0, vec.y); + + vec.y = 50; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + } +} + +/* ************************************************************************ */ + +TEST(Vector2, functions) +{ + { + Vector2 vec(1, 0); + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + auto rot = vec.rotated(unit::deg2rad(90)); + + EXPECT_EQ(0, rot.getX()); + EXPECT_EQ(1, rot.getY()); + } + + { + Vector2 vec(1, 0); + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + auto rot = vec.rotated(unit::deg2rad(-90)); + + EXPECT_EQ(0, rot.getX()); + EXPECT_EQ(-1, rot.getY()); + } + + { + Vector2 vec(1, 0); + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + auto rot = vec.rotated(unit::deg2rad(180)); + + EXPECT_EQ(-1, rot.getX()); + EXPECT_EQ(0, rot.getY()); + } + +} + +/* ************************************************************************ */ diff --git a/unittests/math/Vector3_test.cpp b/unittests/math/Vector3_test.cpp new file mode 100644 index 0000000..0e30b96 --- /dev/null +++ b/unittests/math/Vector3_test.cpp @@ -0,0 +1,473 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +// GTest +#include "gtest/gtest.h" + +// CeCe +#include "cece/math/Vector3.hpp" + +/* ************************************************************************ */ + +using namespace cece; +using namespace cece::math; + +/* ************************************************************************ */ + +TEST(Vector3, ctor) +{ + { + Vector3 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + + { + Vector3 vec(Zero); + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + + { + Vector3 vec = {1.2f, 3.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.2f, vec.getX()); + EXPECT_FLOAT_EQ(3.0f, vec.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec.getZ()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(-8.1f, vec[2]); + } + + { + const Vector3 vec1 = {1.2f, 3.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.2f, vec1.getX()); + EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2(vec1); + + EXPECT_FLOAT_EQ(1.2f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec2.getZ()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.1f, vec2[2]); + } + + { + Vector3 vec1 = {1.2f, 3.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.2f, vec1.getX()); + EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2(std::move(vec1)); + + EXPECT_FLOAT_EQ(1.2f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec2.getZ()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.1f, vec2[2]); + } + + { + const Vector3 vec1 = {1, 3, -8}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(-8, vec1.getZ()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2(vec1); + + EXPECT_FLOAT_EQ(1.0f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(-8.0f, vec2.getZ()); + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.0f, vec2[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, assignment) +{ + { + Vector3 vec{1, 1, 1}; + + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(1, vec[1]); + EXPECT_EQ(1, vec[2]); + + vec = Zero; + + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + + { + Vector3 vec; + + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + + vec = {1.2f, 3.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + EXPECT_FLOAT_EQ(-8.1f, vec[2]); + } + + { + const Vector3 vec1 = {1.2f, 3.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2; + + vec2 = vec1; + + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.1f, vec2[2]); + } + + { + Vector3 vec1 = {1.2f, 3.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2; + + vec2 = std::move(vec1); + + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.1f, vec2[2]); + } + + { + const Vector3 vec1 = {1, 3, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2; + + vec2 = vec1; + + EXPECT_FLOAT_EQ(1.0, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.0f, vec2[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, operators) +{ + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2 = +vec1; + + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(2.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.1f, vec2[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2 = -vec1; + + EXPECT_FLOAT_EQ(-1.0f, vec2[0]); + EXPECT_FLOAT_EQ(-2.0f, vec2[1]); + EXPECT_FLOAT_EQ(8.1f, vec2[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2{1.0f, 2.0f, -8.1f}; + vec1 += vec2; + + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + EXPECT_FLOAT_EQ(-16.2f, vec1[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2{1.0f, 2.0f, -8.1f}; + vec1 -= vec2; + + EXPECT_FLOAT_EQ(0.0f, vec1[0]); + EXPECT_FLOAT_EQ(0.0f, vec1[1]); + EXPECT_FLOAT_EQ(0.0f, vec1[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + vec1 *= 2.0; + + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + EXPECT_FLOAT_EQ(-16.2f, vec1[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2{1.0f, 2.0f, -8.1f}; + vec1 *= vec2; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f * -8.1f, vec1[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + vec1 /= 2.0; + + EXPECT_FLOAT_EQ(0.5f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + EXPECT_FLOAT_EQ(-4.05f, vec1[2]); + } + + { + Vector3 vec1{1.0f, 2.0f, -8.1f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + + Vector3 vec2{1.0f, 2.0f, -8.1f}; + vec1 /= vec2; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + EXPECT_FLOAT_EQ(1.0f, vec1[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, inRange) +{ + { + const Vector3 vecMin{-10.0f, -5.0f, -2.0f}; + const Vector3 vecMax{10.0f, 20.0f, 5.0f}; + + Vector3 vec1; + Vector3 vec2{-15.0f, 0.0f, 0.0f}; + Vector3 vec3{5.0f, 0.0f, 3.0f}; + + EXPECT_TRUE(vec1.inRange(vecMin, vecMax)); + EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); + EXPECT_TRUE(vec3.inRange(vecMin, vecMax)); + } + + { + const Vector3 vecMax{10.0f, 20.0f, 8.0f}; + + Vector3 vec1; + Vector3 vec2{-15.0f, 0.0f, 3.0f}; + Vector3 vec3{5.0f, 0.0f, 3.0f}; + + EXPECT_TRUE(vec1.inRange(vecMax)); + EXPECT_FALSE(vec2.inRange(vecMax)); + EXPECT_TRUE(vec3.inRange(vecMax)); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, memberFunctions) +{ + { + const Vector3 vec; + + EXPECT_FLOAT_EQ(0, vec.getLength()); + } + + { + const Vector3 vec{1.0f, 2.0f, 3.0f}; + + EXPECT_FLOAT_EQ(3.7416574f, vec.getLength()); + } + + { + const Vector3 vec; + + EXPECT_FLOAT_EQ(0, vec.getLengthSquared()); + } + + { + const Vector3 vec{1.0f, 2.0f, 3.0f}; + + EXPECT_FLOAT_EQ(14, vec.getLengthSquared()); + } + + { + const Vector3 vec; + + EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + } + + { + const Vector3 vec{1.0f, 2.0f, 3.0f}; + + EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + } + + { + const Vector3 vec1; + const Vector3 vec2; + + EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); + } + + { + const Vector3 vec1{1.0f, 2.0f, 3.0f}; + const Vector3 vec2{5.0f, 4.0f, 3.0f}; + + EXPECT_FLOAT_EQ(22, vec1.dot(vec2)); + } + + { + const Vector3 vec; + + EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + } + + { + const Vector3 vec{1.0f, 2.0f, 3.0f}; + + EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + } + + { + const Vector3 vec1{1.0f, 2.0f, 3.0f}; + const Vector3 vec2{5.0f, 4.0f, 3.0f}; + + EXPECT_FLOAT_EQ(20.0f, vec1.distanceSquared(vec2)); + } + + { + const Vector3 vec1{1.0f, 2.0f, 3.0f}; + const Vector3 vec2{5.0f, 4.0f, 3.0f}; + + EXPECT_FLOAT_EQ(4.4721360f, vec1.distance(vec2)); + } + + { + const Vector3 vec{1.0f, 2.0f, 3.0f}; + + auto inv = vec.inversed(); + + EXPECT_FLOAT_EQ(1.0f, inv[0]); + EXPECT_FLOAT_EQ(0.5f, inv[1]); + EXPECT_FLOAT_EQ(1.0f / 3.0f, inv[2]); + } + + { + auto vec = Vector3::createSingle(1); + + EXPECT_FLOAT_EQ(1.0f, vec[0]); + EXPECT_FLOAT_EQ(1.0f, vec[1]); + EXPECT_FLOAT_EQ(1.0f, vec[2]); + } + + { + auto vec = Vector3::createSingle(375.1721f); + + EXPECT_FLOAT_EQ(375.1721f, vec[0]); + EXPECT_FLOAT_EQ(375.1721f, vec[1]); + } +} + +/* ************************************************************************ */ From b643b82bbcb6fa53c9101908adad7b7807c9d3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Thu, 9 Mar 2017 17:45:19 +0100 Subject: [PATCH 04/11] Removed and added some operators from Vector2. --- include/cece/math/Vector2.hpp | 161 +++++++------------------------- unittests/math/Vector2_test.cpp | 147 +++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 128 deletions(-) diff --git a/include/cece/math/Vector2.hpp b/include/cece/math/Vector2.hpp index 32f8970..2de646d 100644 --- a/include/cece/math/Vector2.hpp +++ b/include/cece/math/Vector2.hpp @@ -495,45 +495,11 @@ extern template class Vector2; * @return Result vector. */ template -inline Vector2() + std::declval())> +Vector2() + std::declval())> operator+(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -inline Vector2() + std::declval())> -operator+(const Vector2& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Addition operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -inline Vector2() + std::declval())> -operator+(T1 lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Substract operator. * @@ -546,45 +512,11 @@ operator+(T1 lhs, const Vector2& rhs) noexcept; * @return Result vector. */ template -inline Vector2() - std::declval())> +Vector2() - std::declval())> operator-(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -inline Vector2() - std::declval())> -operator-(const Vector2& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Substract operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -inline Vector2() - std::declval())> -operator-(T1 lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -597,7 +529,7 @@ operator-(T1 lhs, const Vector2& rhs) noexcept; * @return Result vector. */ template -inline Vector2() * std::declval())> +Vector2() * std::declval())> operator*(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -614,7 +546,7 @@ operator*(const Vector2& lhs, const Vector2& rhs) noexcept; * @return Result vector. */ template -inline Vector2() * std::declval())> +Vector2() * std::declval())> operator*(const Vector2& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -631,7 +563,7 @@ operator*(const Vector2& lhs, T2 rhs) noexcept; * @return Result vector. */ template -inline Vector2() * std::declval())> +Vector2() * std::declval())> operator*(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -648,7 +580,7 @@ operator*(T1 lhs, const Vector2& rhs) noexcept; * @return Result vector. */ template -inline Vector2() / std::declval())> +Vector2() / std::declval())> operator/(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -665,7 +597,7 @@ operator/(const Vector2& lhs, const Vector2& rhs) noexcept; * @return Result vector. */ template -inline Vector2() / std::declval())> +Vector2() / std::declval())> operator/(const Vector2& lhs, T2 rhs) noexcept; /* ************************************************************************ */ @@ -682,7 +614,7 @@ operator/(const Vector2& lhs, T2 rhs) noexcept; * @return Result vector. */ template -inline Vector2() / std::declval())> +Vector2() / std::declval())> operator/(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -699,7 +631,23 @@ operator/(T1 lhs, const Vector2& rhs) noexcept; * @return Comparision result. */ template -inline bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept; +bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Comparision result. + */ +template +bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -715,7 +663,6 @@ inline bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept; * @return Cross product. */ template -inline decltype(std::declval() * std::declval()) cross(const Vector2& lhs, const Vector2& rhs) noexcept; @@ -733,7 +680,6 @@ cross(const Vector2& lhs, const Vector2& rhs) noexcept; * @return Cross product. */ template -inline Vector2() * std::declval())> cross(const Vector2& lhs, const T2& rhs) noexcept; @@ -751,7 +697,6 @@ cross(const Vector2& lhs, const T2& rhs) noexcept; * @return Cross product. */ template -inline Vector2() * std::declval())> cross(const T1& lhs, const Vector2& rhs) noexcept; @@ -1155,30 +1100,6 @@ operator+(const Vector2& lhs, const Vector2& rhs) noexcept /* ************************************************************************ */ -template -inline Vector2() + std::declval())> -operator+(const Vector2& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() + rhs, - lhs.getY() + rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() + std::declval())> -operator+(T1 lhs, const Vector2& rhs) noexcept -{ - return { - lhs + rhs.getX(), - lhs + rhs.getY() - }; -} - -/* ************************************************************************ */ - template inline Vector2() - std::declval())> operator-(const Vector2& lhs, const Vector2& rhs) noexcept @@ -1191,30 +1112,6 @@ operator-(const Vector2& lhs, const Vector2& rhs) noexcept /* ************************************************************************ */ -template -inline Vector2() - std::declval())> -operator-(const Vector2& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() - rhs, - lhs.getY() - rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() - std::declval())> -operator-(T1 lhs, const Vector2& rhs) noexcept -{ - return { - lhs - rhs.getX(), - lhs - rhs.getY() - }; -} - -/* ************************************************************************ */ - template inline Vector2() * std::declval())> operator*(const Vector2& lhs, const Vector2& rhs) noexcept @@ -1298,6 +1195,14 @@ inline bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept /* ************************************************************************ */ +template +inline bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept +{ + return !operator==(lhs, rhs); +} + +/* ************************************************************************ */ + template inline decltype(std::declval() * std::declval()) diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp index 9b45d9b..0d958cb 100644 --- a/unittests/math/Vector2_test.cpp +++ b/unittests/math/Vector2_test.cpp @@ -503,6 +503,153 @@ TEST(Vector2, functions) EXPECT_EQ(0, rot.getY()); } + + // TODO: cross, dot +} + +/* ************************************************************************ */ + +TEST(Vector2, freeOperators) +{ + { + const Vector2 vec1(5.3f, 8.9f); + const Vector2 vec2(3.3f, 1.2f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + + const auto vec3 = vec1 + vec2; + const auto vec4 = vec2 + vec1; + + EXPECT_FLOAT_EQ(5.3f + 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f + 1.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.3f + 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f + 8.9f, vec4.getY()); + } + + { + const Vector2 vec1(5.3f, 8.9f); + const Vector2 vec2(3.3f, 1.2f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + + const auto vec3 = vec1 - vec2; + const auto vec4 = vec2 - vec1; + + EXPECT_FLOAT_EQ(5.3f - 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f - 1.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.3f - 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f - 8.9f, vec4.getY()); + } + + { + const Vector2 vec1(5.3f, 8.9f); + const Vector2 vec2(3.3f, 1.2f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + + const auto vec3 = vec1 * vec2; + const auto vec4 = vec2 * vec1; + + EXPECT_FLOAT_EQ(5.3f * 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f * 1.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.3f * 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f * 8.9f, vec4.getY()); + } + + { + const Vector2 vec1(5.3f, 8.9f); + const Vector2 vec2(3.3f, 1.2f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + + const auto vec3 = vec1 / vec2; + const auto vec4 = vec2 / vec1; + + EXPECT_FLOAT_EQ(5.3f / 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f / 1.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.3f / 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f / 8.9f, vec4.getY()); + } + + { + const Vector2 vec1(5.3f, 8.9f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + const auto vec3 = vec1 * 3.2f; + const auto vec4 = 3.2f * vec1; + + EXPECT_FLOAT_EQ(5.3f * 3.2f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f * 3.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.2f * 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.2f * 8.9f, vec4.getY()); + } + + { + const Vector2 vec1(5.3f, 8.9f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + const auto vec3 = vec1 / 3.2f; + const auto vec4 = 3.2f / vec1; + + EXPECT_FLOAT_EQ(5.3f / 3.2f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f / 3.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.2f / 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.2f / 8.9f, vec4.getY()); + } + + { + const Vector2 vec1(5.3f, 8.9f); + const Vector2 vec2(5.3f, 8.9f); + const Vector2 vec3(1.3f, 8.9f); + const Vector2 vec4(5.3f, 0.9f); + + EXPECT_EQ(vec1, vec1); + EXPECT_EQ(vec1, vec2); + EXPECT_NE(vec1, vec3); + EXPECT_NE(vec1, vec4); + + EXPECT_EQ(vec2, vec1); + EXPECT_EQ(vec2, vec2); + EXPECT_NE(vec2, vec3); + EXPECT_NE(vec2, vec4); + + EXPECT_NE(vec3, vec1); + EXPECT_NE(vec3, vec2); + EXPECT_EQ(vec3, vec3); + EXPECT_NE(vec3, vec4); + + EXPECT_NE(vec4, vec1); + EXPECT_NE(vec4, vec2); + EXPECT_NE(vec4, vec3); + EXPECT_EQ(vec4, vec4); + } + } /* ************************************************************************ */ From 97b0a25bc5bb484f8444d625a73d0088bf6ee007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Fri, 17 Mar 2017 17:25:58 +0100 Subject: [PATCH 05/11] The math::Vector3 coverage improvement. --- include/cece/math/Vector3.hpp | 389 ++++++----------- unittests/math/CMakeLists.txt | 2 +- unittests/math/Vector3_test.cpp | 753 +++++++++++++++++++++++++++++--- 3 files changed, 828 insertions(+), 316 deletions(-) diff --git a/include/cece/math/Vector3.hpp b/include/cece/math/Vector3.hpp index 93bce5d..699fdf1 100644 --- a/include/cece/math/Vector3.hpp +++ b/include/cece/math/Vector3.hpp @@ -66,6 +66,20 @@ class Vector3 using ValueTypeSq = decltype(std::declval() * std::declval()); +// Public Data Members +public: + + + /// X coordinate. + T x; + + /// Y coordinate. + T y; + + /// Z coordinate. + T z; + + // Public Ctors public: @@ -316,14 +330,6 @@ class Vector3 public: - /** - * @brief Returns X coordinate. - * - * @return Reference to X coordinate. - */ - T& x() noexcept; - - /** * @brief Returns X coordinate. * @@ -340,14 +346,6 @@ class Vector3 void setX(T x) noexcept; - /** - * @brief Returns Y coordinate. - * - * @return Referent co Y coordinate. - */ - T& y() noexcept; - - /** * @brief Returns Y coordinate. * @@ -364,14 +362,6 @@ class Vector3 void setY(T y) noexcept; - /** - * @brief Returns Z coordinate. - * - * @return Referent co Z coordinate. - */ - T& z() noexcept; - - /** * @brief Returns Z coordinate. * @@ -442,16 +432,6 @@ class Vector3 ValueTypeSq getLengthSquared() const noexcept; - /** - * @brief Calculate dot of two vectors. - * - * @param rhs Second vector. - * - * @return Dot product. - */ - ValueTypeSq dot(const Vector3& rhs) const noexcept; - - /** * @brief Calculate vectors squared distance. * @@ -502,19 +482,6 @@ class Vector3 */ static Vector3 createSingle(T val) noexcept; - -// Private Data Members -private: - - /// X coordinate. - T m_x; - - /// Y coordinate. - T m_y; - - /// Z coordinate. - T m_z; - }; /* ************************************************************************ */ @@ -543,40 +510,6 @@ operator+(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -inline Vector3() + std::declval())> -operator+(const Vector3& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Addition operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() + std::declval())> -operator+(T1 lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Substract operator. * @@ -594,40 +527,6 @@ operator-(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -inline Vector3() - std::declval())> -operator-(const Vector3& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Substract operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() - std::declval())> -operator-(T1 lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -746,6 +645,22 @@ inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ +/** + * @brief Compare vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Comparision result. + */ +template +bool operator!=(const Vector3& lhs, const Vector3& rhs) noexcept; + +/* ************************************************************************ */ + /** * @brief Calculate cross product of two vectors. * @@ -758,12 +673,28 @@ inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept; * @return Cross product. */ template -inline Vector3() * std::declval())> cross(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ +/** + * @brief Calculate dot product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Dot product. + */ +template +decltype(std::declval() * std::declval()) +dot(const Vector3& lhs, const Vector3& rhs) noexcept; + +/* ************************************************************************ */ + } } @@ -778,9 +709,9 @@ namespace math { template inline Vector3::Vector3() noexcept - : m_x{} - , m_y{} - , m_z{} + : x{} + , y{} + , z{} { // Nothing to do } @@ -789,9 +720,9 @@ inline Vector3::Vector3() noexcept template inline Vector3::Vector3(T x, T y, T z) noexcept - : m_x(x) - , m_y(y) - , m_z(z) + : x(x) + , y(y) + , z(z) { // Nothing to do } @@ -800,9 +731,9 @@ inline Vector3::Vector3(T x, T y, T z) noexcept template inline Vector3::Vector3(Zero_t zero) noexcept - : m_x{} - , m_y{} - , m_z{} + : x{} + , y{} + , z{} { // Nothing to do } @@ -811,9 +742,9 @@ inline Vector3::Vector3(Zero_t zero) noexcept template inline Vector3::Vector3(const Vector3& src) noexcept - : m_x{src.getX()} - , m_y{src.getY()} - , m_z{src.getZ()} + : x{src.getX()} + , y{src.getY()} + , z{src.getZ()} { // Nothing to do } @@ -822,9 +753,9 @@ inline Vector3::Vector3(const Vector3& src) noexcept template inline Vector3::Vector3(Vector3&& src) noexcept - : m_x{std::move(src.m_x)} - , m_y{std::move(src.m_y)} - , m_z{std::move(src.m_z)} + : x{std::move(src.x)} + , y{std::move(src.y)} + , z{std::move(src.z)} { // Nothing to do } @@ -834,9 +765,9 @@ inline Vector3::Vector3(Vector3&& src) noexcept template template::value>::type*> inline Vector3::Vector3(const Vector3& rhs) noexcept - : m_x(rhs.getX()) - , m_y(rhs.getY()) - , m_z(rhs.getZ()) + : x(rhs.getX()) + , y(rhs.getY()) + , z(rhs.getZ()) { // Nothing to do } @@ -846,9 +777,9 @@ inline Vector3::Vector3(const Vector3& rhs) noexcept template inline Vector3& Vector3::operator=(Zero_t zero) noexcept { - m_x = T{}; - m_y = T{}; - m_z = T{}; + x = T{}; + y = T{}; + z = T{}; return *this; } @@ -858,9 +789,9 @@ inline Vector3& Vector3::operator=(Zero_t zero) noexcept template inline Vector3& Vector3::operator=(const Vector3& src) noexcept { - m_x = src.m_x; - m_y = src.m_y; - m_z = src.m_z; + x = src.x; + y = src.y; + z = src.z; return *this; } @@ -870,9 +801,9 @@ inline Vector3& Vector3::operator=(const Vector3& src) noexcept template inline Vector3& Vector3::operator=(Vector3&& src) noexcept { - m_x = std::move(src.m_x); - m_y = std::move(src.m_y); - m_z = std::move(src.m_z); + x = std::move(src.x); + y = std::move(src.y); + z = std::move(src.z); return *this; } @@ -883,9 +814,9 @@ template template::value>::type*> inline Vector3& Vector3::operator=(const Vector3& src) noexcept { - m_x = T(src.getX()); - m_y = T(src.getY()); - m_z = T(src.getZ()); + x = T(src.getX()); + y = T(src.getY()); + z = T(src.getZ()); return *this; } @@ -903,7 +834,7 @@ inline Vector3 Vector3::operator+() const noexcept template inline Vector3 Vector3::operator-() const noexcept { - return {-m_x, -m_y, -m_z}; + return {-x, -y, -z}; } /* ************************************************************************ */ @@ -915,9 +846,9 @@ template::value>::type*> inline Vector3& Vector3::operator+=(const Vector3& rhs) noexcept { - m_x += rhs.getX(); - m_y += rhs.getY(); - m_z += rhs.getZ(); + x += rhs.getX(); + y += rhs.getY(); + z += rhs.getZ(); return *this; } @@ -931,9 +862,9 @@ template::value>::type*> inline Vector3& Vector3::operator-=(const Vector3& rhs) noexcept { - m_x -= rhs.getX(); - m_y -= rhs.getY(); - m_z -= rhs.getZ(); + x -= rhs.getX(); + y -= rhs.getY(); + z -= rhs.getZ(); return *this; } @@ -950,9 +881,9 @@ template::value>::type*> inline Vector3& Vector3::operator*=(T1 rhs) noexcept { - m_x *= rhs; - m_y *= rhs; - m_z *= rhs; + x *= rhs; + y *= rhs; + z *= rhs; return *this; } @@ -969,9 +900,9 @@ template::value>::type*> inline Vector3& Vector3::operator*=(const Vector3& rhs) noexcept { - m_x *= rhs.getX(); - m_y *= rhs.getY(); - m_z *= rhs.getZ(); + x *= rhs.getX(); + y *= rhs.getY(); + z *= rhs.getZ(); return *this; } @@ -988,9 +919,9 @@ template::value>::type*> inline Vector3& Vector3::operator/=(T1 rhs) noexcept { - m_x /= rhs; - m_y /= rhs; - m_z /= rhs; + x /= rhs; + y /= rhs; + z /= rhs; return *this; } @@ -1007,9 +938,9 @@ template::value>::type*> inline Vector3& Vector3::operator/=(const Vector3& rhs) noexcept { - m_x /= rhs.getX(); - m_y /= rhs.getY(); - m_z /= rhs.getZ(); + x /= rhs.getX(); + y /= rhs.getY(); + z /= rhs.getZ(); return *this; } @@ -1021,7 +952,7 @@ inline T& Vector3::operator[](int pos) noexcept { CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 3); - return (&m_x)[pos]; + return (&x)[pos]; } /* ************************************************************************ */ @@ -1031,15 +962,7 @@ inline const T& Vector3::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 3); - return (&m_x)[pos]; -} - -/* ************************************************************************ */ - -template -inline T& Vector3::x() noexcept -{ - return m_x; + return (&x)[pos]; } /* ************************************************************************ */ @@ -1047,7 +970,7 @@ inline T& Vector3::x() noexcept template inline const T& Vector3::getX() const noexcept { - return m_x; + return x; } /* ************************************************************************ */ @@ -1055,15 +978,7 @@ inline const T& Vector3::getX() const noexcept template inline void Vector3::setX(T x) noexcept { - m_x = std::move(x); -} - -/* ************************************************************************ */ - -template -inline T& Vector3::y() noexcept -{ - return m_y; + this->x = std::move(x); } /* ************************************************************************ */ @@ -1071,7 +986,7 @@ inline T& Vector3::y() noexcept template inline const T& Vector3::getY() const noexcept { - return m_y; + return y; } /* ************************************************************************ */ @@ -1079,15 +994,7 @@ inline const T& Vector3::getY() const noexcept template inline void Vector3::setY(T y) noexcept { - m_y = std::move(y); -} - -/* ************************************************************************ */ - -template -inline T& Vector3::z() noexcept -{ - return m_z; + this->y = std::move(y); } /* ************************************************************************ */ @@ -1095,7 +1002,7 @@ inline T& Vector3::z() noexcept template inline const T& Vector3::getZ() const noexcept { - return m_z; + return z; } /* ************************************************************************ */ @@ -1103,7 +1010,7 @@ inline const T& Vector3::getZ() const noexcept template inline void Vector3::setZ(T z) noexcept { - m_z = std::move(z); + this->z = std::move(z); } /* ************************************************************************ */ @@ -1149,19 +1056,11 @@ inline typename Vector3::ValueType Vector3::getLength() const noexcept template inline typename Vector3::ValueTypeSq Vector3::getLengthSquared() const noexcept -{ - return dot(*this); -} - -/* ************************************************************************ */ - -template -inline typename Vector3::ValueTypeSq Vector3::dot(const Vector3& rhs) const noexcept { return - getX() * rhs.getX() + - getY() * rhs.getY() + - getZ() * rhs.getZ() + getX() * getX() + + getY() * getY() + + getZ() * getZ() ; } @@ -1217,32 +1116,6 @@ operator+(const Vector3& lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ -template -inline Vector3() + std::declval())> -operator+(const Vector3& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() + rhs, - lhs.getY() + rhs, - lhs.getZ() + rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector3() + std::declval())> -operator+(T1 lhs, const Vector3& rhs) noexcept -{ - return { - lhs + rhs.getX(), - lhs + rhs.getY(), - lhs + rhs.getZ() - }; -} - -/* ************************************************************************ */ - template inline Vector3() - std::declval())> operator-(const Vector3& lhs, const Vector3& rhs) noexcept @@ -1256,32 +1129,6 @@ operator-(const Vector3& lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ -template -inline Vector3() - std::declval())> -operator-(const Vector3& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() - rhs, - lhs.getY() - rhs, - lhs.getZ() - rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector3() - std::declval())> -operator-(T1 lhs, const Vector3& rhs) noexcept -{ - return { - lhs - rhs.getX(), - lhs - rhs.getY(), - lhs - rhs.getZ() - }; -} - -/* ************************************************************************ */ - template inline Vector3() * std::declval())> operator*(const Vector3& lhs, const Vector3& rhs) noexcept @@ -1372,6 +1219,14 @@ inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ +template +inline bool operator!=(const Vector3& lhs, const Vector3& rhs) noexcept +{ + return !operator==(lhs, rhs); +} + +/* ************************************************************************ */ + template inline Vector3() * std::declval())> @@ -1386,6 +1241,20 @@ cross(const Vector3& lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ +template +inline +decltype(std::declval() * std::declval()) +dot(const Vector3& lhs, const Vector3& rhs) noexcept +{ + return { + lhs.getX() * rhs.getX() + + lhs.getY() * rhs.getY() + + lhs.getZ() * rhs.getZ() + }; +} + +/* ************************************************************************ */ + } } diff --git a/unittests/math/CMakeLists.txt b/unittests/math/CMakeLists.txt index d5a5575..4893905 100644 --- a/unittests/math/CMakeLists.txt +++ b/unittests/math/CMakeLists.txt @@ -23,7 +23,7 @@ # # # ######################################################################### # -cece_add_test(core +cece_add_test(math SOURCES Vector_test.cpp Vector2_test.cpp diff --git a/unittests/math/Vector3_test.cpp b/unittests/math/Vector3_test.cpp index 0e30b96..e300661 100644 --- a/unittests/math/Vector3_test.cpp +++ b/unittests/math/Vector3_test.cpp @@ -36,7 +36,7 @@ using namespace cece::math; /* ************************************************************************ */ -TEST(Vector3, ctor) +TEST(Vector3, ctorDefault) { { Vector3 vec; @@ -49,6 +49,44 @@ TEST(Vector3, ctor) EXPECT_EQ(0, vec[2]); } + { + Vector3 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + + { + Vector3 vec; + + EXPECT_FLOAT_EQ(0.0f, vec.getX()); + EXPECT_FLOAT_EQ(0.0f, vec.getY()); + EXPECT_FLOAT_EQ(0.0f, vec.getZ()); + EXPECT_FLOAT_EQ(0.0f, vec[0]); + EXPECT_FLOAT_EQ(0.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + } + + { + Vector3 vec; + + EXPECT_DOUBLE_EQ(0.0, vec.getX()); + EXPECT_DOUBLE_EQ(0.0, vec.getY()); + EXPECT_DOUBLE_EQ(0.0, vec.getZ()); + EXPECT_DOUBLE_EQ(0.0, vec[0]); + EXPECT_DOUBLE_EQ(0.0, vec[1]); + EXPECT_DOUBLE_EQ(0.0, vec[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, ctorZero) +{ { Vector3 vec(Zero); @@ -60,6 +98,66 @@ TEST(Vector3, ctor) EXPECT_EQ(0, vec[2]); } + { + Vector3 vec(Zero); + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + + { + Vector3 vec(Zero); + + EXPECT_FLOAT_EQ(0.0f, vec.getX()); + EXPECT_FLOAT_EQ(0.0f, vec.getY()); + EXPECT_FLOAT_EQ(0.0f, vec.getZ()); + EXPECT_FLOAT_EQ(0.0f, vec[0]); + EXPECT_FLOAT_EQ(0.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + } + + { + Vector3 vec(Zero); + + EXPECT_DOUBLE_EQ(0.0, vec.getX()); + EXPECT_DOUBLE_EQ(0.0, vec.getY()); + EXPECT_DOUBLE_EQ(0.0, vec.getZ()); + EXPECT_DOUBLE_EQ(0.0, vec[0]); + EXPECT_DOUBLE_EQ(0.0, vec[1]); + EXPECT_DOUBLE_EQ(0.0, vec[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, ctorElements) +{ + { + Vector3 vec = {1, 3, -8}; + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(3, vec.getY()); + EXPECT_EQ(-8, vec.getZ()); + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(3, vec[1]); + EXPECT_EQ(-8, vec[2]); + } + + { + Vector3 vec = {1, 3, 8}; + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(3, vec.getY()); + EXPECT_EQ(8, vec.getZ()); + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(3, vec[1]); + EXPECT_EQ(8, vec[2]); + } + { Vector3 vec = {1.2f, 3.0f, -8.1f}; @@ -71,6 +169,62 @@ TEST(Vector3, ctor) EXPECT_FLOAT_EQ(-8.1f, vec[2]); } + { + Vector3 vec = {1.2, 3.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.2, vec.getX()); + EXPECT_DOUBLE_EQ(3.0, vec.getY()); + EXPECT_DOUBLE_EQ(-8.1, vec.getZ()); + EXPECT_DOUBLE_EQ(1.2, vec[0]); + EXPECT_DOUBLE_EQ(3.0, vec[1]); + EXPECT_DOUBLE_EQ(-8.1, vec[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, ctorCopy) +{ + { + const Vector3 vec1 = {1, 3, -8}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(-8, vec1.getZ()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2(vec1); + + EXPECT_FLOAT_EQ(1.0f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(-8.0f, vec2.getZ()); + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.0f, vec2[2]); + } + + { + const Vector3 vec1 = {1, 3, 8}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(8, vec1.getZ()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2(vec1); + + EXPECT_EQ(1, vec2.getX()); + EXPECT_EQ(3, vec2.getY()); + EXPECT_EQ(8, vec2.getZ()); + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(3, vec2[1]); + EXPECT_EQ(8, vec2[2]); + } + { const Vector3 vec1 = {1.2f, 3.0f, -8.1f}; @@ -91,6 +245,72 @@ TEST(Vector3, ctor) EXPECT_FLOAT_EQ(-8.1f, vec2[2]); } + { + const Vector3 vec1 = {1.2, 3.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.2, vec1.getX()); + EXPECT_DOUBLE_EQ(3.0, vec1.getY()); + EXPECT_DOUBLE_EQ(-8.1, vec1.getZ()); + EXPECT_DOUBLE_EQ(1.2, vec1[0]); + EXPECT_DOUBLE_EQ(3.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2(vec1); + + EXPECT_DOUBLE_EQ(1.2, vec2.getX()); + EXPECT_DOUBLE_EQ(3.0, vec2.getY()); + EXPECT_DOUBLE_EQ(-8.1, vec2.getZ()); + EXPECT_DOUBLE_EQ(1.2, vec2[0]); + EXPECT_DOUBLE_EQ(3.0, vec2[1]); + EXPECT_DOUBLE_EQ(-8.1, vec2[2]); + } + +} + +/* ************************************************************************ */ + +TEST(Vector3, ctorMove) +{ + { + Vector3 vec1 = {1, 3, -8}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(-8, vec1.getZ()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2(std::move(vec1)); + + EXPECT_EQ(1, vec2.getX()); + EXPECT_EQ(3, vec2.getY()); + EXPECT_EQ(-8, vec2.getZ()); + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(3, vec2[1]); + EXPECT_EQ(-8, vec2[2]); + } + + { + Vector3 vec1 = {1, 3, 8}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(8, vec1.getZ()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2(std::move(vec1)); + + EXPECT_EQ(1, vec2.getX()); + EXPECT_EQ(3, vec2.getY()); + EXPECT_EQ(8, vec2.getZ()); + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(3, vec2[1]); + EXPECT_EQ(8, vec2[2]); + } + { Vector3 vec1 = {1.2f, 3.0f, -8.1f}; @@ -112,29 +332,29 @@ TEST(Vector3, ctor) } { - const Vector3 vec1 = {1, 3, -8}; - - EXPECT_EQ(1, vec1.getX()); - EXPECT_EQ(3, vec1.getY()); - EXPECT_EQ(-8, vec1.getZ()); - EXPECT_EQ(1, vec1[0]); - EXPECT_EQ(3, vec1[1]); - EXPECT_EQ(-8, vec1[2]); - - Vector3 vec2(vec1); - - EXPECT_FLOAT_EQ(1.0f, vec2.getX()); - EXPECT_FLOAT_EQ(3.0f, vec2.getY()); - EXPECT_FLOAT_EQ(-8.0f, vec2.getZ()); - EXPECT_FLOAT_EQ(1.0f, vec2[0]); - EXPECT_FLOAT_EQ(3.0f, vec2[1]); - EXPECT_FLOAT_EQ(-8.0f, vec2[2]); + Vector3 vec1 = {1.2, 3.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.2, vec1.getX()); + EXPECT_DOUBLE_EQ(3.0, vec1.getY()); + EXPECT_DOUBLE_EQ(-8.1, vec1.getZ()); + EXPECT_DOUBLE_EQ(1.2, vec1[0]); + EXPECT_DOUBLE_EQ(3.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2(std::move(vec1)); + + EXPECT_DOUBLE_EQ(1.2, vec2.getX()); + EXPECT_DOUBLE_EQ(3.0, vec2.getY()); + EXPECT_DOUBLE_EQ(-8.1, vec2.getZ()); + EXPECT_DOUBLE_EQ(1.2, vec2[0]); + EXPECT_DOUBLE_EQ(3.0, vec2[1]); + EXPECT_DOUBLE_EQ(-8.1, vec2[2]); } } /* ************************************************************************ */ -TEST(Vector3, assignment) +TEST(Vector3, assignmentZero) { { Vector3 vec{1, 1, 1}; @@ -151,12 +371,87 @@ TEST(Vector3, assignment) } { - Vector3 vec; + Vector3 vec{1, 1, 1}; + + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(1, vec[1]); + EXPECT_EQ(1, vec[2]); + + vec = Zero; + + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + + { + Vector3 vec{1.0f, 1.0f, 1.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec[0]); + EXPECT_FLOAT_EQ(1.0f, vec[1]); + EXPECT_FLOAT_EQ(1.0f, vec[2]); + + vec = Zero; + + EXPECT_FLOAT_EQ(0.0f, vec[0]); + EXPECT_FLOAT_EQ(0.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + } + + { + Vector3 vec{1.0, 1.0, 1.0}; + + EXPECT_DOUBLE_EQ(1.0, vec[0]); + EXPECT_DOUBLE_EQ(1.0, vec[1]); + EXPECT_DOUBLE_EQ(1.0, vec[2]); + + vec = Zero; + + EXPECT_DOUBLE_EQ(0.0, vec[0]); + EXPECT_DOUBLE_EQ(0.0, vec[1]); + EXPECT_DOUBLE_EQ(0.0, vec[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, assignmentElements) +{ + { + Vector3 vec; + + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + + vec = {1, 3, -8}; + + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(3, vec[1]); + EXPECT_EQ(-8, vec[2]); + } + + { + Vector3 vec; EXPECT_EQ(0, vec[0]); EXPECT_EQ(0, vec[1]); EXPECT_EQ(0, vec[2]); + vec = {1, 3, 8}; + + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(3, vec[1]); + EXPECT_EQ(8, vec[2]); + } + + { + Vector3 vec; + + EXPECT_FLOAT_EQ(0.0f, vec[0]); + EXPECT_FLOAT_EQ(0.0f, vec[1]); + EXPECT_FLOAT_EQ(0.0f, vec[2]); + vec = {1.2f, 3.0f, -8.1f}; EXPECT_FLOAT_EQ(1.2f, vec[0]); @@ -164,6 +459,57 @@ TEST(Vector3, assignment) EXPECT_FLOAT_EQ(-8.1f, vec[2]); } + { + Vector3 vec; + + EXPECT_DOUBLE_EQ(0.0, vec[0]); + EXPECT_DOUBLE_EQ(0.0, vec[1]); + EXPECT_DOUBLE_EQ(0.0, vec[2]); + + vec = {1.2, 3.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.2, vec[0]); + EXPECT_DOUBLE_EQ(3.0, vec[1]); + EXPECT_DOUBLE_EQ(-8.1, vec[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, assignmentCopy) +{ + { + const Vector3 vec1 = {1, 3, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2; + + vec2 = vec1; + + EXPECT_FLOAT_EQ(1.0, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + EXPECT_FLOAT_EQ(-8.0f, vec2[2]); + } + + { + const Vector3 vec1 = {1, 3, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2; + + vec2 = vec1; + + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(3, vec2[1]); + EXPECT_EQ(8, vec2[2]); + } + { const Vector3 vec1 = {1.2f, 3.0f, -8.1f}; @@ -180,6 +526,59 @@ TEST(Vector3, assignment) EXPECT_FLOAT_EQ(-8.1f, vec2[2]); } + { + const Vector3 vec1 = {1.2, 3.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.2, vec1[0]); + EXPECT_DOUBLE_EQ(3.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2; + + vec2 = vec1; + + EXPECT_DOUBLE_EQ(1.2, vec2[0]); + EXPECT_DOUBLE_EQ(3.0, vec2[1]); + EXPECT_DOUBLE_EQ(-8.1, vec2[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, assignmentMove) +{ + { + Vector3 vec1 = {1, 3, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2; + + vec2 = std::move(vec1); + + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(3, vec2[1]); + EXPECT_EQ(-8, vec2[2]); + } + + { + Vector3 vec1 = {1, 3, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2; + + vec2 = std::move(vec1); + + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(3, vec2[1]); + EXPECT_EQ(8, vec2[2]); + } + { Vector3 vec1 = {1.2f, 3.0f, -8.1f}; @@ -197,19 +596,19 @@ TEST(Vector3, assignment) } { - const Vector3 vec1 = {1, 3, -8}; + Vector3 vec1 = {1.2, 3.0, -8.1}; - EXPECT_EQ(1, vec1[0]); - EXPECT_EQ(3, vec1[1]); - EXPECT_EQ(-8, vec1[2]); + EXPECT_DOUBLE_EQ(1.2, vec1[0]); + EXPECT_DOUBLE_EQ(3.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); - Vector3 vec2; + Vector3 vec2; - vec2 = vec1; + vec2 = std::move(vec1); - EXPECT_FLOAT_EQ(1.0, vec2[0]); - EXPECT_FLOAT_EQ(3.0f, vec2[1]); - EXPECT_FLOAT_EQ(-8.0f, vec2[2]); + EXPECT_DOUBLE_EQ(1.2, vec2[0]); + EXPECT_DOUBLE_EQ(3.0, vec2[1]); + EXPECT_DOUBLE_EQ(-8.1, vec2[2]); } } @@ -392,32 +791,6 @@ TEST(Vector3, memberFunctions) EXPECT_FLOAT_EQ(14, vec.getLengthSquared()); } - { - const Vector3 vec; - - EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); - } - - { - const Vector3 vec{1.0f, 2.0f, 3.0f}; - - EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); - } - - { - const Vector3 vec1; - const Vector3 vec2; - - EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); - } - - { - const Vector3 vec1{1.0f, 2.0f, 3.0f}; - const Vector3 vec2{5.0f, 4.0f, 3.0f}; - - EXPECT_FLOAT_EQ(22, vec1.dot(vec2)); - } - { const Vector3 vec; @@ -471,3 +844,273 @@ TEST(Vector3, memberFunctions) } /* ************************************************************************ */ + +TEST(Vector3, mutators) +{ + { + Vector3 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + + vec.setX(100); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + + vec.setY(50); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(50, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + + vec.setZ(10); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(50, vec.getY()); + EXPECT_EQ(10, vec.getZ()); + } + + { + Vector3 vec; + + EXPECT_EQ(0, vec.x); + EXPECT_EQ(0, vec.y); + EXPECT_EQ(0, vec.z); + + vec.x = 100; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(0, vec.y); + EXPECT_EQ(0, vec.z); + + vec.y = 50; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + EXPECT_EQ(0, vec.z); + + vec.z = 10; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + EXPECT_EQ(10, vec.z); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, functions) +{ + { + Vector3 vec1(0.94333f, 0.73733f, 0.92636f); + Vector3 vec2(0.16110f, 0.61872f, 0.21556f); + + EXPECT_FLOAT_EQ(0.94333f, vec1.getX()); + EXPECT_FLOAT_EQ(0.73733f, vec1.getY()); + EXPECT_FLOAT_EQ(0.92636f, vec1.getZ()); + + EXPECT_FLOAT_EQ(0.16110f, vec2.getX()); + EXPECT_FLOAT_EQ(0.61872f, vec2.getY()); + EXPECT_FLOAT_EQ(0.21556f, vec2.getZ()); + + auto vec3 = cross(vec1, vec2); + + EXPECT_FLOAT_EQ(0.73733f * 0.21556f - 0.92636f * 0.61872f, vec3.getX()); + EXPECT_FLOAT_EQ(0.92636f * 0.16110f - 0.94333f * 0.21556f, vec3.getY()); + EXPECT_FLOAT_EQ(0.94333f * 0.61872f - 0.73733f * 0.16110f, vec3.getZ()); + } + + { + Vector3 vec1(0.94333f, 0.73733f, 0.92636f); + Vector3 vec2(0.16110f, 0.61872f, 0.21556f); + + EXPECT_FLOAT_EQ(0.94333f, vec1.getX()); + EXPECT_FLOAT_EQ(0.73733f, vec1.getY()); + EXPECT_FLOAT_EQ(0.92636f, vec1.getZ()); + + EXPECT_FLOAT_EQ(0.16110f, vec2.getX()); + EXPECT_FLOAT_EQ(0.61872f, vec2.getY()); + EXPECT_FLOAT_EQ(0.21556f, vec2.getZ()); + + auto res = dot(vec1, vec2); + + EXPECT_FLOAT_EQ( + 0.94333f * 0.16110f + + 0.73733f * 0.61872f + + 0.92636f * 0.21556f, + res + ); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, freeOperators) +{ + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + const Vector3 vec2(3.3f, 1.2f, 2.5f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + EXPECT_FLOAT_EQ(2.5f, vec2.getZ()); + + const auto vec3 = vec1 + vec2; + const auto vec4 = vec2 + vec1; + + EXPECT_FLOAT_EQ(5.3f + 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f + 1.2f, vec3.getY()); + EXPECT_FLOAT_EQ(-8.1f + 2.5f, vec3.getZ()); + + EXPECT_FLOAT_EQ(3.3f + 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f + 8.9f, vec4.getY()); + EXPECT_FLOAT_EQ(2.5f + -8.1f, vec4.getZ()); + } + + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + const Vector3 vec2(3.3f, 1.2f, 2.5f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + EXPECT_FLOAT_EQ(2.5f, vec2.getZ()); + + const auto vec3 = vec1 - vec2; + const auto vec4 = vec2 - vec1; + + EXPECT_FLOAT_EQ(5.3f - 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f - 1.2f, vec3.getY()); + EXPECT_FLOAT_EQ(-8.1f - 2.5f, vec3.getZ()); + + EXPECT_FLOAT_EQ(3.3f - 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f - 8.9f, vec4.getY()); + EXPECT_FLOAT_EQ(2.5f - -8.1f, vec4.getZ()); + } + + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + const Vector3 vec2(3.3f, 1.2f, 2.5f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + EXPECT_FLOAT_EQ(2.5f, vec2.getZ()); + + const auto vec3 = vec1 * vec2; + const auto vec4 = vec2 * vec1; + + EXPECT_FLOAT_EQ(5.3f * 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f * 1.2f, vec3.getY()); + EXPECT_FLOAT_EQ(-8.1f * 2.5f, vec3.getZ()); + + EXPECT_FLOAT_EQ(3.3f * 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f * 8.9f, vec4.getY()); + EXPECT_FLOAT_EQ(2.5f * -8.1f, vec4.getZ()); + } + + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + const Vector3 vec2(3.3f, 1.2f, 2.5f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + EXPECT_FLOAT_EQ(2.5f, vec2.getZ()); + + const auto vec3 = vec1 / vec2; + const auto vec4 = vec2 / vec1; + + EXPECT_FLOAT_EQ(5.3f / 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f / 1.2f, vec3.getY()); + EXPECT_FLOAT_EQ(-8.1f / 2.5f, vec3.getZ()); + + EXPECT_FLOAT_EQ(3.3f / 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f / 8.9f, vec4.getY()); + EXPECT_FLOAT_EQ(2.5f / -8.1f, vec4.getZ()); + } + + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + + const auto vec3 = vec1 * 3.2f; + const auto vec4 = 3.2f * vec1; + + EXPECT_FLOAT_EQ(5.3f * 3.2f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f * 3.2f, vec3.getY()); + EXPECT_FLOAT_EQ(-8.1f * 3.2f, vec3.getZ()); + + EXPECT_FLOAT_EQ(3.2f * 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.2f * 8.9f, vec4.getY()); + EXPECT_FLOAT_EQ(3.2f * -8.1f, vec4.getZ()); + } + + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); + + const auto vec3 = vec1 / 3.2f; + const auto vec4 = 3.2f / vec1; + + EXPECT_FLOAT_EQ(5.3f / 3.2f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f / 3.2f, vec3.getY()); + EXPECT_FLOAT_EQ(-8.1f / 3.2f, vec3.getZ()); + + EXPECT_FLOAT_EQ(3.2f / 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.2f / 8.9f, vec4.getY()); + EXPECT_FLOAT_EQ(3.2f / -8.1f, vec4.getZ()); + } + + { + const Vector3 vec1(5.3f, 8.9f, -8.1f); + const Vector3 vec2(5.3f, 8.9f, -8.1f); + const Vector3 vec3(1.3f, 8.9f, -3.1f); + const Vector3 vec4(5.3f, 0.9f, -1.1f); + + EXPECT_EQ(vec1, vec1); + EXPECT_EQ(vec1, vec2); + EXPECT_NE(vec1, vec3); + EXPECT_NE(vec1, vec4); + + EXPECT_EQ(vec2, vec1); + EXPECT_EQ(vec2, vec2); + EXPECT_NE(vec2, vec3); + EXPECT_NE(vec2, vec4); + + EXPECT_NE(vec3, vec1); + EXPECT_NE(vec3, vec2); + EXPECT_EQ(vec3, vec3); + EXPECT_NE(vec3, vec4); + + EXPECT_NE(vec4, vec1); + EXPECT_NE(vec4, vec2); + EXPECT_NE(vec4, vec3); + EXPECT_EQ(vec4, vec4); + } + +} + +/* ************************************************************************ */ From 3211479cbf4412350d03796b7db00b7f5f20ecbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Fri, 24 Mar 2017 16:21:46 +0100 Subject: [PATCH 06/11] math::Vector2 and math::Vector3 cleanup. --- include/cece/math/Vector2.hpp | 219 +------------- include/cece/math/Vector3.hpp | 136 --------- unittests/math/Vector2_test.cpp | 110 ++----- unittests/math/Vector3_test.cpp | 495 +++++++++++++++++++++++++++----- 4 files changed, 454 insertions(+), 506 deletions(-) diff --git a/include/cece/math/Vector2.hpp b/include/cece/math/Vector2.hpp index 2de646d..2b2e376 100644 --- a/include/cece/math/Vector2.hpp +++ b/include/cece/math/Vector2.hpp @@ -244,25 +244,6 @@ class Vector2 Vector2& operator*=(T1 rhs) noexcept; - /** - * @brief Multiplication operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in Vector2 operand. - * - * @return *this. - */ - template() * std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector2& operator*=(const Vector2& rhs) noexcept; - - /** * @brief Division operator. * @@ -282,25 +263,6 @@ class Vector2 Vector2& operator/=(T1 rhs) noexcept; - /** - * @brief Division operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in Vector2 operand. - * - * @return *this. - */ - template() / std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector2& operator/=(const Vector2& rhs) noexcept; - - /** * @brief Access operator. * @@ -411,16 +373,6 @@ class Vector2 ValueTypeSq getLengthSquared() const noexcept; - /** - * @brief Calculate dot of two vectors. - * - * @param rhs Second vector. - * - * @return Dot product. - */ - ValueTypeSq dot(const Vector2& rhs) const noexcept; - - /** * @brief Calculate vectors squared distance. * @@ -517,23 +469,6 @@ operator-(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -Vector2() * std::declval())> -operator*(const Vector2& lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -568,23 +503,6 @@ operator*(T1 lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Division operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -Vector2() / std::declval())> -operator/(const Vector2& lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Division operator. * @@ -652,7 +570,7 @@ bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ /** - * @brief Calculate cross product of two vectors. + * @brief Calculate dot product of two vectors. * * @param lhs Left operand. * @param rhs Right operand. @@ -660,45 +578,11 @@ bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept; * @tparam T1 The first type. * @tparam T2 The second type. * - * @return Cross product. + * @return Dot product. */ template decltype(std::declval() * std::declval()) -cross(const Vector2& lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Calculate cross product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Cross product. - */ -template -Vector2() * std::declval())> -cross(const Vector2& lhs, const T2& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Calculate cross product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Cross product. - */ -template -Vector2() * std::declval())> -cross(const T1& lhs, const Vector2& rhs) noexcept; +dot(const Vector2& lhs, const Vector2& rhs) noexcept; /* ************************************************************************ */ @@ -884,24 +768,6 @@ inline Vector2& Vector2::operator*=(T1 rhs) noexcept /* ************************************************************************ */ -template -template() * std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector2& Vector2::operator*=(const Vector2& rhs) noexcept -{ - x *= rhs.getX(); - y *= rhs.getY(); - - return *this; -} - -/* ************************************************************************ */ - template template() / std::declval()), @@ -920,24 +786,6 @@ inline Vector2& Vector2::operator/=(T1 rhs) noexcept /* ************************************************************************ */ -template -template() / std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector2& Vector2::operator/=(const Vector2& rhs) noexcept -{ - x /= rhs.getX(); - y /= rhs.getY(); - - return *this; -} - -/* ************************************************************************ */ - template inline T& Vector2::operator[](int pos) noexcept { @@ -1031,15 +879,7 @@ inline typename Vector2::ValueType Vector2::getLength() const noexcept template inline typename Vector2::ValueTypeSq Vector2::getLengthSquared() const noexcept { - return dot(*this); -} - -/* ************************************************************************ */ - -template -inline typename Vector2::ValueTypeSq Vector2::dot(const Vector2& rhs) const noexcept -{ - return getX() * rhs.getX() + getY() * rhs.getY(); + return getX() * getX() + getY() * getY(); } /* ************************************************************************ */ @@ -1112,18 +952,6 @@ operator-(const Vector2& lhs, const Vector2& rhs) noexcept /* ************************************************************************ */ -template -inline Vector2() * std::declval())> -operator*(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return { - lhs.getX() * rhs.getX(), - lhs.getY() * rhs.getY() - }; -} - -/* ************************************************************************ */ - template inline Vector2() * std::declval())> operator*(const Vector2& lhs, T2 rhs) noexcept @@ -1148,18 +976,6 @@ operator*(T1 lhs, const Vector2& rhs) noexcept /* ************************************************************************ */ -template -inline Vector2() / std::declval())> -operator/(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return { - lhs.getX() / rhs.getX(), - lhs.getY() / rhs.getY() - }; -} - -/* ************************************************************************ */ - template inline Vector2() / std::declval())> operator/(const Vector2& lhs, T2 rhs) noexcept @@ -1206,29 +1022,12 @@ inline bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept template inline decltype(std::declval() * std::declval()) -cross(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return {lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX()}; -} - -/* ************************************************************************ */ - -template -inline -Vector2() * std::declval())> -cross(const Vector2& lhs, const T2& rhs) noexcept +dot(const Vector2& lhs, const Vector2& rhs) noexcept { - return {rhs * lhs.getY(), -rhs * lhs.getX()}; -} - -/* ************************************************************************ */ - -template -inline -Vector2() * std::declval())> -cross(const T1& lhs, const Vector2& rhs) noexcept -{ - return {-lhs * rhs.getY(), lhs * rhs.getX()}; + return { + lhs.getX() * rhs.getX() + + lhs.getY() * rhs.getY() + }; } /* ************************************************************************ */ diff --git a/include/cece/math/Vector3.hpp b/include/cece/math/Vector3.hpp index 699fdf1..2fd79cc 100644 --- a/include/cece/math/Vector3.hpp +++ b/include/cece/math/Vector3.hpp @@ -249,25 +249,6 @@ class Vector3 Vector3& operator*=(T1 rhs) noexcept; - /** - * @brief Multiplication operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in Vector3 operand. - * - * @return *this. - */ - template() * std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector3& operator*=(const Vector3& rhs) noexcept; - - /** * @brief Division operator. * @@ -287,25 +268,6 @@ class Vector3 Vector3& operator/=(T1 rhs) noexcept; - /** - * @brief Division operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in Vector3 operand. - * - * @return *this. - */ - template() / std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector3& operator/=(const Vector3& rhs) noexcept; - - /** * @brief Access operator. * @@ -527,23 +489,6 @@ operator-(const Vector3& lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() * std::declval())> -operator*(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Multiplication operator. * @@ -578,23 +523,6 @@ operator*(T1 lhs, const Vector3& rhs) noexcept; /* ************************************************************************ */ -/** - * @brief Division operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() / std::declval())> -operator/(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Division operator. * @@ -890,25 +818,6 @@ inline Vector3& Vector3::operator*=(T1 rhs) noexcept /* ************************************************************************ */ -template -template() * std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector3& Vector3::operator*=(const Vector3& rhs) noexcept -{ - x *= rhs.getX(); - y *= rhs.getY(); - z *= rhs.getZ(); - - return *this; -} - -/* ************************************************************************ */ - template template() / std::declval()), @@ -928,25 +837,6 @@ inline Vector3& Vector3::operator/=(T1 rhs) noexcept /* ************************************************************************ */ -template -template() / std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector3& Vector3::operator/=(const Vector3& rhs) noexcept -{ - x /= rhs.getX(); - y /= rhs.getY(); - z /= rhs.getZ(); - - return *this; -} - -/* ************************************************************************ */ - template inline T& Vector3::operator[](int pos) noexcept { @@ -1129,19 +1019,6 @@ operator-(const Vector3& lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ -template -inline Vector3() * std::declval())> -operator*(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return { - lhs.getX() * rhs.getX(), - lhs.getY() * rhs.getY(), - lhs.getZ() * rhs.getZ() - }; -} - -/* ************************************************************************ */ - template inline Vector3() * std::declval())> operator*(const Vector3& lhs, T2 rhs) noexcept @@ -1168,19 +1045,6 @@ operator*(T1 lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ -template -inline Vector3() / std::declval())> -operator/(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return { - lhs.getX() / rhs.getX(), - lhs.getY() / rhs.getY(), - lhs.getZ() / rhs.getZ() - }; -} - -/* ************************************************************************ */ - template inline Vector3() / std::declval())> operator/(const Vector3& lhs, T2 rhs) noexcept diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp index 0d958cb..48aaa1d 100644 --- a/unittests/math/Vector2_test.cpp +++ b/unittests/math/Vector2_test.cpp @@ -251,19 +251,6 @@ TEST(Vector2, operators) EXPECT_FLOAT_EQ(4.0f, vec1[1]); } - { - Vector2 vec1{1.0f, 2.0f}; - - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(2.0f, vec1[1]); - - Vector2 vec2{1.0f, 2.0f}; - vec1 *= vec2; - - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(4.0f, vec1[1]); - } - { Vector2 vec1{1.0f, 2.0f}; @@ -275,19 +262,6 @@ TEST(Vector2, operators) EXPECT_FLOAT_EQ(0.5f, vec1[0]); EXPECT_FLOAT_EQ(1.0f, vec1[1]); } - - { - Vector2 vec1{1.0f, 2.0f}; - - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(2.0f, vec1[1]); - - Vector2 vec2{1.0f, 2.0f}; - vec1 /= vec2; - - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(1.0f, vec1[1]); - } } /* ************************************************************************ */ @@ -348,32 +322,6 @@ TEST(Vector2, memberFunctions) EXPECT_FLOAT_EQ(5, vec.getLengthSquared()); } - { - const Vector2 vec; - - EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); - } - - { - const Vector2 vec{1.0f, 2.0f}; - - EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); - } - - { - const Vector2 vec1; - const Vector2 vec2; - - EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); - } - - { - const Vector2 vec1{1.0f, 2.0f}; - const Vector2 vec2{5.0f, 4.0f}; - - EXPECT_FLOAT_EQ(13, vec1.dot(vec2)); - } - { const Vector2 vec; @@ -503,8 +451,24 @@ TEST(Vector2, functions) EXPECT_EQ(0, rot.getY()); } + { + Vector2 vec1(0.94333f, 0.73733f); + Vector2 vec2(0.16110f, 0.61872f); + + EXPECT_FLOAT_EQ(0.94333f, vec1.getX()); + EXPECT_FLOAT_EQ(0.73733f, vec1.getY()); + + EXPECT_FLOAT_EQ(0.16110f, vec2.getX()); + EXPECT_FLOAT_EQ(0.61872f, vec2.getY()); - // TODO: cross, dot + auto res = dot(vec1, vec2); + + EXPECT_FLOAT_EQ( + 0.94333f * 0.16110f + + 0.73733f * 0.61872f, + res + ); + } } /* ************************************************************************ */ @@ -551,46 +515,6 @@ TEST(Vector2, freeOperators) EXPECT_FLOAT_EQ(1.2f - 8.9f, vec4.getY()); } - { - const Vector2 vec1(5.3f, 8.9f); - const Vector2 vec2(3.3f, 1.2f); - - EXPECT_FLOAT_EQ(5.3f, vec1.getX()); - EXPECT_FLOAT_EQ(8.9f, vec1.getY()); - - EXPECT_FLOAT_EQ(3.3f, vec2.getX()); - EXPECT_FLOAT_EQ(1.2f, vec2.getY()); - - const auto vec3 = vec1 * vec2; - const auto vec4 = vec2 * vec1; - - EXPECT_FLOAT_EQ(5.3f * 3.3f, vec3.getX()); - EXPECT_FLOAT_EQ(8.9f * 1.2f, vec3.getY()); - - EXPECT_FLOAT_EQ(3.3f * 5.3f, vec4.getX()); - EXPECT_FLOAT_EQ(1.2f * 8.9f, vec4.getY()); - } - - { - const Vector2 vec1(5.3f, 8.9f); - const Vector2 vec2(3.3f, 1.2f); - - EXPECT_FLOAT_EQ(5.3f, vec1.getX()); - EXPECT_FLOAT_EQ(8.9f, vec1.getY()); - - EXPECT_FLOAT_EQ(3.3f, vec2.getX()); - EXPECT_FLOAT_EQ(1.2f, vec2.getY()); - - const auto vec3 = vec1 / vec2; - const auto vec4 = vec2 / vec1; - - EXPECT_FLOAT_EQ(5.3f / 3.3f, vec3.getX()); - EXPECT_FLOAT_EQ(8.9f / 1.2f, vec3.getY()); - - EXPECT_FLOAT_EQ(3.3f / 5.3f, vec4.getX()); - EXPECT_FLOAT_EQ(1.2f / 8.9f, vec4.getY()); - } - { const Vector2 vec1(5.3f, 8.9f); diff --git a/unittests/math/Vector3_test.cpp b/unittests/math/Vector3_test.cpp index e300661..9d9e088 100644 --- a/unittests/math/Vector3_test.cpp +++ b/unittests/math/Vector3_test.cpp @@ -614,8 +614,36 @@ TEST(Vector3, assignmentMove) /* ************************************************************************ */ -TEST(Vector3, operators) +TEST(Vector3, operatorUnaryPlus) { + { + Vector3 vec1{1, 2, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2 = +vec1; + + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(2, vec2[1]); + EXPECT_EQ(-8, vec2[2]); + } + + { + Vector3 vec1{1, 2, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2 = +vec1; + + EXPECT_EQ(1, vec2[0]); + EXPECT_EQ(2, vec2[1]); + EXPECT_EQ(8, vec2[2]); + } + { Vector3 vec1{1.0f, 2.0f, -8.1f}; @@ -630,6 +658,53 @@ TEST(Vector3, operators) EXPECT_FLOAT_EQ(-8.1f, vec2[2]); } + { + Vector3 vec1{1.0, 2.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.0, vec1[0]); + EXPECT_DOUBLE_EQ(2.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2 = +vec1; + + EXPECT_DOUBLE_EQ(1.0, vec2[0]); + EXPECT_DOUBLE_EQ(2.0, vec2[1]); + EXPECT_DOUBLE_EQ(-8.1, vec2[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, operatorUnaryMinus) +{ + { + Vector3 vec1{1, 2, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2 = -vec1; + + EXPECT_EQ(-1, vec2[0]); + EXPECT_EQ(-2, vec2[1]); + EXPECT_EQ(8, vec2[2]); + } + + { + Vector3 vec1{1, 2, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2 = -vec1; + + EXPECT_EQ(-1, vec2[0]); + EXPECT_EQ(-2, vec2[1]); + EXPECT_EQ(-8, vec2[2]); + } + { Vector3 vec1{1.0f, 2.0f, -8.1f}; @@ -644,6 +719,55 @@ TEST(Vector3, operators) EXPECT_FLOAT_EQ(8.1f, vec2[2]); } + { + Vector3 vec1{1.0, 2.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.0, vec1[0]); + EXPECT_DOUBLE_EQ(2.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2 = -vec1; + + EXPECT_DOUBLE_EQ(-1.0, vec2[0]); + EXPECT_DOUBLE_EQ(-2.0, vec2[1]); + EXPECT_DOUBLE_EQ(8.1, vec2[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, operatorPlus) +{ + { + Vector3 vec1{1, 2, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2{1, 2, -8}; + vec1 += vec2; + + EXPECT_EQ(2, vec1[0]); + EXPECT_EQ(4, vec1[1]); + EXPECT_EQ(-16, vec1[2]); + } + + { + Vector3 vec1{1, 2, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2{1, 2, 8}; + vec1 += vec2; + + EXPECT_EQ(2, vec1[0]); + EXPECT_EQ(4, vec1[1]); + EXPECT_EQ(16, vec1[2]); + } + { Vector3 vec1{1.0f, 2.0f, -8.1f}; @@ -659,6 +783,56 @@ TEST(Vector3, operators) EXPECT_FLOAT_EQ(-16.2f, vec1[2]); } + { + Vector3 vec1{1.0, 2.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.0, vec1[0]); + EXPECT_DOUBLE_EQ(2.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2{1.0, 2.0, -8.1}; + vec1 += vec2; + + EXPECT_DOUBLE_EQ(2.0, vec1[0]); + EXPECT_DOUBLE_EQ(4.0, vec1[1]); + EXPECT_DOUBLE_EQ(-16.2, vec1[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, operatorMinus) +{ + { + Vector3 vec1{1, 2, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + Vector3 vec2{1, 2, -8}; + vec1 -= vec2; + + EXPECT_EQ(0, vec1[0]); + EXPECT_EQ(0, vec1[1]); + EXPECT_EQ(0, vec1[2]); + } + + { + Vector3 vec1{1, 2, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + Vector3 vec2{1, 2, 8}; + vec1 -= vec2; + + EXPECT_EQ(0, vec1[0]); + EXPECT_EQ(0, vec1[1]); + EXPECT_EQ(0, vec1[2]); + } + { Vector3 vec1{1.0f, 2.0f, -8.1f}; @@ -674,6 +848,54 @@ TEST(Vector3, operators) EXPECT_FLOAT_EQ(0.0f, vec1[2]); } + { + Vector3 vec1{1.0, 2.0, -8.1}; + + EXPECT_DOUBLE_EQ(1.0, vec1[0]); + EXPECT_DOUBLE_EQ(2.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); + + Vector3 vec2{1.0, 2.0, -8.1}; + vec1 -= vec2; + + EXPECT_DOUBLE_EQ(0.0, vec1[0]); + EXPECT_DOUBLE_EQ(0.0, vec1[1]); + EXPECT_DOUBLE_EQ(0.0, vec1[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, operatorMult) +{ + { + Vector3 vec1{1, 2, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + vec1 *= 2.0; + + EXPECT_EQ(2, vec1[0]); + EXPECT_EQ(4, vec1[1]); + EXPECT_EQ(-16, vec1[2]); + } + + { + Vector3 vec1{1, 2, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + vec1 *= 2.0; + + EXPECT_EQ(2, vec1[0]); + EXPECT_EQ(4, vec1[1]); + EXPECT_EQ(16, vec1[2]); + } + { Vector3 vec1{1.0f, 2.0f, -8.1f}; @@ -689,18 +911,50 @@ TEST(Vector3, operators) } { - Vector3 vec1{1.0f, 2.0f, -8.1f}; + Vector3 vec1{1.0, 2.0, -8.1}; - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(2.0f, vec1[1]); - EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + EXPECT_DOUBLE_EQ(1.0, vec1[0]); + EXPECT_DOUBLE_EQ(2.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); - Vector3 vec2{1.0f, 2.0f, -8.1f}; - vec1 *= vec2; + vec1 *= 2.0; - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(4.0f, vec1[1]); - EXPECT_FLOAT_EQ(-8.1f * -8.1f, vec1[2]); + EXPECT_DOUBLE_EQ(2.0, vec1[0]); + EXPECT_DOUBLE_EQ(4.0, vec1[1]); + EXPECT_DOUBLE_EQ(-16.2, vec1[2]); + } +} + +/* ************************************************************************ */ + +TEST(Vector3, operatorDiv) +{ + { + Vector3 vec1{1, 2, -8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(-8, vec1[2]); + + vec1 /= 2.0; + + EXPECT_EQ(0, vec1[0]); + EXPECT_EQ(1, vec1[1]); + EXPECT_EQ(-4, vec1[2]); + } + + { + Vector3 vec1{1, 2, 8}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + EXPECT_EQ(8, vec1[2]); + + vec1 /= 2.0; + + EXPECT_EQ(0, vec1[0]); + EXPECT_EQ(1, vec1[1]); + EXPECT_EQ(4, vec1[2]); } { @@ -718,18 +972,17 @@ TEST(Vector3, operators) } { - Vector3 vec1{1.0f, 2.0f, -8.1f}; + Vector3 vec1{1.0, 2.0, -8.1}; - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(2.0f, vec1[1]); - EXPECT_FLOAT_EQ(-8.1f, vec1[2]); + EXPECT_DOUBLE_EQ(1.0, vec1[0]); + EXPECT_DOUBLE_EQ(2.0, vec1[1]); + EXPECT_DOUBLE_EQ(-8.1, vec1[2]); - Vector3 vec2{1.0f, 2.0f, -8.1f}; - vec1 /= vec2; + vec1 /= 2.0; - EXPECT_FLOAT_EQ(1.0f, vec1[0]); - EXPECT_FLOAT_EQ(1.0f, vec1[1]); - EXPECT_FLOAT_EQ(1.0f, vec1[2]); + EXPECT_DOUBLE_EQ(0.5, vec1[0]); + EXPECT_DOUBLE_EQ(1.0, vec1[1]); + EXPECT_DOUBLE_EQ(-4.05, vec1[2]); } } @@ -898,6 +1151,162 @@ TEST(Vector3, mutators) EXPECT_EQ(50, vec.y); EXPECT_EQ(10, vec.z); } + + { + Vector3 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + + vec.setX(100); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + + vec.setY(50); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(50, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + + vec.setZ(10); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(50, vec.getY()); + EXPECT_EQ(10, vec.getZ()); + } + + { + Vector3 vec; + + EXPECT_EQ(0, vec.x); + EXPECT_EQ(0, vec.y); + EXPECT_EQ(0, vec.z); + + vec.x = 100; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(0, vec.y); + EXPECT_EQ(0, vec.z); + + vec.y = 50; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + EXPECT_EQ(0, vec.z); + + vec.z = 10; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + EXPECT_EQ(10, vec.z); + } + + { + Vector3 vec; + + EXPECT_FLOAT_EQ(0, vec.getX()); + EXPECT_FLOAT_EQ(0, vec.getY()); + EXPECT_FLOAT_EQ(0, vec.getZ()); + + vec.setX(100.3f); + + EXPECT_FLOAT_EQ(100.3f, vec.getX()); + EXPECT_FLOAT_EQ(0, vec.getY()); + EXPECT_FLOAT_EQ(0, vec.getZ()); + + vec.setY(50); + + EXPECT_FLOAT_EQ(100.3f, vec.getX()); + EXPECT_FLOAT_EQ(50, vec.getY()); + EXPECT_FLOAT_EQ(0, vec.getZ()); + + vec.setZ(10); + + EXPECT_FLOAT_EQ(100.3f, vec.getX()); + EXPECT_FLOAT_EQ(50, vec.getY()); + EXPECT_FLOAT_EQ(10, vec.getZ()); + } + + { + Vector3 vec; + + EXPECT_FLOAT_EQ(0, vec.x); + EXPECT_FLOAT_EQ(0, vec.y); + EXPECT_FLOAT_EQ(0, vec.z); + + vec.x = 100.3f; + + EXPECT_FLOAT_EQ(100.3f, vec.x); + EXPECT_FLOAT_EQ(0, vec.y); + EXPECT_FLOAT_EQ(0, vec.z); + + vec.y = 50; + + EXPECT_FLOAT_EQ(100.3f, vec.x); + EXPECT_FLOAT_EQ(50, vec.y); + EXPECT_FLOAT_EQ(0, vec.z); + + vec.z = 10; + + EXPECT_FLOAT_EQ(100.3f, vec.x); + EXPECT_FLOAT_EQ(50, vec.y); + EXPECT_FLOAT_EQ(10, vec.z); + } + + { + Vector3 vec; + + EXPECT_DOUBLE_EQ(0, vec.getX()); + EXPECT_DOUBLE_EQ(0, vec.getY()); + EXPECT_DOUBLE_EQ(0, vec.getZ()); + + vec.setX(100.3); + + EXPECT_DOUBLE_EQ(100.3, vec.getX()); + EXPECT_DOUBLE_EQ(0, vec.getY()); + EXPECT_DOUBLE_EQ(0, vec.getZ()); + + vec.setY(50); + + EXPECT_DOUBLE_EQ(100.3, vec.getX()); + EXPECT_DOUBLE_EQ(50, vec.getY()); + EXPECT_DOUBLE_EQ(0, vec.getZ()); + + vec.setZ(10); + + EXPECT_DOUBLE_EQ(100.3, vec.getX()); + EXPECT_DOUBLE_EQ(50, vec.getY()); + EXPECT_DOUBLE_EQ(10, vec.getZ()); + } + + { + Vector3 vec; + + EXPECT_DOUBLE_EQ(0, vec.x); + EXPECT_DOUBLE_EQ(0, vec.y); + EXPECT_DOUBLE_EQ(0, vec.z); + + vec.x = 100.3; + + EXPECT_DOUBLE_EQ(100.3, vec.x); + EXPECT_DOUBLE_EQ(0, vec.y); + EXPECT_DOUBLE_EQ(0, vec.z); + + vec.y = 50; + + EXPECT_DOUBLE_EQ(100.3, vec.x); + EXPECT_DOUBLE_EQ(50, vec.y); + EXPECT_DOUBLE_EQ(0, vec.z); + + vec.z = 10; + + EXPECT_DOUBLE_EQ(100.3, vec.x); + EXPECT_DOUBLE_EQ(50, vec.y); + EXPECT_DOUBLE_EQ(10, vec.z); + } } /* ************************************************************************ */ @@ -998,54 +1407,6 @@ TEST(Vector3, freeOperators) EXPECT_FLOAT_EQ(2.5f - -8.1f, vec4.getZ()); } - { - const Vector3 vec1(5.3f, 8.9f, -8.1f); - const Vector3 vec2(3.3f, 1.2f, 2.5f); - - EXPECT_FLOAT_EQ(5.3f, vec1.getX()); - EXPECT_FLOAT_EQ(8.9f, vec1.getY()); - EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); - - EXPECT_FLOAT_EQ(3.3f, vec2.getX()); - EXPECT_FLOAT_EQ(1.2f, vec2.getY()); - EXPECT_FLOAT_EQ(2.5f, vec2.getZ()); - - const auto vec3 = vec1 * vec2; - const auto vec4 = vec2 * vec1; - - EXPECT_FLOAT_EQ(5.3f * 3.3f, vec3.getX()); - EXPECT_FLOAT_EQ(8.9f * 1.2f, vec3.getY()); - EXPECT_FLOAT_EQ(-8.1f * 2.5f, vec3.getZ()); - - EXPECT_FLOAT_EQ(3.3f * 5.3f, vec4.getX()); - EXPECT_FLOAT_EQ(1.2f * 8.9f, vec4.getY()); - EXPECT_FLOAT_EQ(2.5f * -8.1f, vec4.getZ()); - } - - { - const Vector3 vec1(5.3f, 8.9f, -8.1f); - const Vector3 vec2(3.3f, 1.2f, 2.5f); - - EXPECT_FLOAT_EQ(5.3f, vec1.getX()); - EXPECT_FLOAT_EQ(8.9f, vec1.getY()); - EXPECT_FLOAT_EQ(-8.1f, vec1.getZ()); - - EXPECT_FLOAT_EQ(3.3f, vec2.getX()); - EXPECT_FLOAT_EQ(1.2f, vec2.getY()); - EXPECT_FLOAT_EQ(2.5f, vec2.getZ()); - - const auto vec3 = vec1 / vec2; - const auto vec4 = vec2 / vec1; - - EXPECT_FLOAT_EQ(5.3f / 3.3f, vec3.getX()); - EXPECT_FLOAT_EQ(8.9f / 1.2f, vec3.getY()); - EXPECT_FLOAT_EQ(-8.1f / 2.5f, vec3.getZ()); - - EXPECT_FLOAT_EQ(3.3f / 5.3f, vec4.getX()); - EXPECT_FLOAT_EQ(1.2f / 8.9f, vec4.getY()); - EXPECT_FLOAT_EQ(2.5f / -8.1f, vec4.getZ()); - } - { const Vector3 vec1(5.3f, 8.9f, -8.1f); From 7e6a5e0002cad6f08b887342ad334d35b83734b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Mon, 5 Jun 2017 17:50:14 +0200 Subject: [PATCH 07/11] Created VectorBase. VectorBase is base class for all Vector classes (BasicVector, Vector2, Vector3). --- include/cece/math/Vector.hpp | 1384 ++++------------------------ include/cece/math/Vector2.hpp | 729 ++------------- include/cece/math/Vector3.hpp | 748 ++------------- include/cece/math/VectorBase.hpp | 1117 ++++++++++++++++++++++ include/cece/math/VectorRange.hpp | 2 +- unittests/math/CMakeLists.txt | 1 + unittests/math/Vector2_test.cpp | 122 +-- unittests/math/Vector3_test.cpp | 156 ++-- unittests/math/VectorBase_test.cpp | 431 +++++++++ unittests/math/Vector_test.cpp | 85 +- 10 files changed, 2029 insertions(+), 2746 deletions(-) create mode 100644 include/cece/math/VectorBase.hpp create mode 100644 unittests/math/VectorBase_test.cpp diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index ab050e5..8d1167d 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -41,6 +41,7 @@ #include "cece/io/OutStream.hpp" #include "cece/unit/math.hpp" #include "cece/unit/Units.hpp" +#include "cece/math/VectorBase.hpp" #include "cece/math/Vector2.hpp" #include "cece/math/Vector3.hpp" @@ -58,7 +59,7 @@ namespace math { * @tparam N Number of elements. */ template -class BasicVector +class BasicVector : public VectorBase { static_assert(N > 0, "Cannot create empty vector"); @@ -70,8 +71,13 @@ class BasicVector /// BasicVector value type. using ValueType = T; - /// Element type squared. - using ValueTypeSq = decltype(std::declval() * std::declval()); + +// Public Data Members +public: + + + // Member data. + StaticArray m; // Public Ctors @@ -89,7 +95,7 @@ class BasicVector * * @param data The source data. */ - BasicVector(std::initializer_list data) noexcept; + BasicVector(std::initializer_list data); /** @@ -97,7 +103,7 @@ class BasicVector * * @param data The source data. */ - explicit BasicVector(T (&data)[N]) noexcept; + explicit BasicVector(T (&data)[N]); /** @@ -105,7 +111,7 @@ class BasicVector * * @param data The source data. */ - explicit BasicVector(StaticArray data) noexcept; + explicit BasicVector(const StaticArray& data); /** @@ -113,7 +119,7 @@ class BasicVector * * @param[in] zero The zero value. */ - BasicVector(Zero_t zero) noexcept; + BasicVector(Zero_t zero); /** @@ -121,7 +127,7 @@ class BasicVector * * @param[in] src The source vector. */ - BasicVector(const BasicVector& src) noexcept; + BasicVector(const BasicVector& src); /** @@ -129,7 +135,7 @@ class BasicVector * * @param[in] src The source vector. */ - BasicVector(BasicVector&& src) noexcept; + BasicVector(BasicVector&& src); /** @@ -140,7 +146,7 @@ class BasicVector * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - explicit BasicVector(const BasicVector& src) noexcept; + explicit BasicVector(const BasicVector& src); // Public Operators @@ -154,7 +160,7 @@ class BasicVector * * @return *this. */ - BasicVector& operator=(Zero_t zero) noexcept; + BasicVector& operator=(Zero_t zero); /** @@ -164,7 +170,7 @@ class BasicVector * * @return *this. */ - BasicVector& operator=(std::initializer_list data) noexcept; + BasicVector& operator=(std::initializer_list data); /** @@ -174,7 +180,7 @@ class BasicVector * * @return *this. */ - BasicVector& operator=(T (&data)[N]) noexcept; + BasicVector& operator=(T (&data)[N]); /** @@ -184,7 +190,7 @@ class BasicVector * * @return *this. */ - BasicVector& operator=(StaticArray data) noexcept; + BasicVector& operator=(const StaticArray& data); /** @@ -194,7 +200,7 @@ class BasicVector * * @return *this. */ - BasicVector& operator=(const BasicVector& src) noexcept; + BasicVector& operator=(const BasicVector& src); /** @@ -204,7 +210,7 @@ class BasicVector * * @return *this. */ - BasicVector& operator=(BasicVector&& src) noexcept; + BasicVector& operator=(BasicVector&& src); /** @@ -217,131 +223,7 @@ class BasicVector * @return *this. */ template::value>::type* = nullptr> - BasicVector& operator=(const BasicVector& src) noexcept; - - - /** - * @brief Unary plus operator. - * - * @return Vector. - */ - BasicVector operator+() const noexcept; - - - /** - * @brief Unary minus operator. - * - * @return Vector. - */ - BasicVector operator-() const noexcept; - - - /** - * @brief Addition operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() + std::declval()), - T - >::value>::type* = nullptr> - BasicVector& operator+=(const BasicVector& rhs) noexcept; - - - /** - * @brief Subtraction operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @return *this. - */ - template() - std::declval()), - T - >::value>::type* = nullptr> - BasicVector& operator-=(const BasicVector& rhs) noexcept; - - - /** - * @brief Multiplication operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() * std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - BasicVector& operator*=(T1 rhs) noexcept; - - - /** - * @brief Multiplication operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @return *this. - */ - template() * std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - BasicVector& operator*=(const BasicVector& rhs) noexcept; - - - /** - * @brief Division operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() / std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - BasicVector& operator/=(T1 rhs) noexcept; - - - /** - * @brief Division operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in BasicVector operand. - * - * @return *this. - */ - template() / std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - BasicVector& operator/=(const BasicVector& rhs) noexcept; + BasicVector& operator=(const BasicVector& src); /** @@ -375,122 +257,6 @@ class BasicVector */ int getSize() const noexcept; - - /** - * @brief Check if given value is in given range. - * - * @param value Given value. - * @param low Minimum value (>=). - * @param high Maximum value (<). - * - * @return If given value is in given range. - */ - static bool inRange(T value, T low, T high) noexcept; - - - /** - * @brief Check if current vector is in given range. - * - * @param low Minimum coordinates (>=). - * @param high Maximum coordinates (<). - * - * @return If current value is in given range. - */ - bool inRange(const BasicVector& low, const BasicVector& high) const noexcept; - - - /** - * @brief Check if current vector is in given range where the low range - * is Zero vector. - * - * @param high Maximum coordinates (<). - * - * @return If current value is in given range. - */ - bool inRange(const BasicVector& high) const noexcept; - - -// Public Operations -public: - - - /** - * @brief Calculate vector length. - * - * @return The length. - */ - ValueType getLength() const noexcept; - - - /** - * @brief Calculate vector length - squared. - * - * @return The length squared. - */ - ValueTypeSq getLengthSquared() const noexcept; - - - /** - * @brief Calculate dot of two vectors. - * - * @param rhs Second vector. - * - * @return Dot product. - */ - ValueTypeSq dot(const BasicVector& rhs) const noexcept; - - - /** - * @brief Calculate vectors squared distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - ValueTypeSq distanceSquared(const BasicVector& rhs) const noexcept; - - - /** - * @brief Calculate vectors distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - ValueType distance(const BasicVector& rhs) const noexcept; - - - /** - * @brief Inverse current vector (1 / *this). - * - * @tparam T2 Type of result vector's element. - * - * @return Inversed vector. - */ - template - BasicVector inversed() const noexcept; - - -// Public Operations -public: - - - /** - * @brief Create from single value. - * - * @param val The value. - * - * @return Vector of vals. - */ - static BasicVector createSingle(T val) noexcept; - - -// Private Data Members -private: - - /// BasicVector data. - StaticArray m_data; - }; /* ************************************************************************ */ @@ -509,7 +275,41 @@ struct BasicVector : public Vector2 } const T& getWidth() const noexcept { return Vector2::getX(); } + const T& getHeight() const noexcept { return Vector2::getY(); } + + static bool inRange(T value, T low, T high) noexcept { return value >= low && value < high; } + + bool inRange(const BasicVector& low, const BasicVector& high) const noexcept + { + bool res = true; + + res = res && inRange(Vector2::getX(), low.getX(), high.getX()); + res = res && inRange(Vector2::getY(), low.getY(), high.getY()); + + return res; + } + + bool inRange(const BasicVector& high) const noexcept + { + return inRange(Zero, high); + } + + static BasicVector createSingle(T val) noexcept { return BasicVector(val, val); } + + template + BasicVector inversed() const noexcept + { + return BasicVector( + T2(1) / Vector2::getX(), + T2(1) / Vector2::getY() + ); + } + + BasicVector rotated(unit::Angle angle) const noexcept + { + return rotate(*this, angle); + } }; /* ************************************************************************ */ @@ -530,6 +330,36 @@ struct BasicVector : public Vector3 const T& getWidth() const noexcept { return Vector3::getX(); } const T& getHeight() const noexcept { return Vector3::getY(); } const T& getDepth() const noexcept { return Vector3::getZ(); } + + static bool inRange(T value, T low, T high) noexcept { return value >= low && value < high; } + + bool inRange(const BasicVector& low, const BasicVector& high) const noexcept + { + bool res = true; + + res = res && inRange(Vector3::getX(), low.getX(), high.getX()); + res = res && inRange(Vector3::getY(), low.getY(), high.getY()); + res = res && inRange(Vector3::getZ(), low.getZ(), high.getZ()); + + return res; + } + + bool inRange(const BasicVector& high) const noexcept + { + return inRange(Zero, high); + } + + static BasicVector createSingle(T val) noexcept { return BasicVector(val, val, val); } + + template + BasicVector inversed() const noexcept + { + return BasicVector( + T2(1) / Vector3::getX(), + T2(1) / Vector3::getY(), + T2(1) / Vector3::getZ() + ); + } }; /* ************************************************************************ */ @@ -592,776 +422,163 @@ using VectorReal = Vector; /* ************************************************************************ */ /** - * @brief Addition operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * @tparam N BasicVector size. + * @brief Input stream operator. * - * @param lhs Left operand. - * @param rhs Right operand. + * @param is Input stream. + * @param vector Result value. * - * @return Result vector. + * @return is. */ -template -inline BasicVector operator+(const BasicVector& lhs, const BasicVector& rhs) noexcept +template +io::InStream& operator>>(io::InStream& is, BasicVector& vector) { - BasicVector res; + int i = 0; - for (int i = 0; i < N; ++i) - res[i] = lhs[i] + rhs[i]; + for (; i < N; ++i) + { + if (!(is >> std::skipws >> vector[i])) + break; + } - return res; + if (i == 0) + return is; + + // Copy missing values + // TODO: have this feature? + for (int j = i; j < N; ++j) + vector[j] = vector[i - 1]; + + return is; } /* ************************************************************************ */ /** - * @brief Addition operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * @tparam N BasicVector size. + * @brief Output stream operator. * - * @param lhs Left operand. - * @param rhs Right operand. + * @param os Output stream. + * @param vector Input value. * - * @return Result vector. + * @return os. */ -template -inline BasicVector operator+(const BasicVector& lhs, T2 rhs) noexcept +template +io::OutStream& operator<<(io::OutStream& os, const BasicVector& vector) noexcept { - BasicVector res; - for (int i = 0; i < N; ++i) - res[i] = lhs[i] + rhs; + { + if (i != 0) + os << " "; - return res; + os << vector[i]; + } + + return os; } /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * @tparam N BasicVector size. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator+(T1 lhs, const BasicVector& rhs) noexcept -{ - BasicVector res; +extern template class BasicVector; - for (int i = 0; i < N; ++i) - res[i] = lhs + rhs[i]; +/* ************************************************************************ */ - return res; +} } +/* ************************************************************************ */ +/* ************************************************************************ */ /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator-(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - BasicVector res; +namespace cece { +namespace math { - for (int i = 0; i < N; ++i) - res[i] = lhs[i] - rhs[i]; +/* ************************************************************************ */ - return res; +template +inline BasicVector::BasicVector() noexcept + : m{} +{ + // Nothing to do } /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator-(const BasicVector& lhs, T2 rhs) noexcept +template +inline BasicVector::BasicVector(std::initializer_list data) { - BasicVector res; + CECE_ASSERT(data.size() == getSize()); - for (int i = 0; i < N; ++i) - res[i] = lhs[i] - rhs; + using std::begin; + auto it = begin(data); - return res; + for (int i = 0; i < getSize(); ++i, ++it) + m[i] = *it; } /* ************************************************************************ */ -/** - * @brief Substract operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator-(T1 lhs, const BasicVector& rhs) noexcept +template +inline BasicVector::BasicVector(T (&data)[N]) { - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs - rhs[i]; + using std::begin; + auto it = begin(data); - return res; + for (int i = 0; i < getSize(); ++i, ++it) + m[i] = *it; } /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator*(const BasicVector& lhs, const BasicVector& rhs) noexcept +template +inline BasicVector::BasicVector(const StaticArray& data) + : m(data) { - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs[i] * rhs[i]; - - return res; + // Nothing to do } /* ************************************************************************ */ -/** - * @brief Multiplication operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator*(const BasicVector& lhs, T2 rhs) noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs[i] * rhs; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Multiplication operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator*(T1 lhs, const BasicVector& rhs) noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs * rhs[i]; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator/(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs[i] / rhs[i]; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @tparam T1 Type of value in first BasicVector. - * @tparam T2 Type of second operand. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator/(const BasicVector& lhs, T2 rhs) noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs[i] / rhs; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second BasicVector. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Result vector. - */ -template -inline BasicVector operator/(T1 lhs, const BasicVector& rhs) noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = lhs / rhs[i]; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator==(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - bool res = true; - - for (int i = 0; i < N; ++i) - res = res && lhs[i] == rhs[i]; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator==(const BasicVector& lhs, Zero_t rhs) noexcept -{ - return lhs == BasicVector(Zero); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator==(Zero_t lhs, const BasicVector& rhs) noexcept -{ - return BasicVector(Zero) == rhs; -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator!=(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return !operator==(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator!=(const BasicVector& lhs, Zero_t rhs) noexcept -{ - return !operator==(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator!=(Zero_t lhs, const BasicVector& rhs) noexcept -{ - return !operator==(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator<(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - bool res = true; - - for (int i = 0; i < N; ++i) - res = res && ((lhs[i] < rhs[i]) || !(rhs[i] < lhs[i])); - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator<(const BasicVector& lhs, Zero_t rhs) noexcept -{ - return lhs < BasicVector{Zero}; -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator<(Zero_t lhs, const BasicVector& rhs) noexcept -{ - return BasicVector{Zero} < rhs; -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator<=(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return !operator>(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator<=(const BasicVector& lhs, Zero_t rhs) noexcept -{ - return !operator>(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator<=(Zero_t lhs, const BasicVector& rhs) noexcept -{ - return !operator>(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator>(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - // Reversed operands - return operator<(rhs, lhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator>(const BasicVector& lhs, Zero_t rhs) noexcept -{ - // Reversed operands - return operator<(rhs, lhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator>(Zero_t lhs, const BasicVector& rhs) noexcept -{ - // Reversed operands - return operator<(rhs, lhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator>=(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - return !operator<(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator>=(const BasicVector& lhs, Zero_t rhs) noexcept -{ - return !operator<(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return - */ -template -inline bool operator>=(Zero_t lhs, const BasicVector& rhs) noexcept -{ - return !operator<(lhs, rhs); -} - -/* ************************************************************************ */ - -/** - * @brief Calculate dot product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @return Dot product. - */ -template -inline decltype(T1{} * T2{}) dot(const BasicVector& lhs, const BasicVector& rhs) noexcept -{ - decltype(T1{} * T2{}) res{}; - - for (int i = 0; i < N; ++i) - res += lhs[i] * rhs[i]; - - return res; -} - -/* ************************************************************************ */ - -/** - * @brief Input stream operator. - * - * @param is Input stream. - * @param vector Result value. - * - * @return is. - */ template -io::InStream& operator>>(io::InStream& is, BasicVector& vector) +inline BasicVector::BasicVector(Zero_t zero) { - int i = 0; - - for (; i < N; ++i) - { - if (!(is >> std::skipws >> vector[i])) - break; - } - - if (i == 0) - return is; - - // Copy missing values - // TODO: have this feature? - for (int j = i; j < N; ++j) - vector[j] = vector[i - 1]; - - return is; + for (int i = 0; i < getSize(); ++i) + m[i] = T{}; } /* ************************************************************************ */ -/** - * @brief Output stream operator. - * - * @param os Output stream. - * @param vector Input value. - * - * @return os. - */ template -io::OutStream& operator<<(io::OutStream& os, const BasicVector& vector) noexcept +inline BasicVector::BasicVector(const BasicVector& src) { - for (int i = 0; i < N; ++i) - { - if (i != 0) - os << " "; - - os << vector[i]; - } - - return os; + for (int i = 0; i < getSize(); ++i) + m[i] = src.m[i]; } /* ************************************************************************ */ -extern template class BasicVector; - -/* ************************************************************************ */ - -} -} - -/* ************************************************************************ */ -/* ************************************************************************ */ -/* ************************************************************************ */ - -namespace cece { -namespace math { - -/* ************************************************************************ */ - template -inline BasicVector::BasicVector() noexcept - : m_data{} +inline BasicVector::BasicVector(BasicVector&& src) { - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline BasicVector::BasicVector(std::initializer_list data) noexcept -{ - CECE_ASSERT(data.size() == N); - - using std::begin; - auto it = begin(data); - - for (int i = 0; i < N; ++i, ++it) - m_data[i] = *it; -} - -/* ************************************************************************ */ - -template -inline BasicVector::BasicVector(T (&data)[N]) noexcept -{ - using std::begin; - auto it = begin(data); - - for (int i = 0; i < N; ++i, ++it) - m_data[i] = *it; -} - -/* ************************************************************************ */ - -template -inline BasicVector::BasicVector(StaticArray data) noexcept - : m_data(data) -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline BasicVector::BasicVector(Zero_t zero) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] = T{}; -} - -/* ************************************************************************ */ - -template -inline BasicVector::BasicVector(const BasicVector& src) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] = src.m_data[i]; -} - -/* ************************************************************************ */ - -template -inline BasicVector::BasicVector(BasicVector&& src) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] = std::move(src.m_data[i]); + for (int i = 0; i < getSize(); ++i) + m[i] = std::move(src.m[i]); } /* ************************************************************************ */ template template::value>::type*> -inline BasicVector::BasicVector(const BasicVector& src) noexcept +inline BasicVector::BasicVector(const BasicVector& src) { - for (int i = 0; i < N; ++i) - m_data[i] = T(src[i]); + for (int i = 0; i < getSize(); ++i) + m[i] = T(src[i]); } /* ************************************************************************ */ template -inline BasicVector& BasicVector::operator=(Zero_t zero) noexcept +inline BasicVector& BasicVector::operator=(Zero_t zero) { - for (int i = 0; i < N; ++i) - m_data[i] = T{}; + for (int i = 0; i < getSize(); ++i) + m[i] = T{}; return *this; } @@ -1369,15 +586,15 @@ inline BasicVector& BasicVector::operator=(Zero_t zero) noexcept /* ************************************************************************ */ template -inline BasicVector& BasicVector::operator=(std::initializer_list data) noexcept +inline BasicVector& BasicVector::operator=(std::initializer_list data) { - CECE_ASSERT(data.size() == N); + CECE_ASSERT(data.size() == getSize()); using std::begin; auto it = begin(data); - for (int i = 0; i < N; ++i, ++it) - m_data[i] = *it; + for (int i = 0; i < getSize(); ++i, ++it) + m[i] = *it; return *this; } @@ -1385,13 +602,13 @@ inline BasicVector& BasicVector::operator=(std::initializer_list /* ************************************************************************ */ template -inline BasicVector& BasicVector::operator=(T (&data)[N]) noexcept +inline BasicVector& BasicVector::operator=(T (&data)[N]) { using std::begin; auto it = begin(data); - for (int i = 0; i < N; ++i, ++it) - m_data[i] = *it; + for (int i = 0; i < getSize(); ++i, ++it) + m[i] = *it; return *this; } @@ -1399,9 +616,9 @@ inline BasicVector& BasicVector::operator=(T (&data)[N]) noexcept /* ************************************************************************ */ template -inline BasicVector& BasicVector::operator=(StaticArray data) noexcept +inline BasicVector& BasicVector::operator=(const StaticArray& data) { - m_data = data; + m = data; return *this; } @@ -1409,10 +626,10 @@ inline BasicVector& BasicVector::operator=(StaticArray data) n /* ************************************************************************ */ template -inline BasicVector& BasicVector::operator=(const BasicVector& src) noexcept +inline BasicVector& BasicVector::operator=(const BasicVector& src) { - for (int i = 0; i < N; ++i) - m_data[i] = src.m_data[i]; + for (int i = 0; i < getSize(); ++i) + m[i] = src.m[i]; return *this; } @@ -1420,10 +637,10 @@ inline BasicVector& BasicVector::operator=(const BasicVector& src) n /* ************************************************************************ */ template -inline BasicVector& BasicVector::operator=(BasicVector&& src) noexcept +inline BasicVector& BasicVector::operator=(BasicVector&& src) { - for (int i = 0; i < N; ++i) - m_data[i] = std::move(src.m_data[i]); + for (int i = 0; i < getSize(); ++i) + m[i] = std::move(src.m[i]); return *this; } @@ -1432,133 +649,10 @@ inline BasicVector& BasicVector::operator=(BasicVector&& src) noexce template template::value>::type*> -inline BasicVector& BasicVector::operator=(const BasicVector& src) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] = T(src[i]); - - return *this; -} - -/* ************************************************************************ */ - -template -inline BasicVector BasicVector::operator+() const noexcept -{ - return *this; -} - -/* ************************************************************************ */ - -template -inline BasicVector BasicVector::operator-() const noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = -m_data[i]; - - return res; -} - -/* ************************************************************************ */ - -template -template() + std::declval()), - T ->::value>::type*> -inline BasicVector& BasicVector::operator+=(const BasicVector& rhs) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] += rhs[i]; - - return *this; -} - -/* ************************************************************************ */ - -template -template() - std::declval()), - T ->::value>::type*> -inline BasicVector& BasicVector::operator-=(const BasicVector& rhs) noexcept +inline BasicVector& BasicVector::operator=(const BasicVector& src) { - for (int i = 0; i < N; ++i) - m_data[i] -= rhs[i]; - - return *this; -} - -/* ************************************************************************ */ - -template -template() * std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline BasicVector& BasicVector::operator*=(T1 rhs) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] *= rhs; - - return *this; -} - -/* ************************************************************************ */ - -template -template() * std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline BasicVector& BasicVector::operator*=(const BasicVector& rhs) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] *= rhs[i]; - - return *this; -} - -/* ************************************************************************ */ - -template -template() / std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline BasicVector& BasicVector::operator/=(T1 rhs) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] /= rhs; - - return *this; -} - -/* ************************************************************************ */ - -template -template() / std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline BasicVector& BasicVector::operator/=(const BasicVector& rhs) noexcept -{ - for (int i = 0; i < N; ++i) - m_data[i] /= rhs[i]; + for (int i = 0; i < getSize(); ++i) + m[i] = T(src[i]); return *this; } @@ -1569,8 +663,8 @@ template inline T& BasicVector::operator[](int pos) noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < N); - return m_data[pos]; + CECE_ASSERT(pos < getSize()); + return m[pos]; } /* ************************************************************************ */ @@ -1579,8 +673,8 @@ template inline const T& BasicVector::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < N); - return m_data[pos]; + CECE_ASSERT(pos < getSize()); + return m[pos]; } /* ************************************************************************ */ @@ -1593,108 +687,6 @@ int BasicVector::getSize() const noexcept /* ************************************************************************ */ -template -inline bool BasicVector::inRange(T value, T low, T high) noexcept -{ - return value >= low && value < high; -} - -/* ************************************************************************ */ - -template -inline bool BasicVector::inRange(const BasicVector& low, const BasicVector& high) const noexcept -{ - bool res = true; - - for (int i = 0; i < N; ++i) - res = res && inRange(m_data[i], low[i], high[i]); - - return res; -} - -/* ************************************************************************ */ - -template -inline bool BasicVector::inRange(const BasicVector& high) const noexcept -{ - return inRange(Zero, high); -} - -/* ************************************************************************ */ - -template -inline typename BasicVector::ValueType BasicVector::getLength() const noexcept -{ - using std::sqrt; - return static_cast(sqrt(getLengthSquared())); -} - -/* ************************************************************************ */ - -template -inline typename BasicVector::ValueTypeSq BasicVector::getLengthSquared() const noexcept -{ - return dot(*this); -} - -/* ************************************************************************ */ - -template -inline typename BasicVector::ValueTypeSq BasicVector::dot(const BasicVector& rhs) const noexcept -{ - ValueTypeSq res{}; - - for (int i = 0; i < N; ++i) - res += m_data[i] * rhs[i]; - - return res; -} - -/* ************************************************************************ */ - -template -inline typename BasicVector::ValueTypeSq BasicVector::distanceSquared(const BasicVector& rhs) const noexcept -{ - return (*this - rhs).getLengthSquared(); -} - -/* ************************************************************************ */ - -template -inline typename BasicVector::ValueType BasicVector::distance(const BasicVector& rhs) const noexcept -{ - return (*this - rhs).getLength(); -} - -/* ************************************************************************ */ - -template -template -inline BasicVector BasicVector::inversed() const noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = T2(1) / m_data[i]; - - return res; -} - -/* ************************************************************************ */ - -template -inline BasicVector BasicVector::createSingle(T val) noexcept -{ - BasicVector res; - - for (int i = 0; i < N; ++i) - res[i] = val; - - return res; -} - -/* ************************************************************************ */ - } } diff --git a/include/cece/math/Vector2.hpp b/include/cece/math/Vector2.hpp index 2b2e376..4661074 100644 --- a/include/cece/math/Vector2.hpp +++ b/include/cece/math/Vector2.hpp @@ -28,14 +28,14 @@ /* ************************************************************************ */ // C++ -#include #include +#include // CeCe #include "cece/common.hpp" #include "cece/Assert.hpp" #include "cece/math/Zero.hpp" -#include "cece/unit/math.hpp" +#include "cece/math/VectorBase.hpp" #include "cece/unit/Units.hpp" /* ************************************************************************ */ @@ -51,7 +51,7 @@ namespace math { * @tparam T Element type. */ template -class Vector2 +class Vector2 : public VectorBase { @@ -62,18 +62,24 @@ class Vector2 /// Vector2 value type. using ValueType = T; - /// Element type squared. - using ValueTypeSq = decltype(std::declval() * std::declval()); - // Public Data Members public: - /// X coordinate. - T x; - /// Y coordinate. - T y; + union + { + struct + { + /// X coordinate. + T x; + + /// Y coordinate. + T y; + }; + + T m[2]; + }; // Public Ctors @@ -83,7 +89,15 @@ class Vector2 /** * @brief Default constructor. */ - Vector2() noexcept; + Vector2(); + + + /** + * @brief Constructor. + * + * @param x The X and Y coordinate. + */ + explicit Vector2(T value); /** @@ -92,7 +106,7 @@ class Vector2 * @param x The X coordinate. * @param y The Y coordinate. */ - Vector2(T x, T y) noexcept; + Vector2(T x, T y); /** @@ -100,7 +114,7 @@ class Vector2 * * @param[in] zero The zero value. */ - Vector2(Zero_t zero) noexcept; + Vector2(Zero_t zero); /** @@ -108,7 +122,7 @@ class Vector2 * * @param[in] src The source vector. */ - Vector2(const Vector2& src) noexcept; + Vector2(const Vector2& src); /** @@ -116,7 +130,7 @@ class Vector2 * * @param[in] src The source vector. */ - Vector2(Vector2&& src) noexcept; + Vector2(Vector2&& src); /** @@ -127,7 +141,7 @@ class Vector2 * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - Vector2(const Vector2& rhs) noexcept; + Vector2(const Vector2& rhs); // Public Operators @@ -141,7 +155,7 @@ class Vector2 * * @return *this. */ - Vector2& operator=(Zero_t zero) noexcept; + Vector2& operator=(Zero_t zero); /** @@ -151,7 +165,7 @@ class Vector2 * * @return *this. */ - Vector2& operator=(const Vector2& src) noexcept; + Vector2& operator=(const Vector2& src); /** @@ -161,7 +175,7 @@ class Vector2 * * @return *this. */ - Vector2& operator=(Vector2&& src) noexcept; + Vector2& operator=(Vector2&& src); /** @@ -174,93 +188,7 @@ class Vector2 * @return *this. */ template::value>::type* = nullptr> - Vector2& operator=(const Vector2& src) noexcept; - - - /** - * @brief Unary plus operator. - * - * @return Vector. - */ - Vector2 operator+() const noexcept; - - - /** - * @brief Unary minus operator. - * - * @return Vector. - */ - Vector2 operator-() const noexcept; - - - /** - * @brief Addition operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() + std::declval()), - T - >::value>::type* = nullptr> - Vector2& operator+=(const Vector2& rhs) noexcept; - - - /** - * @brief Subtraction operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in Vector2 operand. - * - * @return *this. - */ - template() - std::declval()), - T - >::value>::type* = nullptr> - Vector2& operator-=(const Vector2& rhs) noexcept; - - - /** - * @brief Multiplication operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() * std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector2& operator*=(T1 rhs) noexcept; - - - /** - * @brief Division operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() / std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector2& operator/=(T1 rhs) noexcept; + Vector2& operator=(const Vector2& src); /** @@ -287,6 +215,14 @@ class Vector2 public: + /** + * @brief Returns vector size. + * + * @return The size. + */ + int getSize() const noexcept; + + /** * @brief Returns X coordinate. * @@ -300,7 +236,7 @@ class Vector2 * * @param x The X coordinate. */ - void setX(T x) noexcept; + void setX(T x); /** @@ -316,273 +252,31 @@ class Vector2 * * @param y The Y coordinate. */ - void setY(T y) noexcept; - - - /** - * @brief Check if given value is in given range. - * - * @param value Given value. - * @param low Minimum value (>=). - * @param high Maximum value (<). - * - * @return If given value is in given range. - */ - static bool inRange(T value, T low, T high) noexcept; - - - /** - * @brief Check if current vector is in given range. - * - * @param low Minimum coordinates (>=). - * @param high Maximum coordinates (<). - * - * @return If current value is in given range. - */ - bool inRange(const Vector2& low, const Vector2& high) const noexcept; - - - /** - * @brief Check if current vector is in given range where the low range - * is Zero vector. - * - * @param high Maximum coordinates (<). - * - * @return If current value is in given range. - */ - bool inRange(const Vector2& high) const noexcept; - - -// Public Operations -public: - - - /** - * @brief Calculate vector length. - * - * @return The length. - */ - ValueType getLength() const noexcept; - - - /** - * @brief Calculate vector length - squared. - * - * @return The length squared. - */ - ValueTypeSq getLengthSquared() const noexcept; - - - /** - * @brief Calculate vectors squared distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - ValueTypeSq distanceSquared(const Vector2& rhs) const noexcept; - - - /** - * @brief Calculate vectors distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - ValueType distance(const Vector2& rhs) const noexcept; - - - /** - * @brief Inverse current vector (1 / *this). - * - * @tparam T2 Type of result vector's element. - * - * @return Inversed vector. - */ - template - Vector2 inversed() const noexcept; - - - /** - * @brief Rotate current vector counter-clockwise and return rotated - * version. - * - * @param angle Rotation angle. - * - * @return Rotated vector. - */ - Vector2 rotated(unit::Angle angle) const noexcept; - - - /** - * @brief Create from single value. - * - * @param val The value - * - * @return Vector of {val, val}. - */ - static Vector2 createSingle(T val) noexcept; + void setY(T y); }; /* ************************************************************************ */ -extern template class Vector2; -extern template class Vector2; -extern template class Vector2; -extern template class Vector2; - -/* ************************************************************************ */ - -/** - * @brief Addition operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -Vector2() + std::declval())> -operator+(const Vector2& lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Substract operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -Vector2() - std::declval())> -operator-(const Vector2& lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Multiplication operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -Vector2() * std::declval())> -operator*(const Vector2& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Multiplication operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -Vector2() * std::declval())> -operator*(T1 lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector2. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -Vector2() / std::declval())> -operator/(const Vector2& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector2. - * - * @return Result vector. - */ -template -Vector2() / std::declval())> -operator/(T1 lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Comparision result. - */ -template -bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept; - -/* ************************************************************************ */ - /** - * @brief Compare vectors. + * @brief Rotate the vector counter-clockwise and return rotated version. * - * @param lhs Left operand. - * @param rhs Right operand. + * @param[in] vec The vector. + * @param[in] angle Rotation angle. * - * @tparam T1 The first type. - * @tparam T2 The second type. + * @tparam T The vector element type. * - * @return Comparision result. + * @return Rotated vector. */ -template -bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept; +template +Vector2 rotate(const Vector2& vec, unit::Angle angle) noexcept; /* ************************************************************************ */ -/** - * @brief Calculate dot product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Dot product. - */ -template -decltype(std::declval() * std::declval()) -dot(const Vector2& lhs, const Vector2& rhs) noexcept; +extern template class Vector2; +extern template class Vector2; +extern template class Vector2; +extern template class Vector2; /* ************************************************************************ */ @@ -599,7 +293,7 @@ namespace math { /* ************************************************************************ */ template -inline Vector2::Vector2() noexcept +inline Vector2::Vector2() : x{} , y{} { @@ -609,7 +303,17 @@ inline Vector2::Vector2() noexcept /* ************************************************************************ */ template -inline Vector2::Vector2(T x, T y) noexcept +inline Vector2::Vector2(T val) + : x{val} + , y{val} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector2::Vector2(T x, T y) : x{std::move(x)} , y{std::move(y)} { @@ -619,7 +323,7 @@ inline Vector2::Vector2(T x, T y) noexcept /* ************************************************************************ */ template -inline Vector2::Vector2(Zero_t zero) noexcept +inline Vector2::Vector2(Zero_t zero) : x{} , y{} { @@ -629,7 +333,7 @@ inline Vector2::Vector2(Zero_t zero) noexcept /* ************************************************************************ */ template -inline Vector2::Vector2(const Vector2& src) noexcept +inline Vector2::Vector2(const Vector2& src) : x{src.getX()} , y{src.getY()} { @@ -639,7 +343,7 @@ inline Vector2::Vector2(const Vector2& src) noexcept /* ************************************************************************ */ template -inline Vector2::Vector2(Vector2&& src) noexcept +inline Vector2::Vector2(Vector2&& src) : x{std::move(src.x)} , y{std::move(src.y)} { @@ -650,7 +354,7 @@ inline Vector2::Vector2(Vector2&& src) noexcept template template::value>::type*> -inline Vector2::Vector2(const Vector2& rhs) noexcept +inline Vector2::Vector2(const Vector2& rhs) : x(rhs.getX()) , y(rhs.getY()) { @@ -660,7 +364,7 @@ inline Vector2::Vector2(const Vector2& rhs) noexcept /* ************************************************************************ */ template -inline Vector2& Vector2::operator=(Zero_t zero) noexcept +inline Vector2& Vector2::operator=(Zero_t zero) { x = T{}; y = T{}; @@ -671,7 +375,7 @@ inline Vector2& Vector2::operator=(Zero_t zero) noexcept /* ************************************************************************ */ template -inline Vector2& Vector2::operator=(const Vector2& src) noexcept +inline Vector2& Vector2::operator=(const Vector2& src) { x = src.x; y = src.y; @@ -682,7 +386,7 @@ inline Vector2& Vector2::operator=(const Vector2& src) noexcept /* ************************************************************************ */ template -inline Vector2& Vector2::operator=(Vector2&& src) noexcept +inline Vector2& Vector2::operator=(Vector2&& src) { x = std::move(src.x); y = std::move(src.y); @@ -694,7 +398,7 @@ inline Vector2& Vector2::operator=(Vector2&& src) noexcept template template::value>::type*> -inline Vector2& Vector2::operator=(const Vector2& src) noexcept +inline Vector2& Vector2::operator=(const Vector2& src) { x = T(src.getX()); y = T(src.getY()); @@ -705,103 +409,29 @@ inline Vector2& Vector2::operator=(const Vector2& src) noexcept /* ************************************************************************ */ template -inline Vector2 Vector2::operator+() const noexcept -{ - return *this; -} - -/* ************************************************************************ */ - -template -inline Vector2 Vector2::operator-() const noexcept -{ - return {-x, -y}; -} - -/* ************************************************************************ */ - -template -template() + std::declval()), - T ->::value>::type*> -inline Vector2& Vector2::operator+=(const Vector2& rhs) noexcept -{ - x += rhs.getX(); - y += rhs.getY(); - - return *this; -} - -/* ************************************************************************ */ - -template -template() - std::declval()), - T ->::value>::type*> -inline Vector2& Vector2::operator-=(const Vector2& rhs) noexcept -{ - x -= rhs.getX(); - y -= rhs.getY(); - - return *this; -} - -/* ************************************************************************ */ - -template -template() * std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector2& Vector2::operator*=(T1 rhs) noexcept -{ - x *= rhs; - y *= rhs; - - return *this; -} - -/* ************************************************************************ */ - -template -template() / std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector2& Vector2::operator/=(T1 rhs) noexcept +inline T& Vector2::operator[](int pos) noexcept { - x /= rhs; - y /= rhs; - - return *this; + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < getSize()); + return (&x)[pos]; } /* ************************************************************************ */ template -inline T& Vector2::operator[](int pos) noexcept +inline const T& Vector2::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < 2); + CECE_ASSERT(pos < getSize()); return (&x)[pos]; } /* ************************************************************************ */ template -inline const T& Vector2::operator[](int pos) const noexcept +inline int Vector2::getSize() const noexcept { - CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < 2); - return (&x)[pos]; + return 2; } /* ************************************************************************ */ @@ -815,7 +445,7 @@ inline const T& Vector2::getX() const noexcept /* ************************************************************************ */ template -inline void Vector2::setX(T x) noexcept +inline void Vector2::setX(T x) { this->x = std::move(x); } @@ -831,7 +461,7 @@ inline const T& Vector2::getY() const noexcept /* ************************************************************************ */ template -inline void Vector2::setY(T y) noexcept +inline void Vector2::setY(T y) { this->y = std::move(y); } @@ -839,194 +469,11 @@ inline void Vector2::setY(T y) noexcept /* ************************************************************************ */ template -inline bool Vector2::inRange(T value, T low, T high) noexcept -{ - return value >= low && value < high; -} - -/* ************************************************************************ */ - -template -inline bool Vector2::inRange(const Vector2& low, const Vector2& high) const noexcept -{ - bool res = true; - - res = res && inRange(getX(), low.getX(), high.getX()); - res = res && inRange(getY(), low.getY(), high.getY()); - - return res; -} - -/* ************************************************************************ */ - -template -inline bool Vector2::inRange(const Vector2& high) const noexcept -{ - return inRange(Zero, high); -} - -/* ************************************************************************ */ - -template -inline typename Vector2::ValueType Vector2::getLength() const noexcept -{ - using std::sqrt; - return static_cast(sqrt(getLengthSquared())); -} - -/* ************************************************************************ */ - -template -inline typename Vector2::ValueTypeSq Vector2::getLengthSquared() const noexcept -{ - return getX() * getX() + getY() * getY(); -} - -/* ************************************************************************ */ - -template -inline typename Vector2::ValueTypeSq Vector2::distanceSquared(const Vector2& rhs) const noexcept -{ - return (*this - rhs).getLengthSquared(); -} - -/* ************************************************************************ */ - -template -inline typename Vector2::ValueType Vector2::distance(const Vector2& rhs) const noexcept -{ - return (*this - rhs).getLength(); -} - -/* ************************************************************************ */ - -template -template -inline Vector2 Vector2::inversed() const noexcept -{ - return {T2(1) / getX(), T2(1) / getY()}; -} - -/* ************************************************************************ */ - -template -inline Vector2 Vector2::rotated(unit::Angle angle) const noexcept -{ - return { - static_cast(getX() * cos(static_cast(angle)) - getY() * sin(static_cast(angle))), - static_cast(getX() * sin(static_cast(angle)) + getY() * cos(static_cast(angle))) - }; -} - -/* ************************************************************************ */ - -template -inline Vector2 Vector2::createSingle(T val) noexcept -{ - return {val, val}; -} - -/* ************************************************************************ */ - -template -inline Vector2() + std::declval())> -operator+(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return { - lhs.getX() + rhs.getX(), - lhs.getY() + rhs.getY() - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() - std::declval())> -operator-(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return { - lhs.getX() - rhs.getX(), - lhs.getY() - rhs.getY() - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() * std::declval())> -operator*(const Vector2& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() * rhs, - lhs.getY() * rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() * std::declval())> -operator*(T1 lhs, const Vector2& rhs) noexcept -{ - return { - lhs * rhs.getX(), - lhs * rhs.getY() - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() / std::declval())> -operator/(const Vector2& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() / rhs, - lhs.getY() / rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector2() / std::declval())> -operator/(T1 lhs, const Vector2& rhs) noexcept -{ - return { - lhs / rhs.getX(), - lhs / rhs.getY() - }; -} - -/* ************************************************************************ */ - -template -inline bool operator==(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return - lhs.getX() == rhs.getX() && - lhs.getY() == rhs.getY() - ; -} - -/* ************************************************************************ */ - -template -inline bool operator!=(const Vector2& lhs, const Vector2& rhs) noexcept -{ - return !operator==(lhs, rhs); -} - -/* ************************************************************************ */ - -template -inline -decltype(std::declval() * std::declval()) -dot(const Vector2& lhs, const Vector2& rhs) noexcept +inline Vector2 rotate(const Vector2& vec, unit::Angle angle) noexcept { return { - lhs.getX() * rhs.getX() + - lhs.getY() * rhs.getY() + static_cast(vec.getX() * cos(static_cast(angle)) - vec.getY() * sin(static_cast(angle))), + static_cast(vec.getX() * sin(static_cast(angle)) + vec.getY() * cos(static_cast(angle))) }; } diff --git a/include/cece/math/Vector3.hpp b/include/cece/math/Vector3.hpp index 2fd79cc..bfaeeca 100644 --- a/include/cece/math/Vector3.hpp +++ b/include/cece/math/Vector3.hpp @@ -28,15 +28,14 @@ /* ************************************************************************ */ // C++ -#include #include +#include // CeCe #include "cece/common.hpp" #include "cece/Assert.hpp" #include "cece/math/Zero.hpp" -#include "cece/unit/math.hpp" -#include "cece/unit/Units.hpp" +#include "cece/math/VectorBase.hpp" /* ************************************************************************ */ @@ -51,7 +50,7 @@ namespace math { * @tparam T Element type. */ template -class Vector3 +class Vector3 : public VectorBase { @@ -62,22 +61,27 @@ class Vector3 /// Vector3 value type. using ValueType = T; - /// Element type squared. - using ValueTypeSq = decltype(std::declval() * std::declval()); - // Public Data Members public: - /// X coordinate. - T x; + union + { + struct + { + /// X coordinate. + T x; + + /// Y coordinate. + T y; - /// Y coordinate. - T y; + /// Z coordinate. + T z; + }; - /// Z coordinate. - T z; + T m[3]; + }; // Public Ctors @@ -90,6 +94,14 @@ class Vector3 Vector3() noexcept; + /** + * @brief Constructor. + * + * @param val The X, Y and Z coordinate. + */ + explicit Vector3(T val); + + /** * @brief Constructor. * @@ -97,7 +109,7 @@ class Vector3 * @param y The Y coordinate. * @param y The Z coordinate. */ - Vector3(T x, T y, T z) noexcept; + Vector3(T x, T y, T z); /** @@ -105,7 +117,7 @@ class Vector3 * * @param[in] zero The zero value. */ - Vector3(Zero_t zero) noexcept; + Vector3(Zero_t zero); /** @@ -113,7 +125,7 @@ class Vector3 * * @param[in] src The source vector. */ - Vector3(const Vector3& src) noexcept; + Vector3(const Vector3& src); /** @@ -121,7 +133,7 @@ class Vector3 * * @param[in] src The source vector. */ - Vector3(Vector3&& src) noexcept; + Vector3(Vector3&& src); /** @@ -132,7 +144,7 @@ class Vector3 * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - Vector3(const Vector3& rhs) noexcept; + Vector3(const Vector3& rhs); // Public Operators @@ -146,7 +158,7 @@ class Vector3 * * @return *this. */ - Vector3& operator=(Zero_t zero) noexcept; + Vector3& operator=(Zero_t zero); /** @@ -156,7 +168,7 @@ class Vector3 * * @return *this. */ - Vector3& operator=(const Vector3& src) noexcept; + Vector3& operator=(const Vector3& src); /** @@ -166,7 +178,7 @@ class Vector3 * * @return *this. */ - Vector3& operator=(Vector3&& src) noexcept; + Vector3& operator=(Vector3&& src); /** @@ -179,93 +191,7 @@ class Vector3 * @return *this. */ template::value>::type* = nullptr> - Vector3& operator=(const Vector3& src) noexcept; - - - /** - * @brief Unary plus operator. - * - * @return Vector. - */ - Vector3 operator+() const noexcept; - - - /** - * @brief Unary minus operator. - * - * @return Vector. - */ - Vector3 operator-() const noexcept; - - - /** - * @brief Addition operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() + std::declval()), - T - >::value>::type* = nullptr> - Vector3& operator+=(const Vector3& rhs) noexcept; - - - /** - * @brief Subtraction operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of value in Vector3 operand. - * - * @return *this. - */ - template() - std::declval()), - T - >::value>::type* = nullptr> - Vector3& operator-=(const Vector3& rhs) noexcept; - - - /** - * @brief Multiplication operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() * std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector3& operator*=(T1 rhs) noexcept; - - - /** - * @brief Division operator. - * - * @param rhs Right operand. - * - * @tparam T1 Type of right operand. - * - * @return *this. - */ - template() / std::declval()), - T - >::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) - >::value>::type* = nullptr> - Vector3& operator/=(T1 rhs) noexcept; + Vector3& operator=(const Vector3& src); /** @@ -292,6 +218,14 @@ class Vector3 public: + /** + * @brief Returns vector size. + * + * @return The size. + */ + int getSize() const noexcept; + + /** * @brief Returns X coordinate. * @@ -305,7 +239,7 @@ class Vector3 * * @param x The X coordinate. */ - void setX(T x) noexcept; + void setX(T x); /** @@ -321,7 +255,7 @@ class Vector3 * * @param y The Y coordinate. */ - void setY(T y) noexcept; + void setY(T y); /** @@ -337,112 +271,7 @@ class Vector3 * * @param z The Z coordinate. */ - void setZ(T z) noexcept; - - - /** - * @brief Check if given value is in given range. - * - * @param value Given value. - * @param low Minimum value (>=). - * @param high Maximum value (<). - * - * @return If given value is in given range. - */ - static bool inRange(T value, T low, T high) noexcept; - - - /** - * @brief Check if current vector is in given range. - * - * @param low Minimum coordinates (>=). - * @param high Maximum coordinates (<). - * - * @return If current value is in given range. - */ - bool inRange(const Vector3& low, const Vector3& high) const noexcept; - - - /** - * @brief Check if current vector is in given range where the low range - * is Zero vector. - * - * @param high Maximum coordinates (<). - * - * @return If current value is in given range. - */ - bool inRange(const Vector3& high) const noexcept; - - -// Public Operations -public: - - - /** - * @brief Calculate vector length. - * - * @return The length. - */ - ValueType getLength() const noexcept; - - - /** - * @brief Calculate vector length - squared. - * - * @return The length squared. - */ - ValueTypeSq getLengthSquared() const noexcept; - - - /** - * @brief Calculate vectors squared distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - ValueTypeSq distanceSquared(const Vector3& rhs) const noexcept; - - - /** - * @brief Calculate vectors distance. - * - * @param rhs Second vector. - * - * @return Distance. - */ - ValueType distance(const Vector3& rhs) const noexcept; - - - /** - * @brief Inverse current vector (1 / *this). - * - * @tparam T2 Type of result vector's element. - * - * @return Inversed vector. - */ - template - Vector3 inversed() const noexcept; - - - /** - * @brief Rotate current vector and return rotated version. - * - * @param angle Rotation angle. - * - * @return Rotated vector. - */ - Vector3 rotated(unit::Angle angle) const noexcept; - - - /** - * @brief Create from single value. - * - * @param val The value - * - * @return Vector of {val, val}. - */ - static Vector3 createSingle(T val) noexcept; + void setZ(T z); }; @@ -455,140 +284,6 @@ extern template class Vector3; /* ************************************************************************ */ -/** - * @brief Addition operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() + std::declval())> -operator+(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Substract operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() - std::declval())> -operator-(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Multiplication operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -inline Vector3() * std::declval())> -operator*(const Vector3& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Multiplication operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() * std::declval())> -operator*(T1 lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of value in first Vector3. - * @tparam T2 Type of second operand. - * - * @return Result vector. - */ -template -inline Vector3() / std::declval())> -operator/(const Vector3& lhs, T2 rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Division operator. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 Type of first operand. - * @tparam T2 Type of value in second Vector3. - * - * @return Result vector. - */ -template -inline Vector3() / std::declval())> -operator/(T1 lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Comparision result. - */ -template -inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Compare vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Comparision result. - */ -template -bool operator!=(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - /** * @brief Calculate cross product of two vectors. * @@ -602,24 +297,7 @@ bool operator!=(const Vector3& lhs, const Vector3& rhs) noexcept; */ template Vector3() * std::declval())> -cross(const Vector3& lhs, const Vector3& rhs) noexcept; - -/* ************************************************************************ */ - -/** - * @brief Calculate dot product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Dot product. - */ -template -decltype(std::declval() * std::declval()) -dot(const Vector3& lhs, const Vector3& rhs) noexcept; +cross(const Vector3& lhs, const Vector3& rhs); /* ************************************************************************ */ @@ -647,10 +325,21 @@ inline Vector3::Vector3() noexcept /* ************************************************************************ */ template -inline Vector3::Vector3(T x, T y, T z) noexcept - : x(x) - , y(y) - , z(z) +inline Vector3::Vector3(T val) + : x{val} + , y{val} + , z{val} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector3::Vector3(T x, T y, T z) + : x{std::move(x)} + , y{std::move(y)} + , z{std::move(z)} { // Nothing to do } @@ -658,7 +347,7 @@ inline Vector3::Vector3(T x, T y, T z) noexcept /* ************************************************************************ */ template -inline Vector3::Vector3(Zero_t zero) noexcept +inline Vector3::Vector3(Zero_t zero) : x{} , y{} , z{} @@ -669,7 +358,7 @@ inline Vector3::Vector3(Zero_t zero) noexcept /* ************************************************************************ */ template -inline Vector3::Vector3(const Vector3& src) noexcept +inline Vector3::Vector3(const Vector3& src) : x{src.getX()} , y{src.getY()} , z{src.getZ()} @@ -680,7 +369,7 @@ inline Vector3::Vector3(const Vector3& src) noexcept /* ************************************************************************ */ template -inline Vector3::Vector3(Vector3&& src) noexcept +inline Vector3::Vector3(Vector3&& src) : x{std::move(src.x)} , y{std::move(src.y)} , z{std::move(src.z)} @@ -692,7 +381,7 @@ inline Vector3::Vector3(Vector3&& src) noexcept template template::value>::type*> -inline Vector3::Vector3(const Vector3& rhs) noexcept +inline Vector3::Vector3(const Vector3& rhs) : x(rhs.getX()) , y(rhs.getY()) , z(rhs.getZ()) @@ -703,7 +392,7 @@ inline Vector3::Vector3(const Vector3& rhs) noexcept /* ************************************************************************ */ template -inline Vector3& Vector3::operator=(Zero_t zero) noexcept +inline Vector3& Vector3::operator=(Zero_t zero) { x = T{}; y = T{}; @@ -715,7 +404,7 @@ inline Vector3& Vector3::operator=(Zero_t zero) noexcept /* ************************************************************************ */ template -inline Vector3& Vector3::operator=(const Vector3& src) noexcept +inline Vector3& Vector3::operator=(const Vector3& src) { x = src.x; y = src.y; @@ -727,7 +416,7 @@ inline Vector3& Vector3::operator=(const Vector3& src) noexcept /* ************************************************************************ */ template -inline Vector3& Vector3::operator=(Vector3&& src) noexcept +inline Vector3& Vector3::operator=(Vector3&& src) { x = std::move(src.x); y = std::move(src.y); @@ -740,7 +429,7 @@ inline Vector3& Vector3::operator=(Vector3&& src) noexcept template template::value>::type*> -inline Vector3& Vector3::operator=(const Vector3& src) noexcept +inline Vector3& Vector3::operator=(const Vector3& src) { x = T(src.getX()); y = T(src.getY()); @@ -752,87 +441,9 @@ inline Vector3& Vector3::operator=(const Vector3& src) noexcept /* ************************************************************************ */ template -inline Vector3 Vector3::operator+() const noexcept -{ - return *this; -} - -/* ************************************************************************ */ - -template -inline Vector3 Vector3::operator-() const noexcept +inline int Vector3::getSize() const noexcept { - return {-x, -y, -z}; -} - -/* ************************************************************************ */ - -template -template() + std::declval()), - T ->::value>::type*> -inline Vector3& Vector3::operator+=(const Vector3& rhs) noexcept -{ - x += rhs.getX(); - y += rhs.getY(); - z += rhs.getZ(); - - return *this; -} - -/* ************************************************************************ */ - -template -template() - std::declval()), - T ->::value>::type*> -inline Vector3& Vector3::operator-=(const Vector3& rhs) noexcept -{ - x -= rhs.getX(); - y -= rhs.getY(); - z -= rhs.getZ(); - - return *this; -} - -/* ************************************************************************ */ - -template -template() * std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector3& Vector3::operator*=(T1 rhs) noexcept -{ - x *= rhs; - y *= rhs; - z *= rhs; - - return *this; -} - -/* ************************************************************************ */ - -template -template() / std::declval()), - T ->::value || std::is_constructible< - T, - decltype(std::declval() * std::declval()) ->::value>::type*> -inline Vector3& Vector3::operator/=(T1 rhs) noexcept -{ - x /= rhs; - y /= rhs; - z /= rhs; - - return *this; + return 3; } /* ************************************************************************ */ @@ -841,7 +452,7 @@ template inline T& Vector3::operator[](int pos) noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < 3); + CECE_ASSERT(pos < getSize()); return (&x)[pos]; } @@ -851,7 +462,7 @@ template inline const T& Vector3::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < 3); + CECE_ASSERT(pos < getSize()); return (&x)[pos]; } @@ -866,7 +477,7 @@ inline const T& Vector3::getX() const noexcept /* ************************************************************************ */ template -inline void Vector3::setX(T x) noexcept +inline void Vector3::setX(T x) { this->x = std::move(x); } @@ -882,7 +493,7 @@ inline const T& Vector3::getY() const noexcept /* ************************************************************************ */ template -inline void Vector3::setY(T y) noexcept +inline void Vector3::setY(T y) { this->y = std::move(y); } @@ -898,203 +509,18 @@ inline const T& Vector3::getZ() const noexcept /* ************************************************************************ */ template -inline void Vector3::setZ(T z) noexcept +inline void Vector3::setZ(T z) { this->z = std::move(z); } /* ************************************************************************ */ -template -inline bool Vector3::inRange(T value, T low, T high) noexcept -{ - return value >= low && value < high; -} - -/* ************************************************************************ */ - -template -inline bool Vector3::inRange(const Vector3& low, const Vector3& high) const noexcept -{ - bool res = true; - - res = res && inRange(getX(), low.getX(), high.getX()); - res = res && inRange(getY(), low.getY(), high.getY()); - res = res && inRange(getZ(), low.getZ(), high.getZ()); - - return res; -} - -/* ************************************************************************ */ - -template -inline bool Vector3::inRange(const Vector3& high) const noexcept -{ - return inRange(Zero, high); -} - -/* ************************************************************************ */ - -template -inline typename Vector3::ValueType Vector3::getLength() const noexcept -{ - using std::sqrt; - return static_cast(sqrt(getLengthSquared())); -} - -/* ************************************************************************ */ - -template -inline typename Vector3::ValueTypeSq Vector3::getLengthSquared() const noexcept -{ - return - getX() * getX() + - getY() * getY() + - getZ() * getZ() - ; -} - -/* ************************************************************************ */ - -template -inline typename Vector3::ValueTypeSq Vector3::distanceSquared(const Vector3& rhs) const noexcept -{ - return (*this - rhs).getLengthSquared(); -} - -/* ************************************************************************ */ - -template -inline typename Vector3::ValueType Vector3::distance(const Vector3& rhs) const noexcept -{ - return (*this - rhs).getLength(); -} - -/* ************************************************************************ */ - -template -template -inline Vector3 Vector3::inversed() const noexcept -{ - return { - T2(1) / getX(), - T2(1) / getY(), - T2(1) / getZ() - }; -} - -/* ************************************************************************ */ - -template -inline Vector3 Vector3::createSingle(T val) noexcept -{ - return {val, val, val}; -} - -/* ************************************************************************ */ - -template -inline Vector3() + std::declval())> -operator+(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return { - lhs.getX() + rhs.getX(), - lhs.getY() + rhs.getY(), - lhs.getZ() + rhs.getZ() - }; -} - -/* ************************************************************************ */ - -template -inline Vector3() - std::declval())> -operator-(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return { - lhs.getX() - rhs.getX(), - lhs.getY() - rhs.getY(), - lhs.getZ() - rhs.getZ() - }; -} - -/* ************************************************************************ */ - -template -inline Vector3() * std::declval())> -operator*(const Vector3& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() * rhs, - lhs.getY() * rhs, - lhs.getZ() * rhs - }; -} - -/* ************************************************************************ */ - template -inline Vector3() * std::declval())> -operator*(T1 lhs, const Vector3& rhs) noexcept -{ - return { - lhs * rhs.getX(), - lhs * rhs.getY(), - lhs * rhs.getZ() - }; -} - -/* ************************************************************************ */ - -template -inline Vector3() / std::declval())> -operator/(const Vector3& lhs, T2 rhs) noexcept -{ - return { - lhs.getX() / rhs, - lhs.getY() / rhs, - lhs.getZ() / rhs - }; -} - -/* ************************************************************************ */ - -template -inline Vector3() / std::declval())> -operator/(T1 lhs, const Vector3& rhs) noexcept -{ - return { - lhs / rhs.getX(), - lhs / rhs.getY(), - lhs / rhs.getZ() - }; -} - -/* ************************************************************************ */ - -template -inline bool operator==(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return - lhs.getX() == rhs.getX() && - lhs.getY() == rhs.getY() && - lhs.getZ() == rhs.getZ() - ; -} - -/* ************************************************************************ */ - -template -inline bool operator!=(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return !operator==(lhs, rhs); -} - -/* ************************************************************************ */ - -template -inline -Vector3() * std::declval())> -cross(const Vector3& lhs, const Vector3& rhs) noexcept +inline Vector3() * std::declval())> cross( + const Vector3& lhs, + const Vector3& rhs +) { return { lhs.getY() * rhs.getZ() - lhs.getZ() * rhs.getY(), @@ -1105,20 +531,6 @@ cross(const Vector3& lhs, const Vector3& rhs) noexcept /* ************************************************************************ */ -template -inline -decltype(std::declval() * std::declval()) -dot(const Vector3& lhs, const Vector3& rhs) noexcept -{ - return { - lhs.getX() * rhs.getX() + - lhs.getY() * rhs.getY() + - lhs.getZ() * rhs.getZ() - }; -} - -/* ************************************************************************ */ - } } diff --git a/include/cece/math/VectorBase.hpp b/include/cece/math/VectorBase.hpp new file mode 100644 index 0000000..216169c --- /dev/null +++ b/include/cece/math/VectorBase.hpp @@ -0,0 +1,1117 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +#pragma once + +/* ************************************************************************ */ + +// C++ +#include +#include + +// CeCe +#include "cece/common.hpp" +#include "cece/Assert.hpp" +#include "cece/math/Zero.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +/** + * @brief Vector adaptor. + * + * @tparam VectorType The vector type. + * @tparam T Value type. + * @tparam Tags Additional tags. + */ +template< + template typename VectorType, + typename T, + int... Tags +> +class VectorBase +{ + +// Public Types +public: + + + /// VectorBase value type. + using ValueType = T; + + +// Public Operators +public: + + + /** + * @brief Unary plus operator. + * + * @return Vector. + */ + VectorType operator+() const noexcept; + + + /** + * @brief Unary minus operator. + * + * @return Vector. + */ + VectorType operator-() const noexcept; + + + /** + * @brief Addition operator. + * + * @param rhs The right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + VectorType& operator+=(const VectorType& rhs); + + + /** + * @brief Subtraction operator. + * + * @param rhs The right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + VectorType& operator-=(const VectorType& rhs); + + + /** + * @brief Multiplication operator. + * + * @param rhs The right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template + VectorType& operator*=(T1 rhs); + + + /** + * @brief Multiplication operator. + * + * @param rhs The right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + VectorType& operator*=(const VectorType& rhs); + + + /** + * @brief Division operator. + * + * @param rhs The right operand. + * + * @tparam T1 Type of right operand. + * + * @return *this. + */ + template + VectorType& operator/=(T1 rhs); + + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + VectorType& operator/=(const VectorType& rhs); + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + T& operator[](int pos); + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + const T& operator[](int pos) const; + + +// Public Accessors +public: + + + /** + * @brief Returns vector size. + * + * @return The size. + */ + int getSize() const; + + +// Public Operations +public: + + + /** + * @brief Calculate vector length. + * + * @return The length. + */ + T getLength() const; + + + /** + * @brief Calculate vector length - squared. + * + * @return The length squared. + */ + decltype(std::declval() * std::declval()) getLengthSquared() const; + +}; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() + std::declval()), Tags...> operator+( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Substract operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() - std::declval()), Tags...> operator-( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() * std::declval()), Tags...> operator*( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() * std::declval()), Tags...> operator*( + const VectorType& lhs, + const T2& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() * std::declval()), Tags...> operator*( + const T1& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() / std::declval()), Tags...> operator/( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() / std::declval()), Tags...> operator/( + const VectorType& lhs, + const T2& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Division operator. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Result vector. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +VectorType() / std::declval()), Tags...> operator/( + const T1& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +bool operator==( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, int... Tags> +bool operator==( + const VectorType& lhs, + const Zero_t& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T2, int... Tags> +bool operator==( + const Zero_t& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +bool operator!=( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, int... Tags> +bool operator!=( + const VectorType& lhs, + const Zero_t& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T2, int... Tags> +bool operator!=( + const Zero_t& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +bool operator<( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +bool operator<=( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +bool operator>( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Compare vectors. + * + * @param lhs The left operand. + * @param rhs The right operand. + * + * @tparam VectorType Vector type. + * @tparam T1 Type of value in first VectorBase. + * @tparam T2 Type of value in second VectorBase. + * @tparam Tags Vector type tags. + * + * @return Operation result. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +bool operator>=( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Calculate dot product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @return Dot product. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +decltype(std::declval() * std::declval()) dot( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Calculate distance of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @return Distance. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +decltype(std::declval() - std::declval())>() * std::declval() - std::declval())>()) distanceSquared( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Calculate distance of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @return Distance. + */ +template typename VectorType, typename T1, typename T2, int... Tags> +decltype(std::declval() - std::declval()) distance( + const VectorType& lhs, + const VectorType& rhs +); + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline VectorType VectorBase::operator+() const noexcept +{ + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline VectorType VectorBase::operator-() const noexcept +{ + VectorType res; + + for (int i = 0; i < getSize(); ++i) + res[i] = -(*this)[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +template +inline VectorType& VectorBase::operator+=(const VectorType& rhs) +{ + for (int i = 0; i < getSize(); ++i) + (*this)[i] += rhs[i]; + + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +template +inline VectorType& VectorBase::operator-=(const VectorType& rhs) +{ + for (int i = 0; i < getSize(); ++i) + (*this)[i] -= rhs[i]; + + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +template +inline VectorType& VectorBase::operator*=(T1 rhs) +{ + for (int i = 0; i < getSize(); ++i) + (*this)[i] *= rhs; + + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +template +inline VectorType& VectorBase::operator*=(const VectorType& rhs) +{ + for (int i = 0; i < getSize(); ++i) + (*this)[i] *= rhs[i]; + + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +template +inline VectorType& VectorBase::operator/=(T1 rhs) +{ + for (int i = 0; i < getSize(); ++i) + (*this)[i] /= rhs; + + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +template +inline VectorType& VectorBase::operator/=(const VectorType& rhs) +{ + for (int i = 0; i < getSize(); ++i) + (*this)[i] /= rhs[i]; + + return *static_cast*>(this); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline T& VectorBase::operator[](int pos) +{ + // TODO: recursion possibility + return (*static_cast*>(this))[pos]; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline const T& VectorBase::operator[](int pos) const +{ + // TODO: recursion possibility + return (*static_cast*>(this))[pos]; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline int VectorBase::getSize() const +{ + // TODO: recursion possibility + return static_cast*>(this)->getSize(); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline T VectorBase::getLength() const +{ + using std::sqrt; + return static_cast(sqrt(getLengthSquared())); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline decltype(std::declval() * std::declval()) VectorBase::getLengthSquared() const +{ + decltype(std::declval() * std::declval()) res{}; + + for (int i = 0; i < getSize(); ++i) + res += (*this)[i] * (*this)[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() + std::declval()), Tags...> operator+( + const VectorType& lhs, + const VectorType& rhs +) +{ + VectorType() + std::declval()), Tags...> res; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + CECE_ASSERT(res.getSize() == lhs.getSize()); + CECE_ASSERT(res.getSize() == rhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs[i] + rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() - std::declval()), Tags...> operator-( + const VectorType& lhs, + const VectorType& rhs +) +{ + VectorType() - std::declval()), Tags...> res; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + CECE_ASSERT(res.getSize() == lhs.getSize()); + CECE_ASSERT(res.getSize() == rhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs[i] - rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() * std::declval()), Tags...> operator*( + const VectorType& lhs, + const VectorType& rhs +) +{ + VectorType() * std::declval()), Tags...> res; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + CECE_ASSERT(res.getSize() == lhs.getSize()); + CECE_ASSERT(res.getSize() == rhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs[i] * rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() * std::declval()), Tags...> operator*( + const VectorType& lhs, + const T2& rhs +) +{ + VectorType() * std::declval()), Tags...> res; + + CECE_ASSERT(res.getSize() == lhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs[i] * rhs; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() * std::declval()), Tags...> operator*( + const T1& lhs, + const VectorType& rhs +) +{ + VectorType() * std::declval()), Tags...> res; + + CECE_ASSERT(res.getSize() == rhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs * rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() / std::declval()), Tags...> operator/( + const VectorType& lhs, + const VectorType& rhs +) +{ + VectorType() / std::declval()), Tags...> res; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + CECE_ASSERT(res.getSize() == lhs.getSize()); + CECE_ASSERT(res.getSize() == rhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs[i] / rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() / std::declval()), Tags...> operator/( + const VectorType& lhs, + const T2& rhs +) +{ + VectorType() / std::declval()), Tags...> res; + + CECE_ASSERT(res.getSize() == lhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs[i] / rhs; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline VectorType() / std::declval()), Tags...> operator/( + const T1& lhs, + const VectorType& rhs +) +{ + VectorType() / std::declval()), Tags...> res; + + CECE_ASSERT(res.getSize() == rhs.getSize()); + + for (int i = 0; i < res.getSize(); ++i) + res[i] = lhs / rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline bool operator==( + const VectorType& lhs, + const VectorType& rhs +) +{ + bool res = true; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + + for (int i = 0; i < lhs.getSize(); ++i) + res = res && lhs[i] == rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, int... Tags> +inline bool operator==( + const VectorType& lhs, + const Zero_t& rhs +) +{ + return operator==(lhs, VectorType(Zero)); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T2, int... Tags> +inline bool operator==( + const Zero_t& lhs, + const VectorType& rhs +) +{ + return operator==(VectorType(lhs), rhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline bool operator!=( + const VectorType& lhs, + const VectorType& rhs +) +{ + return !operator==(lhs, rhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, int... Tags> +inline bool operator!=( + const VectorType& lhs, + const Zero_t& rhs +) +{ + return !operator==(lhs, rhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T2, int... Tags> +inline bool operator!=( + const Zero_t& lhs, + const VectorType& rhs +) +{ + return !operator==(lhs, rhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline bool operator<( + const VectorType& lhs, + const VectorType& rhs +) +{ + bool res = true; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + + for (int i = 0; i < lhs.getSize(); ++i) + res = res && (lhs[i] < rhs[i]); + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline bool operator<=( + const VectorType& lhs, + const VectorType& rhs +) +{ + return !operator>(lhs, rhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline bool operator>( + const VectorType& lhs, + const VectorType& rhs +) +{ + return operator<(rhs, lhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline bool operator>=( + const VectorType& lhs, + const VectorType& rhs +) +{ + return !operator<(lhs, rhs); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline decltype(std::declval() * std::declval()) dot( + const VectorType& lhs, + const VectorType& rhs +) +{ + decltype(std::declval() * std::declval()) res{}; + + CECE_ASSERT(lhs.getSize() == rhs.getSize()); + + for (int i = 0; i < lhs.getSize(); ++i) + res += lhs[i] * rhs[i]; + + return res; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline decltype(std::declval() - std::declval())>() * std::declval() - std::declval())>()) distanceSquared( + const VectorType& lhs, + const VectorType& rhs +) +{ + return (lhs - rhs).getLengthSquared(); +} + +/* ************************************************************************ */ + +template typename VectorType, typename T1, typename T2, int... Tags> +inline decltype(std::declval() - std::declval()) distance( + const VectorType& lhs, + const VectorType& rhs +) +{ + return (lhs - rhs).getLength(); +} + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ diff --git a/include/cece/math/VectorRange.hpp b/include/cece/math/VectorRange.hpp index e9f708e..4ef1912 100644 --- a/include/cece/math/VectorRange.hpp +++ b/include/cece/math/VectorRange.hpp @@ -203,7 +203,7 @@ template constexpr IteratorRange> range(Vector begin, Vector end) noexcept { return makeRange( - IteratorVector{begin, end - T{1}, begin}, + IteratorVector{begin, end - Vector{1}, begin}, IteratorVector{Vector{begin.getX(), end.getY()}, Zero, Zero} ); } diff --git a/unittests/math/CMakeLists.txt b/unittests/math/CMakeLists.txt index 4893905..97ea6a5 100644 --- a/unittests/math/CMakeLists.txt +++ b/unittests/math/CMakeLists.txt @@ -25,6 +25,7 @@ cece_add_test(math SOURCES + VectorBase_test.cpp Vector_test.cpp Vector2_test.cpp Vector3_test.cpp diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp index 48aaa1d..e6bad88 100644 --- a/unittests/math/Vector2_test.cpp +++ b/unittests/math/Vector2_test.cpp @@ -28,6 +28,7 @@ // CeCe #include "cece/math/Vector2.hpp" +#include "cece/unit/math.hpp" /* ************************************************************************ */ @@ -56,6 +57,16 @@ TEST(Vector2, ctor) EXPECT_EQ(0, vec[1]); } + { + Vector2 vec(12.3f); + + EXPECT_FLOAT_EQ(12.3f, vec.getX()); + EXPECT_FLOAT_EQ(12.3f, vec.getY()); + EXPECT_FLOAT_EQ(12.3f, vec[0]); + EXPECT_FLOAT_EQ(12.3f, vec[1]); + } + + { Vector2 vec = {1.2f, 3.0f}; @@ -266,36 +277,6 @@ TEST(Vector2, operators) /* ************************************************************************ */ -TEST(Vector2, inRange) -{ - { - const Vector2 vecMin{-10.0f, -5.0f}; - const Vector2 vecMax{10.0f, 20.0f}; - - Vector2 vec1; - Vector2 vec2{-15.0f, 0.0f}; - Vector2 vec3{5.0f, 0.0f}; - - EXPECT_TRUE(vec1.inRange(vecMin, vecMax)); - EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); - EXPECT_TRUE(vec3.inRange(vecMin, vecMax)); - } - - { - const Vector2 vecMax{10.0f, 20.0f}; - - Vector2 vec1; - Vector2 vec2{-15.0f, 0.0f}; - Vector2 vec3{5.0f, 0.0f}; - - EXPECT_TRUE(vec1.inRange(vecMax)); - EXPECT_FALSE(vec2.inRange(vecMax)); - EXPECT_TRUE(vec3.inRange(vecMax)); - } -} - -/* ************************************************************************ */ - TEST(Vector2, memberFunctions) { { @@ -321,55 +302,6 @@ TEST(Vector2, memberFunctions) EXPECT_FLOAT_EQ(5, vec.getLengthSquared()); } - - { - const Vector2 vec; - - EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); - } - - { - const Vector2 vec{1.0f, 2.0f}; - - EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); - } - - { - const Vector2 vec1{1.0f, 2.0f}; - const Vector2 vec2{5.0f, 4.0f}; - - EXPECT_FLOAT_EQ(20.0f, vec1.distanceSquared(vec2)); - } - - { - const Vector2 vec1{1.0f, 2.0f}; - const Vector2 vec2{5.0f, 4.0f}; - - EXPECT_FLOAT_EQ(4.4721360f, vec1.distance(vec2)); - } - - { - const Vector2 vec{1.0f, 2.0f}; - - auto inv = vec.inversed(); - - EXPECT_FLOAT_EQ(1.0f, inv[0]); - EXPECT_FLOAT_EQ(0.5f, inv[1]); - } - - { - auto vec = Vector2::createSingle(1); - - EXPECT_FLOAT_EQ(1.0f, vec[0]); - EXPECT_FLOAT_EQ(1.0f, vec[1]); - } - - { - auto vec = Vector2::createSingle(375.1721f); - - EXPECT_FLOAT_EQ(375.1721f, vec[0]); - EXPECT_FLOAT_EQ(375.1721f, vec[1]); - } } /* ************************************************************************ */ @@ -421,7 +353,7 @@ TEST(Vector2, functions) EXPECT_EQ(1, vec.getX()); EXPECT_EQ(0, vec.getY()); - auto rot = vec.rotated(unit::deg2rad(90)); + auto rot = rotate(vec, unit::deg2rad(90)); EXPECT_EQ(0, rot.getX()); EXPECT_EQ(1, rot.getY()); @@ -433,7 +365,7 @@ TEST(Vector2, functions) EXPECT_EQ(1, vec.getX()); EXPECT_EQ(0, vec.getY()); - auto rot = vec.rotated(unit::deg2rad(-90)); + auto rot = rotate(vec, unit::deg2rad(-90)); EXPECT_EQ(0, rot.getX()); EXPECT_EQ(-1, rot.getY()); @@ -445,7 +377,7 @@ TEST(Vector2, functions) EXPECT_EQ(1, vec.getX()); EXPECT_EQ(0, vec.getY()); - auto rot = vec.rotated(unit::deg2rad(180)); + auto rot = rotate(vec, unit::deg2rad(180)); EXPECT_EQ(-1, rot.getX()); EXPECT_EQ(0, rot.getY()); @@ -469,6 +401,32 @@ TEST(Vector2, functions) res ); } + + { + const Vector2 vec; + + EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); + } + + { + const Vector2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); + } + + { + const Vector2 vec1{1.0f, 2.0f}; + const Vector2 vec2{5.0f, 4.0f}; + + EXPECT_FLOAT_EQ(20.0f, distanceSquared(vec1, vec2)); + } + + { + const Vector2 vec1{1.0f, 2.0f}; + const Vector2 vec2{5.0f, 4.0f}; + + EXPECT_FLOAT_EQ(4.4721360f, distance(vec1, vec2)); + } } /* ************************************************************************ */ diff --git a/unittests/math/Vector3_test.cpp b/unittests/math/Vector3_test.cpp index 9d9e088..ddb7eee 100644 --- a/unittests/math/Vector3_test.cpp +++ b/unittests/math/Vector3_test.cpp @@ -134,6 +134,55 @@ TEST(Vector3, ctorZero) /* ************************************************************************ */ +TEST(Vector3, ctorSingle) +{ + { + Vector3 vec{1}; + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(1, vec.getY()); + EXPECT_EQ(1, vec.getZ()); + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(1, vec[1]); + EXPECT_EQ(1, vec[2]); + } + + { + Vector3 vec{3}; + + EXPECT_EQ(3, vec.getX()); + EXPECT_EQ(3, vec.getY()); + EXPECT_EQ(3, vec.getZ()); + EXPECT_EQ(3, vec[0]); + EXPECT_EQ(3, vec[1]); + EXPECT_EQ(3, vec[2]); + } + + { + Vector3 vec{1.2f}; + + EXPECT_FLOAT_EQ(1.2f, vec.getX()); + EXPECT_FLOAT_EQ(1.2f, vec.getY()); + EXPECT_FLOAT_EQ(1.2f, vec.getZ()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(1.2f, vec[1]); + EXPECT_FLOAT_EQ(1.2f, vec[2]); + } + + { + Vector3 vec{1.2}; + + EXPECT_DOUBLE_EQ(1.2, vec.getX()); + EXPECT_DOUBLE_EQ(1.2, vec.getY()); + EXPECT_DOUBLE_EQ(1.2, vec.getZ()); + EXPECT_DOUBLE_EQ(1.2, vec[0]); + EXPECT_DOUBLE_EQ(1.2, vec[1]); + EXPECT_DOUBLE_EQ(1.2, vec[2]); + } +} + +/* ************************************************************************ */ + TEST(Vector3, ctorElements) { { @@ -988,36 +1037,6 @@ TEST(Vector3, operatorDiv) /* ************************************************************************ */ -TEST(Vector3, inRange) -{ - { - const Vector3 vecMin{-10.0f, -5.0f, -2.0f}; - const Vector3 vecMax{10.0f, 20.0f, 5.0f}; - - Vector3 vec1; - Vector3 vec2{-15.0f, 0.0f, 0.0f}; - Vector3 vec3{5.0f, 0.0f, 3.0f}; - - EXPECT_TRUE(vec1.inRange(vecMin, vecMax)); - EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); - EXPECT_TRUE(vec3.inRange(vecMin, vecMax)); - } - - { - const Vector3 vecMax{10.0f, 20.0f, 8.0f}; - - Vector3 vec1; - Vector3 vec2{-15.0f, 0.0f, 3.0f}; - Vector3 vec3{5.0f, 0.0f, 3.0f}; - - EXPECT_TRUE(vec1.inRange(vecMax)); - EXPECT_FALSE(vec2.inRange(vecMax)); - EXPECT_TRUE(vec3.inRange(vecMax)); - } -} - -/* ************************************************************************ */ - TEST(Vector3, memberFunctions) { { @@ -1043,57 +1062,6 @@ TEST(Vector3, memberFunctions) EXPECT_FLOAT_EQ(14, vec.getLengthSquared()); } - - { - const Vector3 vec; - - EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); - } - - { - const Vector3 vec{1.0f, 2.0f, 3.0f}; - - EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); - } - - { - const Vector3 vec1{1.0f, 2.0f, 3.0f}; - const Vector3 vec2{5.0f, 4.0f, 3.0f}; - - EXPECT_FLOAT_EQ(20.0f, vec1.distanceSquared(vec2)); - } - - { - const Vector3 vec1{1.0f, 2.0f, 3.0f}; - const Vector3 vec2{5.0f, 4.0f, 3.0f}; - - EXPECT_FLOAT_EQ(4.4721360f, vec1.distance(vec2)); - } - - { - const Vector3 vec{1.0f, 2.0f, 3.0f}; - - auto inv = vec.inversed(); - - EXPECT_FLOAT_EQ(1.0f, inv[0]); - EXPECT_FLOAT_EQ(0.5f, inv[1]); - EXPECT_FLOAT_EQ(1.0f / 3.0f, inv[2]); - } - - { - auto vec = Vector3::createSingle(1); - - EXPECT_FLOAT_EQ(1.0f, vec[0]); - EXPECT_FLOAT_EQ(1.0f, vec[1]); - EXPECT_FLOAT_EQ(1.0f, vec[2]); - } - - { - auto vec = Vector3::createSingle(375.1721f); - - EXPECT_FLOAT_EQ(375.1721f, vec[0]); - EXPECT_FLOAT_EQ(375.1721f, vec[1]); - } } /* ************************************************************************ */ @@ -1353,6 +1321,32 @@ TEST(Vector3, functions) res ); } + + { + const Vector3 vec; + + EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); + } + + { + const Vector3 vec{1.0f, 2.0f, 3.0f}; + + EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); + } + + { + const Vector3 vec1{1.0f, 2.0f, 3.0f}; + const Vector3 vec2{5.0f, 4.0f, 3.0f}; + + EXPECT_FLOAT_EQ(20.0f, distanceSquared(vec1, vec2)); + } + + { + const Vector3 vec1{1.0f, 2.0f, 3.0f}; + const Vector3 vec2{5.0f, 4.0f, 3.0f}; + + EXPECT_FLOAT_EQ(4.4721360f, distance(vec1, vec2)); + } } /* ************************************************************************ */ diff --git a/unittests/math/VectorBase_test.cpp b/unittests/math/VectorBase_test.cpp new file mode 100644 index 0000000..770d3bf --- /dev/null +++ b/unittests/math/VectorBase_test.cpp @@ -0,0 +1,431 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +// GTest +#include "gtest/gtest.h" + +// CeCe +#include "cece/math/VectorBase.hpp" + +/* ************************************************************************ */ + +using namespace cece; +using namespace cece::math; + +/* ************************************************************************ */ + +template +struct Vec2 : public VectorBase +{ + Vec2() : x{}, y{} {} + Vec2(T x, T y) : x{x}, y{y} {} + + T& operator[](int pos) { return (&x)[pos]; } + const T& operator[](int pos) const { return (&x)[pos]; } + + int getSize() const noexcept { return 2; } + T getX() const noexcept { return x; } + void setX(T x) { this->x = x; } + T getY() const noexcept { return y; } + void setY(T y) { this->y = y; } + + T x; + T y; +}; + +/* ************************************************************************ */ + +template +std::ostream& operator<<(std::ostream& os, const Vec2& vec) +{ + return os << "(x = " << vec.x << ", y = " << vec.y << ")"; +} + +/* ************************************************************************ */ + +TEST(VectorBase, operators) +{ + { + Vec2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + Vec2 vec2 = +vec1; + + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(2.0f, vec2[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + Vec2 vec2 = -vec1; + + EXPECT_FLOAT_EQ(-1.0f, vec2[0]); + EXPECT_FLOAT_EQ(-2.0f, vec2[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + Vec2 vec2{1.0f, 2.0f}; + vec1 += vec2; + + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + Vec2 vec2{1.0f, 2.0f}; + vec1 -= vec2; + + EXPECT_FLOAT_EQ(0.0f, vec1[0]); + EXPECT_FLOAT_EQ(0.0f, vec1[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + vec1 *= 2.0; + + EXPECT_FLOAT_EQ(2.0f, vec1[0]); + EXPECT_FLOAT_EQ(4.0f, vec1[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + Vec2 vec2{5.0f, 3.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + EXPECT_FLOAT_EQ(5.0f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + + vec1 *= vec2; + + EXPECT_FLOAT_EQ(1.0f * 5.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f * 3.0f, vec1[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + vec1 /= 2.0; + + EXPECT_FLOAT_EQ(0.5f, vec1[0]); + EXPECT_FLOAT_EQ(1.0f, vec1[1]); + } + + { + Vec2 vec1{1.0f, 2.0f}; + Vec2 vec2{2.0f, 6.0f}; + + EXPECT_FLOAT_EQ(1.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f, vec1[1]); + + EXPECT_FLOAT_EQ(2.0f, vec2[0]); + EXPECT_FLOAT_EQ(6.0f, vec2[1]); + + vec1 /= vec2; + + EXPECT_FLOAT_EQ(1.0f / 2.0f, vec1[0]); + EXPECT_FLOAT_EQ(2.0f / 6.0f, vec1[1]); + } +} + +/* ************************************************************************ */ + +TEST(VectorBase, memberFunctions) +{ + { + const Vec2 vec; + + EXPECT_FLOAT_EQ(0, vec.getLength()); + } + + { + const Vec2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(2.2360680f, vec.getLength()); + } + + { + const Vec2 vec; + + EXPECT_FLOAT_EQ(0, vec.getLengthSquared()); + } + + { + const Vec2 vec{1.0f, 2.0f}; + + EXPECT_FLOAT_EQ(5, vec.getLengthSquared()); + } +} + +/* ************************************************************************ */ + +TEST(VectorBase, mutators) +{ + { + Vec2 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + vec.setX(100); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + vec.setY(50); + + EXPECT_EQ(100, vec.getX()); + EXPECT_EQ(50, vec.getY()); + } + + { + Vec2 vec; + + EXPECT_EQ(0, vec.x); + EXPECT_EQ(0, vec.y); + + vec.x = 100; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(0, vec.y); + + vec.y = 50; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + } +} + +/* ************************************************************************ */ + +TEST(VectorBase, functions) +{ + { + Vec2 vec1(0.94333f, 0.73733f); + Vec2 vec2(0.16110f, 0.61872f); + + EXPECT_FLOAT_EQ(0.94333f, vec1.getX()); + EXPECT_FLOAT_EQ(0.73733f, vec1.getY()); + + EXPECT_FLOAT_EQ(0.16110f, vec2.getX()); + EXPECT_FLOAT_EQ(0.61872f, vec2.getY()); + + auto res = dot(vec1, vec2); + + EXPECT_FLOAT_EQ( + 0.94333f * 0.16110f + + 0.73733f * 0.61872f, + res + ); + } +} + +/* ************************************************************************ */ + +TEST(VectorBase, freeOperators) +{ + { + const Vec2 vec1(5.3f, 8.9f); + const Vec2 vec2(3.3f, 1.2f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + + const auto vec3 = vec1 + vec2; + const auto vec4 = vec2 + vec1; + + EXPECT_FLOAT_EQ(5.3f + 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f + 1.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.3f + 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f + 8.9f, vec4.getY()); + } + + { + const Vec2 vec1(5.3f, 8.9f); + const Vec2 vec2(3.3f, 1.2f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(3.3f, vec2.getX()); + EXPECT_FLOAT_EQ(1.2f, vec2.getY()); + + const auto vec3 = vec1 - vec2; + const auto vec4 = vec2 - vec1; + + EXPECT_FLOAT_EQ(5.3f - 3.3f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f - 1.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.3f - 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(1.2f - 8.9f, vec4.getY()); + } + + { + const Vec2 vec1(5.3f, 8.9f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + const auto vec3 = vec1 * 3.2f; + const auto vec4 = 3.2f * vec1; + + EXPECT_FLOAT_EQ(5.3f * 3.2f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f * 3.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.2f * 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.2f * 8.9f, vec4.getY()); + } + + { + const Vec2 vec1(5.3f, 8.9f); + const Vec2 vec2(1.8f, 3.5f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(1.8f, vec2.getX()); + EXPECT_FLOAT_EQ(3.5f, vec2.getY()); + + const auto vec3 = vec1 * vec2; + const auto vec4 = vec2 * vec1; + + EXPECT_FLOAT_EQ(5.3f * 1.8f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f * 3.5f, vec3.getY()); + + EXPECT_FLOAT_EQ(1.8f * 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.5f * 8.9f, vec4.getY()); + } + + { + const Vec2 vec1(5.3f, 8.9f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + const auto vec3 = vec1 / 3.2f; + const auto vec4 = 3.2f / vec1; + + EXPECT_FLOAT_EQ(5.3f / 3.2f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f / 3.2f, vec3.getY()); + + EXPECT_FLOAT_EQ(3.2f / 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.2f / 8.9f, vec4.getY()); + } + + { + const Vec2 vec1(5.3f, 8.9f); + const Vec2 vec2(1.8f, 3.5f); + + EXPECT_FLOAT_EQ(5.3f, vec1.getX()); + EXPECT_FLOAT_EQ(8.9f, vec1.getY()); + + EXPECT_FLOAT_EQ(1.8f, vec2.getX()); + EXPECT_FLOAT_EQ(3.5f, vec2.getY()); + + const auto vec3 = vec1 / vec2; + const auto vec4 = vec2 / vec1; + + EXPECT_FLOAT_EQ(5.3f / 1.8f, vec3.getX()); + EXPECT_FLOAT_EQ(8.9f / 3.5f, vec3.getY()); + + EXPECT_FLOAT_EQ(1.8f / 5.3f, vec4.getX()); + EXPECT_FLOAT_EQ(3.5f / 8.9f, vec4.getY()); + } + + { + const Vec2 vec1(5.3f, 8.9f); + const Vec2 vec2(5.3f, 8.9f); + const Vec2 vec3(1.3f, 8.9f); + const Vec2 vec4(5.3f, 0.9f); + const Vec2 vec5(1.3f, 0.9f); + + EXPECT_EQ(vec1, vec1); + EXPECT_EQ(vec1, vec2); + EXPECT_NE(vec1, vec3); + EXPECT_NE(vec1, vec4); + + EXPECT_EQ(vec2, vec1); + EXPECT_EQ(vec2, vec2); + EXPECT_NE(vec2, vec3); + EXPECT_NE(vec2, vec4); + + EXPECT_NE(vec3, vec1); + EXPECT_NE(vec3, vec2); + EXPECT_EQ(vec3, vec3); + EXPECT_NE(vec3, vec4); + + EXPECT_NE(vec4, vec1); + EXPECT_NE(vec4, vec2); + EXPECT_NE(vec4, vec3); + EXPECT_EQ(vec4, vec4); + + EXPECT_FALSE(vec1 < vec2); + + EXPECT_GE(vec1, vec1); + EXPECT_GE(vec1, vec2); + EXPECT_GE(vec1, vec3); + EXPECT_GE(vec1, vec4); + + EXPECT_GT(vec1, vec5); + + EXPECT_LE(vec1, vec1); + EXPECT_LE(vec1, vec2); + EXPECT_LE(vec3, vec1); + EXPECT_LE(vec4, vec1); + + EXPECT_LT(vec5, vec1); + } + +} + +/* ************************************************************************ */ diff --git a/unittests/math/Vector_test.cpp b/unittests/math/Vector_test.cpp index e4ce1f2..e65f32d 100644 --- a/unittests/math/Vector_test.cpp +++ b/unittests/math/Vector_test.cpp @@ -499,40 +499,6 @@ TEST(Vector, operators) /* ************************************************************************ */ -TEST(Vector, inRange) -{ - { - const BasicVector vecMin{-10.0f, -5.0f, 0.0f, 5.0f, 10.0f}; - const BasicVector vecMax{10.0f, 20.0f, 30.0f, 40.0f, 50.0f}; - - BasicVector vec1; - BasicVector vec2{-15.0f, 0.0f, 0.0f, 0.0f, 0.0f}; - BasicVector vec3{5.0f, 0.0f, 0.0f, 10.0f, 40.0f}; - BasicVector vec4{5.0f, 0.0f, 0.0f, 5.0f, 40.0f}; - - EXPECT_FALSE(vec1.inRange(vecMin, vecMax)); - EXPECT_FALSE(vec2.inRange(vecMin, vecMax)); - EXPECT_TRUE(vec3.inRange(vecMin, vecMax)); - EXPECT_TRUE(vec4.inRange(vecMin, vecMax)); - } - - { - const BasicVector vecMax{10.0f, 20.0f, 30.0f, 40.0f, 50.0f}; - - BasicVector vec1; - BasicVector vec2{-15.0f, 0.0f, 0.0f, 0.0f, 0.0f}; - BasicVector vec3{5.0f, 0.0f, -3.0f, 0.0f, 40.0f}; - BasicVector vec4{5.0f, 0.0f, 0.0f, 5.0f, 40.0f}; - - EXPECT_TRUE(vec1.inRange(vecMax)); - EXPECT_FALSE(vec2.inRange(vecMax)); - EXPECT_FALSE(vec3.inRange(vecMax)); - EXPECT_TRUE(vec4.inRange(vecMax)); - } -} - -/* ************************************************************************ */ - TEST(Vector, memberFunctions) { { @@ -562,88 +528,53 @@ TEST(Vector, memberFunctions) { const BasicVector vec; - EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + EXPECT_FLOAT_EQ(vec.getLengthSquared(), dot(vec, vec)); } { const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - EXPECT_FLOAT_EQ(vec.getLengthSquared(), vec.dot(vec)); + EXPECT_FLOAT_EQ(vec.getLengthSquared(), dot(vec, vec)); } { const BasicVector vec1; const BasicVector vec2; - EXPECT_FLOAT_EQ(0, vec1.dot(vec2)); + EXPECT_FLOAT_EQ(0, dot(vec1, vec2)); } { const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; - EXPECT_FLOAT_EQ(35, vec1.dot(vec2)); + EXPECT_FLOAT_EQ(35, dot(vec1, vec2)); } { const BasicVector vec; - EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); } { const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - EXPECT_FLOAT_EQ(0.0f, vec.distanceSquared(vec)); + EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); } { const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; - EXPECT_FLOAT_EQ(40.0f, vec1.distanceSquared(vec2)); + EXPECT_FLOAT_EQ(40.0f, distanceSquared(vec1, vec2)); } { const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; - EXPECT_FLOAT_EQ(6.3245554f, vec1.distance(vec2)); - } - - { - const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - - auto inv = vec.inversed(); - - EXPECT_EQ(5, inv.getSize()); - EXPECT_FLOAT_EQ(1.0f, inv[0]); - EXPECT_FLOAT_EQ(0.5f, inv[1]); - EXPECT_FLOAT_EQ(1.0f / 3.0f, inv[2]); - EXPECT_FLOAT_EQ(0.25f, inv[3]); - EXPECT_FLOAT_EQ(0.2f, inv[4]); - } - - { - auto vec = BasicVector::createSingle(1); - - EXPECT_EQ(5, vec.getSize()); - EXPECT_FLOAT_EQ(1.0f, vec[0]); - EXPECT_FLOAT_EQ(1.0f, vec[1]); - EXPECT_FLOAT_EQ(1.0f, vec[2]); - EXPECT_FLOAT_EQ(1.0f, vec[3]); - EXPECT_FLOAT_EQ(1.0f, vec[4]); - } - - { - auto vec = BasicVector::createSingle(375.1721f); - - EXPECT_EQ(5, vec.getSize()); - EXPECT_FLOAT_EQ(375.1721f, vec[0]); - EXPECT_FLOAT_EQ(375.1721f, vec[1]); - EXPECT_FLOAT_EQ(375.1721f, vec[2]); - EXPECT_FLOAT_EQ(375.1721f, vec[3]); - EXPECT_FLOAT_EQ(375.1721f, vec[4]); + EXPECT_FLOAT_EQ(6.3245554f, distance(vec1, vec2)); } } From 54760dfd3f7a1eea66ed65b5093aaf4f757ffc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Thu, 8 Jun 2017 16:50:24 +0200 Subject: [PATCH 08/11] Massive Vector refractoring. --- include/cece/math/Vector.hpp | 1606 +++++++++++++---- include/cece/math/Vector2.hpp | 485 ----- include/cece/math/Vector3.hpp | 537 ------ include/cece/math/VectorBase.hpp | 557 +++--- include/cece/math/VectorIo.hpp | 125 ++ include/cece/unit/VectorUnits.hpp | 11 +- src/math/CMakeLists.txt | 2 - src/math/Vector.cpp | 13 +- src/math/Vector3.cpp | 46 - src/simulation/DefaultSimulation.cpp | 1 + src/simulation/Object.cpp | 1 + src/simulation/Simulation.cpp | 1 + src/unit/VectorUnits.cpp | 11 +- unittests/math/CMakeLists.txt | 1 + unittests/math/Vector2_test.cpp | 45 +- unittests/math/Vector3_test.cpp | 2 +- unittests/math/VectorBase_test.cpp | 66 +- .../math/VectorIo_test.cpp | 108 +- 18 files changed, 1886 insertions(+), 1732 deletions(-) delete mode 100644 include/cece/math/Vector2.hpp delete mode 100644 include/cece/math/Vector3.hpp create mode 100644 include/cece/math/VectorIo.hpp delete mode 100644 src/math/Vector3.cpp rename src/math/Vector2.cpp => unittests/math/VectorIo_test.cpp (53%) diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index 8d1167d..c4dd936 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -37,13 +37,9 @@ #include "cece/Assert.hpp" #include "cece/StaticArray.hpp" #include "cece/math/Zero.hpp" -#include "cece/io/InStream.hpp" -#include "cece/io/OutStream.hpp" #include "cece/unit/math.hpp" #include "cece/unit/Units.hpp" #include "cece/math/VectorBase.hpp" -#include "cece/math/Vector2.hpp" -#include "cece/math/Vector3.hpp" /* ************************************************************************ */ @@ -58,8 +54,8 @@ namespace math { * @tparam T Element type. * @tparam N Number of elements. */ -template -class BasicVector : public VectorBase +template +class Vector : public VectorBase { static_assert(N > 0, "Cannot create empty vector"); @@ -68,7 +64,7 @@ class BasicVector : public VectorBase public: - /// BasicVector value type. + /// Vector value type. using ValueType = T; @@ -87,7 +83,7 @@ class BasicVector : public VectorBase /** * @brief Default constructor. */ - BasicVector() noexcept; + Vector() noexcept; /** @@ -95,7 +91,7 @@ class BasicVector : public VectorBase * * @param data The source data. */ - BasicVector(std::initializer_list data); + Vector(std::initializer_list data); /** @@ -103,7 +99,7 @@ class BasicVector : public VectorBase * * @param data The source data. */ - explicit BasicVector(T (&data)[N]); + explicit Vector(T (&data)[N]); /** @@ -111,7 +107,7 @@ class BasicVector : public VectorBase * * @param data The source data. */ - explicit BasicVector(const StaticArray& data); + explicit Vector(const StaticArray& data); /** @@ -119,7 +115,7 @@ class BasicVector : public VectorBase * * @param[in] zero The zero value. */ - BasicVector(Zero_t zero); + Vector(Zero_t zero); /** @@ -127,7 +123,7 @@ class BasicVector : public VectorBase * * @param[in] src The source vector. */ - BasicVector(const BasicVector& src); + Vector(const Vector& src); /** @@ -135,7 +131,7 @@ class BasicVector : public VectorBase * * @param[in] src The source vector. */ - BasicVector(BasicVector&& src); + Vector(Vector&& src); /** @@ -146,7 +142,7 @@ class BasicVector : public VectorBase * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - explicit BasicVector(const BasicVector& src); + explicit Vector(const Vector& src); // Public Operators @@ -160,7 +156,7 @@ class BasicVector : public VectorBase * * @return *this. */ - BasicVector& operator=(Zero_t zero); + Vector& operator=(Zero_t zero); /** @@ -170,7 +166,7 @@ class BasicVector : public VectorBase * * @return *this. */ - BasicVector& operator=(std::initializer_list data); + Vector& operator=(std::initializer_list data); /** @@ -180,7 +176,7 @@ class BasicVector : public VectorBase * * @return *this. */ - BasicVector& operator=(T (&data)[N]); + Vector& operator=(T (&data)[N]); /** @@ -190,7 +186,7 @@ class BasicVector : public VectorBase * * @return *this. */ - BasicVector& operator=(const StaticArray& data); + Vector& operator=(const StaticArray& data); /** @@ -200,7 +196,7 @@ class BasicVector : public VectorBase * * @return *this. */ - BasicVector& operator=(const BasicVector& src); + Vector& operator=(const Vector& src); /** @@ -210,7 +206,7 @@ class BasicVector : public VectorBase * * @return *this. */ - BasicVector& operator=(BasicVector&& src); + Vector& operator=(Vector&& src); /** @@ -223,7 +219,7 @@ class BasicVector : public VectorBase * @return *this. */ template::value>::type* = nullptr> - BasicVector& operator=(const BasicVector& src); + Vector& operator=(const Vector& src); /** @@ -245,444 +241,1446 @@ class BasicVector : public VectorBase */ const T& operator[](int pos) const noexcept; - -// Public Accessors -public: - - - /** - * @brief Returns vector size. - * - * @return The size. - */ - int getSize() const noexcept; - }; /* ************************************************************************ */ -// TODO: rework +/** + * @brief 2D vector specialization. + * + * @tparam T Element type. + */ template -struct BasicVector : public Vector2 +struct Vector : public VectorBase { - using Vector2::Vector2; - - BasicVector() {}; - BasicVector(const Vector2& src) - : Vector2(src) - { - // - } - const T& getWidth() const noexcept { return Vector2::getX(); } +// Public Types +public: - const T& getHeight() const noexcept { return Vector2::getY(); } - static bool inRange(T value, T low, T high) noexcept { return value >= low && value < high; } + /// Element type. + using ValueType = T; - bool inRange(const BasicVector& low, const BasicVector& high) const noexcept - { - bool res = true; - res = res && inRange(Vector2::getX(), low.getX(), high.getX()); - res = res && inRange(Vector2::getY(), low.getY(), high.getY()); +// Public Data Members +public: - return res; - } - bool inRange(const BasicVector& high) const noexcept + union { - return inRange(Zero, high); - } + struct + { + /// X coordinate. + T x; - static BasicVector createSingle(T val) noexcept { return BasicVector(val, val); } + /// Y coordinate. + T y; + }; - template - BasicVector inversed() const noexcept - { - return BasicVector( - T2(1) / Vector2::getX(), - T2(1) / Vector2::getY() - ); - } + struct + { + /// Width + T width; - BasicVector rotated(unit::Angle angle) const noexcept - { - return rotate(*this, angle); - } -}; + /// Height. + T height; + }; -/* ************************************************************************ */ + T m[2]; + }; -// TODO: rework -template -struct BasicVector : public Vector3 -{ - using Vector3::Vector3; - BasicVector() {}; - BasicVector(const Vector3& src) - : Vector3(src) - { - // - } +// Public Ctors +public: - const T& getWidth() const noexcept { return Vector3::getX(); } - const T& getHeight() const noexcept { return Vector3::getY(); } - const T& getDepth() const noexcept { return Vector3::getZ(); } - static bool inRange(T value, T low, T high) noexcept { return value >= low && value < high; } + /** + * @brief Default constructor. + */ + Vector(); - bool inRange(const BasicVector& low, const BasicVector& high) const noexcept - { - bool res = true; - res = res && inRange(Vector3::getX(), low.getX(), high.getX()); - res = res && inRange(Vector3::getY(), low.getY(), high.getY()); - res = res && inRange(Vector3::getZ(), low.getZ(), high.getZ()); + /** + * @brief Constructor. + * + * @param x The X and Y coordinate. + */ + explicit Vector(T value); - return res; - } - bool inRange(const BasicVector& high) const noexcept - { - return inRange(Zero, high); - } + /** + * @brief Constructor. + * + * @param x The X coordinate. + * @param y The Y coordinate. + */ + Vector(T x, T y); - static BasicVector createSingle(T val) noexcept { return BasicVector(val, val, val); } - template - BasicVector inversed() const noexcept - { - return BasicVector( - T2(1) / Vector3::getX(), - T2(1) / Vector3::getY(), - T2(1) / Vector3::getZ() - ); - } -}; + /** + * @brief Zero value constructor. + * + * @param[in] zero The zero value. + */ + Vector(Zero_t zero); -/* ************************************************************************ */ -/** - * @brief Basic vector. - */ -template -using Vector = BasicVector; + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + */ + Vector(const Vector& src); -/* ************************************************************************ */ -/** - * @brief Vector for integer size. - */ -using Size = Vector; + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + */ + Vector(Vector&& src); -/* ************************************************************************ */ -/** - * @brief Vector for coordinates. - */ -using Coordinate = Vector; + /** + * @brief Copy constructor. + * + * @param rhs Source vector. + * + * @tparam T2 The source vector element type. + */ + template::value>::type* = nullptr> + Vector(const Vector& rhs); -/* ************************************************************************ */ -/** - * @brief Vector of int. - */ -using VectorInt = Vector; +// Public Operators +public: -/* ************************************************************************ */ -/** - * @brief Vector of float. - */ -using VectorFloat = Vector; + /** + * @brief Copy constructor. + * + * @param[in] zero The zero value. + * + * @return *this. + */ + Vector& operator=(Zero_t zero); -/* ************************************************************************ */ -/** - * @brief Vector of float. - */ -using VectorDouble = Vector; + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + Vector& operator=(const Vector& src); -/* ************************************************************************ */ -/** - * @brief Vector of float. - */ -using VectorLongDouble = Vector; + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + Vector& operator=(Vector&& src); -/* ************************************************************************ */ -/** - * @brief Vector of float. - */ -using VectorReal = Vector; + /** + * @brief Copy constructor. + * + * @param v The source vector. + * + * @tparam T2 The source vector element type. + * + * @return *this. + */ + template::value>::type* = nullptr> + Vector& operator=(const Vector& src); -/* ************************************************************************ */ -/** - * @brief Input stream operator. - * - * @param is Input stream. - * @param vector Result value. - * - * @return is. - */ -template -io::InStream& operator>>(io::InStream& is, BasicVector& vector) -{ - int i = 0; + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + T& operator[](int pos) noexcept; - for (; i < N; ++i) - { - if (!(is >> std::skipws >> vector[i])) - break; - } - if (i == 0) - return is; + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + const T& operator[](int pos) const noexcept; - // Copy missing values - // TODO: have this feature? - for (int j = i; j < N; ++j) - vector[j] = vector[i - 1]; - return is; -} +// Public Accessors +public: -/* ************************************************************************ */ -/** - * @brief Output stream operator. - * - * @param os Output stream. - * @param vector Input value. - * - * @return os. - */ -template -io::OutStream& operator<<(io::OutStream& os, const BasicVector& vector) noexcept -{ - for (int i = 0; i < N; ++i) - { - if (i != 0) - os << " "; + /** + * @brief Returns X coordinate. + * + * @return The X coordinate. + */ + const T& getX() const noexcept; - os << vector[i]; - } - return os; -} + /** + * @brief Set X coordinate. + * + * @param[in] x The X coordinate. + */ + void setX(T x); -/* ************************************************************************ */ -extern template class BasicVector; + /** + * @brief Returns Y coordinate. + * + * @return The Y coordinate. + */ + const T& getY() const noexcept; -/* ************************************************************************ */ -} -} + /** + * @brief Set Y coordinate. + * + * @param[in] y The Y coordinate. + */ + void setY(T y); -/* ************************************************************************ */ -/* ************************************************************************ */ -/* ************************************************************************ */ -namespace cece { -namespace math { + /** + * @brief Gets the width. + * + * @return The width. + */ + const T& getWidth() const noexcept; -/* ************************************************************************ */ -template -inline BasicVector::BasicVector() noexcept - : m{} -{ - // Nothing to do -} + /** + * @brief Set the width. + * + * @param[in] width The width. + */ + void setWidth(T width); -/* ************************************************************************ */ -template -inline BasicVector::BasicVector(std::initializer_list data) -{ - CECE_ASSERT(data.size() == getSize()); + /** + * @brief Gets the height. + * + * @return The height. + */ + const T& getHeight() const noexcept; - using std::begin; - auto it = begin(data); - for (int i = 0; i < getSize(); ++i, ++it) - m[i] = *it; -} + /** + * @brief Sets the height. + * + * @param[in] height The height + */ + void setHeight(T height); -/* ************************************************************************ */ -template -inline BasicVector::BasicVector(T (&data)[N]) -{ - using std::begin; - auto it = begin(data); +// Public Deprecated +public: - for (int i = 0; i < getSize(); ++i, ++it) - m[i] = *it; -} -/* ************************************************************************ */ + // @deprecated + bool inRange(const Vector& low, const Vector& high) const noexcept + { + return math::inRange(*this, low, high); + } -template -inline BasicVector::BasicVector(const StaticArray& data) - : m(data) -{ - // Nothing to do -} -/* ************************************************************************ */ + // @deprecated + bool inRange(const Vector& high) const noexcept + { + return math::inRange(*this, high); + } -template -inline BasicVector::BasicVector(Zero_t zero) -{ - for (int i = 0; i < getSize(); ++i) - m[i] = T{}; -} -/* ************************************************************************ */ + // @deprecated + static Vector createSingle(T val) noexcept + { + return Vector(val, val); + } -template -inline BasicVector::BasicVector(const BasicVector& src) -{ - for (int i = 0; i < getSize(); ++i) + + // @deprecated + template + Vector inversed() const noexcept + { + return T2(1) / *this; + } + + + // @deprecated + Vector rotated(unit::Angle angle) const noexcept + { + return rotate(*this, angle); + } +}; + +/* ************************************************************************ */ + +/** + * @brief 3D vector specialization. + * + * @tparam T Element type. + */ +template +struct Vector : public VectorBase +{ + + +// Public Types +public: + + + /// Vector element type. + using ValueType = T; + + +// Public Data Members +public: + + + union + { + struct + { + /// X coordinate. + T x; + + /// Y coordinate. + T y; + + /// Z coordinate. + T z; + }; + + struct + { + /// Width. + T width; + + /// Height. + T height; + + /// Depth. + T depth; + }; + + T m[3]; + }; + + +// Public Ctors +public: + + + /** + * @brief Default constructor. + */ + Vector() noexcept; + + + /** + * @brief Constructor. + * + * @param val The X, Y and Z coordinate. + */ + explicit Vector(T val); + + + /** + * @brief Constructor. + * + * @param x The X coordinate. + * @param y The Y coordinate. + * @param y The Z coordinate. + */ + Vector(T x, T y, T z); + + + /** + * @brief Zero value constructor. + * + * @param[in] zero The zero value. + */ + Vector(Zero_t zero); + + + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + */ + Vector(const Vector& src); + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + */ + Vector(Vector&& src); + + + /** + * @brief Copy constructor. + * + * @param rhs Source vector. + * + * @tparam T2 The source vector element type. + */ + template::value>::type* = nullptr> + Vector(const Vector& rhs); + + +// Public Operators +public: + + + /** + * @brief Copy constructor. + * + * @param[in] zero The zero value. + * + * @return *this. + */ + Vector& operator=(Zero_t zero); + + + /** + * @brief Copy constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + Vector& operator=(const Vector& src); + + + /** + * @brief Move constructor. + * + * @param[in] src The source vector. + * + * @return *this. + */ + Vector& operator=(Vector&& src); + + + /** + * @brief Copy constructor. + * + * @param v The source vector. + * + * @tparam T2 The source vector element type. + * + * @return *this. + */ + template::value>::type* = nullptr> + Vector& operator=(const Vector& src); + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + T& operator[](int pos) noexcept; + + + /** + * @brief Access operator. + * + * @param pos The position. + * + * @return Reference to the element. + */ + const T& operator[](int pos) const noexcept; + + +// Public Accessors +public: + + + /** + * @brief Returns X coordinate. + * + * @return The X coordinate. + */ + const T& getX() const noexcept; + + + /** + * @brief Set X coordinate. + * + * @param x The X coordinate. + */ + void setX(T x); + + + /** + * @brief Returns Y coordinate. + * + * @return The Y coordinate. + */ + const T& getY() const noexcept; + + + /** + * @brief Set Y coordinate. + * + * @param y The Y coordinate. + */ + void setY(T y); + + + /** + * @brief Returns Z coordinate. + * + * @return The Z coordinate. + */ + const T& getZ() const noexcept; + + + /** + * @brief Set Z coordinate. + * + * @param z The Z coordinate. + */ + void setZ(T z); + + + /** + * @brief Gets the width. + * + * @return The width. + */ + const T& getWidth() const noexcept; + + + /** + * @brief Set the width. + * + * @param[in] width The width. + */ + void setWidth(T width); + + + /** + * @brief Gets the height. + * + * @return The height. + */ + const T& getHeight() const noexcept; + + + /** + * @brief Sets the height. + * + * @param[in] height The height + */ + void setHeight(T height); + + + /** + * @brief Gets the depth. + * + * @return The depth. + */ + const T& getDepth() const noexcept; + + + /** + * @brief Sets the depth. + * + * @param[in] depth The depth + */ + void setDepth(T depth); + + +// Public Deprecated +public: + + + // @deprecated + bool inRange(const Vector& low, const Vector& high) const noexcept + { + return math::inRange(*this, low, high); + } + + + // @deprecated + bool inRange(const Vector& high) const noexcept + { + return math::inRange(*this, high); + } + + + // @deprecated + static Vector createSingle(T val) noexcept + { + return Vector(val, val, val); + } + + + // @deprecated + template + Vector inversed() const noexcept + { + return T2(1) / *this; + } +}; + +/* ************************************************************************ */ + +/** + * @brief 2D vector alias. + */ +template +using Vector2 = Vector; + +/* ************************************************************************ */ + +/** + * @brief 3D vector alias. + */ +template +using Vector3 = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector for integer size. + * @deprecated + */ +using Size = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector for coordinates. + * @deprecated + */ +using Coordinate = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of int. + * @deprecated + */ +using VectorInt = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of float. + * @deprecated + */ +using VectorFloat = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of double. + * @deprecated + */ +using VectorDouble = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of long double. + * @deprecated + */ +using VectorLongDouble = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of float. + * @deprecated + */ +using VectorReal = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of integers. + */ +using IntVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of float. + */ +using FloatVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of double. + */ +using DoubleVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of long double. + */ +using LongDoubleVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector of float. + */ +using RealVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector for indices. + */ +using IndexVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Vector for sizes. + */ +using SizeVector = Vector; + +/* ************************************************************************ */ + +/** + * @brief Rotate the vector counter-clockwise and return rotated version. + * + * @param[in] vec The vector. + * @param[in] angle Rotation angle. + * + * @tparam T The vector element type. + * + * @return Rotated vector. + */ +template +Vector rotate(const Vector& vec, unit::Angle angle) noexcept; + +/* ************************************************************************ */ + +/** + * @brief Calculate cross product of two vectors. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 The first type. + * @tparam T2 The second type. + * + * @return Cross product. + */ +template +Vector() * std::declval()), 3> +cross(const Vector& lhs, const Vector& rhs); + +/* ************************************************************************ */ + +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; + +/* ************************************************************************ */ + +/// @deprecated +template +using BasicVector = Vector; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template +inline Vector::Vector() noexcept + : m{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(std::initializer_list data) +{ + CECE_ASSERT(data.size() == N); + + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m[i] = *it; +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(T (&data)[N]) +{ + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m[i] = *it; +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(const StaticArray& data) + : m(data) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(Zero_t zero) +{ + for (int i = 0; i < N; ++i) + m[i] = T{}; +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(const Vector& src) +{ + for (int i = 0; i < N; ++i) + m[i] = src.m[i]; +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(Vector&& src) +{ + for (int i = 0; i < N; ++i) + m[i] = std::move(src.m[i]); +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline Vector::Vector(const Vector& src) +{ + for (int i = 0; i < N; ++i) + m[i] = T(src[i]); +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(Zero_t zero) +{ + for (int i = 0; i < N; ++i) + m[i] = T{}; + + return *this; +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(std::initializer_list data) +{ + CECE_ASSERT(data.size() == N); + + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m[i] = *it; + + return *this; +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(T (&data)[N]) +{ + using std::begin; + auto it = begin(data); + + for (int i = 0; i < N; ++i, ++it) + m[i] = *it; + + return *this; +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(const StaticArray& data) +{ + m = data; + + return *this; +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(const Vector& src) +{ + for (int i = 0; i < N; ++i) m[i] = src.m[i]; + + return *this; +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(Vector&& src) +{ + for (int i = 0; i < N; ++i) + m[i] = std::move(src.m[i]); + + return *this; +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline Vector& Vector::operator=(const Vector& src) +{ + for (int i = 0; i < N; ++i) + m[i] = T(src[i]); + + return *this; +} + +/* ************************************************************************ */ + +template +inline T& Vector::operator[](int pos) noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < N); + return m[pos]; +} + +/* ************************************************************************ */ + +template +inline const T& Vector::operator[](int pos) const noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < N); + return m[pos]; +} + +/* ************************************************************************ */ + +template +inline Vector::Vector() + : x{} + , y{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(T val) + : x{val} + , y{val} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(T x, T y) + : x{std::move(x)} + , y{std::move(y)} +{ + // Nothing to do } /* ************************************************************************ */ -template -inline BasicVector::BasicVector(BasicVector&& src) +template +inline Vector::Vector(Zero_t zero) + : x{} + , y{} { - for (int i = 0; i < getSize(); ++i) - m[i] = std::move(src.m[i]); + // Nothing to do } /* ************************************************************************ */ -template +template +inline Vector::Vector(const Vector& src) + : x{src.getX()} + , y{src.getY()} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(Vector&& src) + : x{std::move(src.x)} + , y{std::move(src.y)} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template template::value>::type*> -inline BasicVector::BasicVector(const BasicVector& src) +inline Vector::Vector(const Vector& rhs) + : x(rhs.getX()) + , y(rhs.getY()) { - for (int i = 0; i < getSize(); ++i) - m[i] = T(src[i]); + // Nothing to do } /* ************************************************************************ */ -template -inline BasicVector& BasicVector::operator=(Zero_t zero) +template +inline Vector& Vector::operator=(Zero_t zero) { - for (int i = 0; i < getSize(); ++i) - m[i] = T{}; + x = T{}; + y = T{}; return *this; } /* ************************************************************************ */ -template -inline BasicVector& BasicVector::operator=(std::initializer_list data) +template +inline Vector& Vector::operator=(const Vector& src) { - CECE_ASSERT(data.size() == getSize()); + x = src.x; + y = src.y; - using std::begin; - auto it = begin(data); + return *this; +} - for (int i = 0; i < getSize(); ++i, ++it) - m[i] = *it; +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(Vector&& src) +{ + x = std::move(src.x); + y = std::move(src.y); return *this; } /* ************************************************************************ */ -template -inline BasicVector& BasicVector::operator=(T (&data)[N]) +template +template::value>::type*> +inline Vector& Vector::operator=(const Vector& src) { - using std::begin; - auto it = begin(data); - - for (int i = 0; i < getSize(); ++i, ++it) - m[i] = *it; + x = T(src.getX()); + y = T(src.getY()); return *this; } /* ************************************************************************ */ -template -inline BasicVector& BasicVector::operator=(const StaticArray& data) +template +inline T& Vector::operator[](int pos) noexcept { - m = data; + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < 2); + return (&x)[pos]; +} + +/* ************************************************************************ */ + +template +inline const T& Vector::operator[](int pos) const noexcept +{ + CECE_ASSERT(pos >= 0); + CECE_ASSERT(pos < 2); + return (&x)[pos]; +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getX() const noexcept +{ + return x; +} + +/* ************************************************************************ */ + +template +inline void Vector::setX(T x) +{ + this->x = std::move(x); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getY() const noexcept +{ + return y; +} + +/* ************************************************************************ */ + +template +inline void Vector::setY(T y) +{ + this->y = std::move(y); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getWidth() const noexcept +{ + return width; +} + +/* ************************************************************************ */ + +template +inline void Vector::setWidth(T width) +{ + this->width = std::move(width); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getHeight() const noexcept +{ + return height; +} + +/* ************************************************************************ */ + +template +inline void Vector::setHeight(T height) +{ + this->height = std::move(height); +} + +/* ************************************************************************ */ + +template +inline Vector::Vector() noexcept + : x{} + , y{} + , z{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(T val) + : x{val} + , y{val} + , z{val} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(T x, T y, T z) + : x{std::move(x)} + , y{std::move(y)} + , z{std::move(z)} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(Zero_t zero) + : x{} + , y{} + , z{} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(const Vector& src) + : x{src.getX()} + , y{src.getY()} + , z{src.getZ()} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector::Vector(Vector&& src) + : x{std::move(src.x)} + , y{std::move(src.y)} + , z{std::move(src.z)} +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +template::value>::type*> +inline Vector::Vector(const Vector& rhs) + : x(rhs.getX()) + , y(rhs.getY()) + , z(rhs.getZ()) +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Vector& Vector::operator=(Zero_t zero) +{ + x = T{}; + y = T{}; + z = T{}; return *this; } /* ************************************************************************ */ -template -inline BasicVector& BasicVector::operator=(const BasicVector& src) +template +inline Vector& Vector::operator=(const Vector& src) { - for (int i = 0; i < getSize(); ++i) - m[i] = src.m[i]; + x = src.x; + y = src.y; + z = src.z; return *this; } /* ************************************************************************ */ -template -inline BasicVector& BasicVector::operator=(BasicVector&& src) +template +inline Vector& Vector::operator=(Vector&& src) { - for (int i = 0; i < getSize(); ++i) - m[i] = std::move(src.m[i]); + x = std::move(src.x); + y = std::move(src.y); + z = std::move(src.z); return *this; } /* ************************************************************************ */ -template +template template::value>::type*> -inline BasicVector& BasicVector::operator=(const BasicVector& src) +inline Vector& Vector::operator=(const Vector& src) { - for (int i = 0; i < getSize(); ++i) - m[i] = T(src[i]); + x = T(src.getX()); + y = T(src.getY()); + z = T(src.getZ()); return *this; } /* ************************************************************************ */ -template -inline T& BasicVector::operator[](int pos) noexcept +template +inline T& Vector::operator[](int pos) noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < getSize()); - return m[pos]; + CECE_ASSERT(pos < 3); + return (&x)[pos]; } /* ************************************************************************ */ -template -inline const T& BasicVector::operator[](int pos) const noexcept +template +inline const T& Vector::operator[](int pos) const noexcept { CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < getSize()); - return m[pos]; + CECE_ASSERT(pos < 3); + return (&x)[pos]; } /* ************************************************************************ */ -template -int BasicVector::getSize() const noexcept +template +inline const T& Vector::getX() const noexcept +{ + return x; +} + +/* ************************************************************************ */ + +template +inline void Vector::setX(T x) +{ + this->x = std::move(x); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getY() const noexcept +{ + return y; +} + +/* ************************************************************************ */ + +template +inline void Vector::setY(T y) +{ + this->y = std::move(y); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getZ() const noexcept +{ + return z; +} + +/* ************************************************************************ */ + +template +inline void Vector::setZ(T z) +{ + this->z = std::move(z); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getWidth() const noexcept +{ + return width; +} + +/* ************************************************************************ */ + +template +inline void Vector::setWidth(T width) +{ + this->width = std::move(width); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getHeight() const noexcept +{ + return height; +} + +/* ************************************************************************ */ + +template +inline void Vector::setHeight(T height) +{ + this->height = std::move(height); +} + +/* ************************************************************************ */ + +template +inline const T& Vector::getDepth() const noexcept +{ + return depth; +} + +/* ************************************************************************ */ + +template +inline void Vector::setDepth(T depth) +{ + this->depth = std::move(depth); +} + +/* ************************************************************************ */ + +template +inline Vector rotate(const Vector& vec, unit::Angle angle) noexcept +{ + return { + static_cast(vec.getX() * cos(static_cast(angle)) - vec.getY() * sin(static_cast(angle))), + static_cast(vec.getX() * sin(static_cast(angle)) + vec.getY() * cos(static_cast(angle))) + }; +} + +/* ************************************************************************ */ + +template +inline Vector() * std::declval()), 3> cross( + const Vector& lhs, + const Vector& rhs +) { - return N; + return { + lhs.getY() * rhs.getZ() - lhs.getZ() * rhs.getY(), + lhs.getZ() * rhs.getX() - lhs.getX() * rhs.getZ(), + lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX() + }; } /* ************************************************************************ */ diff --git a/include/cece/math/Vector2.hpp b/include/cece/math/Vector2.hpp deleted file mode 100644 index 4661074..0000000 --- a/include/cece/math/Vector2.hpp +++ /dev/null @@ -1,485 +0,0 @@ -/* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2017 */ -/* ************************************************************************ */ -/* Department of Cybernetics */ -/* Faculty of Applied Sciences */ -/* University of West Bohemia in Pilsen */ -/* ************************************************************************ */ -/* */ -/* This file is part of CeCe. */ -/* */ -/* CeCe is free software: you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation, either version 3 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* CeCe is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with CeCe. If not, see . */ -/* */ -/* ************************************************************************ */ - -#pragma once - -/* ************************************************************************ */ - -// C++ -#include -#include - -// CeCe -#include "cece/common.hpp" -#include "cece/Assert.hpp" -#include "cece/math/Zero.hpp" -#include "cece/math/VectorBase.hpp" -#include "cece/unit/Units.hpp" - -/* ************************************************************************ */ - -namespace cece { -namespace math { - -/* ************************************************************************ */ - -/** - * @brief Two dimensional vector. - * - * @tparam T Element type. - */ -template -class Vector2 : public VectorBase -{ - - -// Public Types -public: - - - /// Vector2 value type. - using ValueType = T; - - -// Public Data Members -public: - - - union - { - struct - { - /// X coordinate. - T x; - - /// Y coordinate. - T y; - }; - - T m[2]; - }; - - -// Public Ctors -public: - - - /** - * @brief Default constructor. - */ - Vector2(); - - - /** - * @brief Constructor. - * - * @param x The X and Y coordinate. - */ - explicit Vector2(T value); - - - /** - * @brief Constructor. - * - * @param x The X coordinate. - * @param y The Y coordinate. - */ - Vector2(T x, T y); - - - /** - * @brief Zero value constructor. - * - * @param[in] zero The zero value. - */ - Vector2(Zero_t zero); - - - /** - * @brief Copy constructor. - * - * @param[in] src The source vector. - */ - Vector2(const Vector2& src); - - - /** - * @brief Move constructor. - * - * @param[in] src The source vector. - */ - Vector2(Vector2&& src); - - - /** - * @brief Copy constructor. - * - * @param rhs Source vector. - * - * @tparam T2 The source vector element type. - */ - template::value>::type* = nullptr> - Vector2(const Vector2& rhs); - - -// Public Operators -public: - - - /** - * @brief Copy constructor. - * - * @param[in] zero The zero value. - * - * @return *this. - */ - Vector2& operator=(Zero_t zero); - - - /** - * @brief Copy constructor. - * - * @param[in] src The source vector. - * - * @return *this. - */ - Vector2& operator=(const Vector2& src); - - - /** - * @brief Move constructor. - * - * @param[in] src The source vector. - * - * @return *this. - */ - Vector2& operator=(Vector2&& src); - - - /** - * @brief Copy constructor. - * - * @param v The source vector. - * - * @tparam T2 The source vector element type. - * - * @return *this. - */ - template::value>::type* = nullptr> - Vector2& operator=(const Vector2& src); - - - /** - * @brief Access operator. - * - * @param pos The position. - * - * @return Reference to the element. - */ - T& operator[](int pos) noexcept; - - - /** - * @brief Access operator. - * - * @param pos The position. - * - * @return Reference to the element. - */ - const T& operator[](int pos) const noexcept; - - -// Public Accessors -public: - - - /** - * @brief Returns vector size. - * - * @return The size. - */ - int getSize() const noexcept; - - - /** - * @brief Returns X coordinate. - * - * @return The X coordinate. - */ - const T& getX() const noexcept; - - - /** - * @brief Set X coordinate. - * - * @param x The X coordinate. - */ - void setX(T x); - - - /** - * @brief Returns Y coordinate. - * - * @return The Y coordinate. - */ - const T& getY() const noexcept; - - - /** - * @brief Set Y coordinate. - * - * @param y The Y coordinate. - */ - void setY(T y); - -}; - -/* ************************************************************************ */ - -/** - * @brief Rotate the vector counter-clockwise and return rotated version. - * - * @param[in] vec The vector. - * @param[in] angle Rotation angle. - * - * @tparam T The vector element type. - * - * @return Rotated vector. - */ -template -Vector2 rotate(const Vector2& vec, unit::Angle angle) noexcept; - -/* ************************************************************************ */ - -extern template class Vector2; -extern template class Vector2; -extern template class Vector2; -extern template class Vector2; - -/* ************************************************************************ */ - -} -} - -/* ************************************************************************ */ -/* ************************************************************************ */ -/* ************************************************************************ */ - -namespace cece { -namespace math { - -/* ************************************************************************ */ - -template -inline Vector2::Vector2() - : x{} - , y{} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector2::Vector2(T val) - : x{val} - , y{val} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector2::Vector2(T x, T y) - : x{std::move(x)} - , y{std::move(y)} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector2::Vector2(Zero_t zero) - : x{} - , y{} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector2::Vector2(const Vector2& src) - : x{src.getX()} - , y{src.getY()} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector2::Vector2(Vector2&& src) - : x{std::move(src.x)} - , y{std::move(src.y)} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -template::value>::type*> -inline Vector2::Vector2(const Vector2& rhs) - : x(rhs.getX()) - , y(rhs.getY()) -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector2& Vector2::operator=(Zero_t zero) -{ - x = T{}; - y = T{}; - - return *this; -} - -/* ************************************************************************ */ - -template -inline Vector2& Vector2::operator=(const Vector2& src) -{ - x = src.x; - y = src.y; - - return *this; -} - -/* ************************************************************************ */ - -template -inline Vector2& Vector2::operator=(Vector2&& src) -{ - x = std::move(src.x); - y = std::move(src.y); - - return *this; -} - -/* ************************************************************************ */ - -template -template::value>::type*> -inline Vector2& Vector2::operator=(const Vector2& src) -{ - x = T(src.getX()); - y = T(src.getY()); - - return *this; -} - -/* ************************************************************************ */ - -template -inline T& Vector2::operator[](int pos) noexcept -{ - CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < getSize()); - return (&x)[pos]; -} - -/* ************************************************************************ */ - -template -inline const T& Vector2::operator[](int pos) const noexcept -{ - CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < getSize()); - return (&x)[pos]; -} - -/* ************************************************************************ */ - -template -inline int Vector2::getSize() const noexcept -{ - return 2; -} - -/* ************************************************************************ */ - -template -inline const T& Vector2::getX() const noexcept -{ - return x; -} - -/* ************************************************************************ */ - -template -inline void Vector2::setX(T x) -{ - this->x = std::move(x); -} - -/* ************************************************************************ */ - -template -inline const T& Vector2::getY() const noexcept -{ - return y; -} - -/* ************************************************************************ */ - -template -inline void Vector2::setY(T y) -{ - this->y = std::move(y); -} - -/* ************************************************************************ */ - -template -inline Vector2 rotate(const Vector2& vec, unit::Angle angle) noexcept -{ - return { - static_cast(vec.getX() * cos(static_cast(angle)) - vec.getY() * sin(static_cast(angle))), - static_cast(vec.getX() * sin(static_cast(angle)) + vec.getY() * cos(static_cast(angle))) - }; -} - -/* ************************************************************************ */ - -} -} - -/* ************************************************************************ */ diff --git a/include/cece/math/Vector3.hpp b/include/cece/math/Vector3.hpp deleted file mode 100644 index bfaeeca..0000000 --- a/include/cece/math/Vector3.hpp +++ /dev/null @@ -1,537 +0,0 @@ -/* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2017 */ -/* ************************************************************************ */ -/* Department of Cybernetics */ -/* Faculty of Applied Sciences */ -/* University of West Bohemia in Pilsen */ -/* ************************************************************************ */ -/* */ -/* This file is part of CeCe. */ -/* */ -/* CeCe is free software: you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation, either version 3 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* CeCe is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with CeCe. If not, see . */ -/* */ -/* ************************************************************************ */ - -#pragma once - -/* ************************************************************************ */ - -// C++ -#include -#include - -// CeCe -#include "cece/common.hpp" -#include "cece/Assert.hpp" -#include "cece/math/Zero.hpp" -#include "cece/math/VectorBase.hpp" - -/* ************************************************************************ */ - -namespace cece { -namespace math { - -/* ************************************************************************ */ - -/** - * @brief Three dimensional vector. - * - * @tparam T Element type. - */ -template -class Vector3 : public VectorBase -{ - - -// Public Types -public: - - - /// Vector3 value type. - using ValueType = T; - - -// Public Data Members -public: - - - union - { - struct - { - /// X coordinate. - T x; - - /// Y coordinate. - T y; - - /// Z coordinate. - T z; - }; - - T m[3]; - }; - - -// Public Ctors -public: - - - /** - * @brief Default constructor. - */ - Vector3() noexcept; - - - /** - * @brief Constructor. - * - * @param val The X, Y and Z coordinate. - */ - explicit Vector3(T val); - - - /** - * @brief Constructor. - * - * @param x The X coordinate. - * @param y The Y coordinate. - * @param y The Z coordinate. - */ - Vector3(T x, T y, T z); - - - /** - * @brief Zero value constructor. - * - * @param[in] zero The zero value. - */ - Vector3(Zero_t zero); - - - /** - * @brief Copy constructor. - * - * @param[in] src The source vector. - */ - Vector3(const Vector3& src); - - - /** - * @brief Move constructor. - * - * @param[in] src The source vector. - */ - Vector3(Vector3&& src); - - - /** - * @brief Copy constructor. - * - * @param rhs Source vector. - * - * @tparam T2 The source vector element type. - */ - template::value>::type* = nullptr> - Vector3(const Vector3& rhs); - - -// Public Operators -public: - - - /** - * @brief Copy constructor. - * - * @param[in] zero The zero value. - * - * @return *this. - */ - Vector3& operator=(Zero_t zero); - - - /** - * @brief Copy constructor. - * - * @param[in] src The source vector. - * - * @return *this. - */ - Vector3& operator=(const Vector3& src); - - - /** - * @brief Move constructor. - * - * @param[in] src The source vector. - * - * @return *this. - */ - Vector3& operator=(Vector3&& src); - - - /** - * @brief Copy constructor. - * - * @param v The source vector. - * - * @tparam T2 The source vector element type. - * - * @return *this. - */ - template::value>::type* = nullptr> - Vector3& operator=(const Vector3& src); - - - /** - * @brief Access operator. - * - * @param pos The position. - * - * @return Reference to the element. - */ - T& operator[](int pos) noexcept; - - - /** - * @brief Access operator. - * - * @param pos The position. - * - * @return Reference to the element. - */ - const T& operator[](int pos) const noexcept; - - -// Public Accessors -public: - - - /** - * @brief Returns vector size. - * - * @return The size. - */ - int getSize() const noexcept; - - - /** - * @brief Returns X coordinate. - * - * @return The X coordinate. - */ - const T& getX() const noexcept; - - - /** - * @brief Set X coordinate. - * - * @param x The X coordinate. - */ - void setX(T x); - - - /** - * @brief Returns Y coordinate. - * - * @return The Y coordinate. - */ - const T& getY() const noexcept; - - - /** - * @brief Set Y coordinate. - * - * @param y The Y coordinate. - */ - void setY(T y); - - - /** - * @brief Returns Z coordinate. - * - * @return The Z coordinate. - */ - const T& getZ() const noexcept; - - - /** - * @brief Set Z coordinate. - * - * @param z The Z coordinate. - */ - void setZ(T z); - -}; - -/* ************************************************************************ */ - -extern template class Vector3; -extern template class Vector3; -extern template class Vector3; -extern template class Vector3; - -/* ************************************************************************ */ - -/** - * @brief Calculate cross product of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. - * - * @tparam T1 The first type. - * @tparam T2 The second type. - * - * @return Cross product. - */ -template -Vector3() * std::declval())> -cross(const Vector3& lhs, const Vector3& rhs); - -/* ************************************************************************ */ - -} -} - -/* ************************************************************************ */ -/* ************************************************************************ */ -/* ************************************************************************ */ - -namespace cece { -namespace math { - -/* ************************************************************************ */ - -template -inline Vector3::Vector3() noexcept - : x{} - , y{} - , z{} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector3::Vector3(T val) - : x{val} - , y{val} - , z{val} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector3::Vector3(T x, T y, T z) - : x{std::move(x)} - , y{std::move(y)} - , z{std::move(z)} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector3::Vector3(Zero_t zero) - : x{} - , y{} - , z{} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector3::Vector3(const Vector3& src) - : x{src.getX()} - , y{src.getY()} - , z{src.getZ()} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector3::Vector3(Vector3&& src) - : x{std::move(src.x)} - , y{std::move(src.y)} - , z{std::move(src.z)} -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -template::value>::type*> -inline Vector3::Vector3(const Vector3& rhs) - : x(rhs.getX()) - , y(rhs.getY()) - , z(rhs.getZ()) -{ - // Nothing to do -} - -/* ************************************************************************ */ - -template -inline Vector3& Vector3::operator=(Zero_t zero) -{ - x = T{}; - y = T{}; - z = T{}; - - return *this; -} - -/* ************************************************************************ */ - -template -inline Vector3& Vector3::operator=(const Vector3& src) -{ - x = src.x; - y = src.y; - z = src.z; - - return *this; -} - -/* ************************************************************************ */ - -template -inline Vector3& Vector3::operator=(Vector3&& src) -{ - x = std::move(src.x); - y = std::move(src.y); - z = std::move(src.z); - - return *this; -} - -/* ************************************************************************ */ - -template -template::value>::type*> -inline Vector3& Vector3::operator=(const Vector3& src) -{ - x = T(src.getX()); - y = T(src.getY()); - z = T(src.getZ()); - - return *this; -} - -/* ************************************************************************ */ - -template -inline int Vector3::getSize() const noexcept -{ - return 3; -} - -/* ************************************************************************ */ - -template -inline T& Vector3::operator[](int pos) noexcept -{ - CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < getSize()); - return (&x)[pos]; -} - -/* ************************************************************************ */ - -template -inline const T& Vector3::operator[](int pos) const noexcept -{ - CECE_ASSERT(pos >= 0); - CECE_ASSERT(pos < getSize()); - return (&x)[pos]; -} - -/* ************************************************************************ */ - -template -inline const T& Vector3::getX() const noexcept -{ - return x; -} - -/* ************************************************************************ */ - -template -inline void Vector3::setX(T x) -{ - this->x = std::move(x); -} - -/* ************************************************************************ */ - -template -inline const T& Vector3::getY() const noexcept -{ - return y; -} - -/* ************************************************************************ */ - -template -inline void Vector3::setY(T y) -{ - this->y = std::move(y); -} - -/* ************************************************************************ */ - -template -inline const T& Vector3::getZ() const noexcept -{ - return z; -} - -/* ************************************************************************ */ - -template -inline void Vector3::setZ(T z) -{ - this->z = std::move(z); -} - -/* ************************************************************************ */ - -template -inline Vector3() * std::declval())> cross( - const Vector3& lhs, - const Vector3& rhs -) -{ - return { - lhs.getY() * rhs.getZ() - lhs.getZ() * rhs.getY(), - lhs.getZ() * rhs.getX() - lhs.getX() * rhs.getZ(), - lhs.getX() * rhs.getY() - lhs.getY() * rhs.getX() - }; -} - -/* ************************************************************************ */ - -} -} - -/* ************************************************************************ */ diff --git a/include/cece/math/VectorBase.hpp b/include/cece/math/VectorBase.hpp index 216169c..a9f5ee1 100644 --- a/include/cece/math/VectorBase.hpp +++ b/include/cece/math/VectorBase.hpp @@ -48,12 +48,12 @@ namespace math { * * @tparam VectorType The vector type. * @tparam T Value type. - * @tparam Tags Additional tags. + * @tparam N Vector size. */ template< - template typename VectorType, + template typename VectorType, typename T, - int... Tags + int N > class VectorBase { @@ -75,7 +75,7 @@ class VectorBase * * @return Vector. */ - VectorType operator+() const noexcept; + VectorType operator+() const noexcept; /** @@ -83,7 +83,7 @@ class VectorBase * * @return Vector. */ - VectorType operator-() const noexcept; + VectorType operator-() const noexcept; /** @@ -96,7 +96,7 @@ class VectorBase * @return *this. */ template - VectorType& operator+=(const VectorType& rhs); + VectorType& operator+=(const VectorType& rhs); /** @@ -109,7 +109,7 @@ class VectorBase * @return *this. */ template - VectorType& operator-=(const VectorType& rhs); + VectorType& operator-=(const VectorType& rhs); /** @@ -122,7 +122,7 @@ class VectorBase * @return *this. */ template - VectorType& operator*=(T1 rhs); + VectorType& operator*=(T1 rhs); /** @@ -135,7 +135,7 @@ class VectorBase * @return *this. */ template - VectorType& operator*=(const VectorType& rhs); + VectorType& operator*=(const VectorType& rhs); /** @@ -148,7 +148,7 @@ class VectorBase * @return *this. */ template - VectorType& operator/=(T1 rhs); + VectorType& operator/=(T1 rhs); /** @@ -161,7 +161,7 @@ class VectorBase * @return *this. */ template - VectorType& operator/=(const VectorType& rhs); + VectorType& operator/=(const VectorType& rhs); /** @@ -193,7 +193,7 @@ class VectorBase * * @return The size. */ - int getSize() const; + constexpr int getSize() const noexcept; // Public Operations @@ -232,10 +232,10 @@ class VectorBase * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() + std::declval()), Tags...> operator+( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +VectorType() + std::declval()), N> operator+( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ @@ -253,10 +253,10 @@ VectorType() + std::declval()), Tags...> operator+ * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() - std::declval()), Tags...> operator-( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +VectorType() - std::declval()), N> operator-( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ @@ -274,10 +274,10 @@ VectorType() - std::declval()), Tags...> operator- * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() * std::declval()), Tags...> operator*( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +VectorType() * std::declval()), N> operator*( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ @@ -295,9 +295,9 @@ VectorType() * std::declval()), Tags...> operator* * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() * std::declval()), Tags...> operator*( - const VectorType& lhs, +template typename VectorType, typename T1, typename T2, int N> +VectorType() * std::declval()), N> operator*( + const VectorType& lhs, const T2& rhs ); @@ -316,10 +316,10 @@ VectorType() * std::declval()), Tags...> operator* * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() * std::declval()), Tags...> operator*( +template typename VectorType, typename T1, typename T2, int N> +VectorType() * std::declval()), N> operator*( const T1& lhs, - const VectorType& rhs + const VectorType& rhs ); /* ************************************************************************ */ @@ -337,10 +337,10 @@ VectorType() * std::declval()), Tags...> operator* * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() / std::declval()), Tags...> operator/( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +VectorType() / std::declval()), N> operator/( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ @@ -358,9 +358,9 @@ VectorType() / std::declval()), Tags...> operator/ * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() / std::declval()), Tags...> operator/( - const VectorType& lhs, +template typename VectorType, typename T1, typename T2, int N> +VectorType() / std::declval()), N> operator/( + const VectorType& lhs, const T2& rhs ); @@ -379,10 +379,10 @@ VectorType() / std::declval()), Tags...> operator/ * * @return Result vector. */ -template typename VectorType, typename T1, typename T2, int... Tags> -VectorType() / std::declval()), Tags...> operator/( +template typename VectorType, typename T1, typename T2, int N> +VectorType() / std::declval()), N> operator/( const T1& lhs, - const VectorType& rhs + const VectorType& rhs ); /* ************************************************************************ */ @@ -400,10 +400,10 @@ VectorType() / std::declval()), Tags...> operator/ * * @return Operation result. */ -template typename VectorType, typename T1, typename T2, int... Tags> +template typename VectorType, typename T1, typename T2, int N> bool operator==( - const VectorType& lhs, - const VectorType& rhs + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ @@ -420,9 +420,9 @@ bool operator==( * * @return Operation result. */ -template typename VectorType, typename T1, int... Tags> +template typename VectorType, typename T1, int N> bool operator==( - const VectorType& lhs, + const VectorType& lhs, const Zero_t& rhs ); @@ -440,10 +440,10 @@ bool operator==( * * @return Operation result. */ -template typename VectorType, typename T2, int... Tags> +template typename VectorType, typename T2, int N> bool operator==( const Zero_t& lhs, - const VectorType& rhs + const VectorType& rhs ); /* ************************************************************************ */ @@ -461,10 +461,10 @@ bool operator==( * * @return Operation result. */ -template typename VectorType, typename T1, typename T2, int... Tags> +template typename VectorType, typename T1, typename T2, int N> bool operator!=( - const VectorType& lhs, - const VectorType& rhs + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ @@ -481,9 +481,9 @@ bool operator!=( * * @return Operation result. */ -template typename VectorType, typename T1, int... Tags> +template typename VectorType, typename T1, int N> bool operator!=( - const VectorType& lhs, + const VectorType& lhs, const Zero_t& rhs ); @@ -501,142 +501,123 @@ bool operator!=( * * @return Operation result. */ -template typename VectorType, typename T2, int... Tags> +template typename VectorType, typename T2, int N> bool operator!=( const Zero_t& lhs, - const VectorType& rhs + const VectorType& rhs ); /* ************************************************************************ */ /** - * @brief Compare vectors. + * @brief Calculate dot product of two vectors. * - * @param lhs The left operand. - * @param rhs The right operand. + * @param lhs Left operand. + * @param rhs Right operand. * * @tparam VectorType Vector type. * @tparam T1 Type of value in first VectorBase. * @tparam T2 Type of value in second VectorBase. * @tparam Tags Vector type tags. * - * @return Operation result. + * @return Dot product. */ -template typename VectorType, typename T1, typename T2, int... Tags> -bool operator<( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +decltype(std::declval() * std::declval()) dot( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ /** - * @brief Compare vectors. + * @brief Calculate distance of two vectors. * - * @param lhs The left operand. - * @param rhs The right operand. + * @param lhs Left operand. + * @param rhs Right operand. * * @tparam VectorType Vector type. * @tparam T1 Type of value in first VectorBase. * @tparam T2 Type of value in second VectorBase. * @tparam Tags Vector type tags. * - * @return Operation result. + * @return Distance. */ -template typename VectorType, typename T1, typename T2, int... Tags> -bool operator<=( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +decltype(std::declval() - std::declval())>() * std::declval() - std::declval())>()) distanceSquared( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ /** - * @brief Compare vectors. + * @brief Calculate distance of two vectors. * - * @param lhs The left operand. - * @param rhs The right operand. + * @param lhs Left operand. + * @param rhs Right operand. * * @tparam VectorType Vector type. * @tparam T1 Type of value in first VectorBase. * @tparam T2 Type of value in second VectorBase. * @tparam Tags Vector type tags. * - * @return Operation result. + * @return Distance. */ -template typename VectorType, typename T1, typename T2, int... Tags> -bool operator>( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +decltype(std::declval() - std::declval()) distance( + const VectorType& lhs, + const VectorType& rhs ); /* ************************************************************************ */ /** - * @brief Compare vectors. + * @brief Check if value is in given range. * - * @param lhs The left operand. - * @param rhs The right operand. + * @code + * value >= low && value < high; + * @endcode + * + * @param[in] value The tested value. + * @param[in] low The low value. + * @param[in] high The high value. * * @tparam VectorType Vector type. - * @tparam T1 Type of value in first VectorBase. - * @tparam T2 Type of value in second VectorBase. + * @tparam T Type of value. * @tparam Tags Vector type tags. * - * @return Operation result. + * @return If value is in range. */ -template typename VectorType, typename T1, typename T2, int... Tags> -bool operator>=( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T, int N> +bool inRange( + const VectorType& value, + const VectorType& low, + const VectorType& high ); /* ************************************************************************ */ /** - * @brief Calculate dot product of two vectors. + * @brief Check if value is in given range. * - * @param lhs Left operand. - * @param rhs Right operand. + * @code + * value >= Zero && value < high; + * @endcode * - * @return Dot product. - */ -template typename VectorType, typename T1, typename T2, int... Tags> -decltype(std::declval() * std::declval()) dot( - const VectorType& lhs, - const VectorType& rhs -); - -/* ************************************************************************ */ - -/** - * @brief Calculate distance of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. + * @param[in] value The tested value. + * @param[in] high The high value. * - * @return Distance. - */ -template typename VectorType, typename T1, typename T2, int... Tags> -decltype(std::declval() - std::declval())>() * std::declval() - std::declval())>()) distanceSquared( - const VectorType& lhs, - const VectorType& rhs -); - -/* ************************************************************************ */ - -/** - * @brief Calculate distance of two vectors. - * - * @param lhs Left operand. - * @param rhs Right operand. + * @tparam VectorType Vector type. + * @tparam T Type of value. + * @tparam Tags Vector type tags. * - * @return Distance. + * @return If value is in range. */ -template typename VectorType, typename T1, typename T2, int... Tags> -decltype(std::declval() - std::declval()) distance( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T, int N> +bool inRange( + const VectorType& value, + const VectorType& high ); /* ************************************************************************ */ @@ -653,20 +634,20 @@ namespace math { /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline VectorType VectorBase::operator+() const noexcept +template typename VectorType, typename T, int N> +inline VectorType VectorBase::operator+() const noexcept { - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline VectorType VectorBase::operator-() const noexcept +template typename VectorType, typename T, int N> +inline VectorType VectorBase::operator-() const noexcept { - VectorType res; + VectorType res; - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = -(*this)[i]; return res; @@ -674,107 +655,106 @@ inline VectorType VectorBase::operator-() co /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> +template typename VectorType, typename T, int N> template -inline VectorType& VectorBase::operator+=(const VectorType& rhs) +inline VectorType& VectorBase::operator+=(const VectorType& rhs) { - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) (*this)[i] += rhs[i]; - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> +template typename VectorType, typename T, int N> template -inline VectorType& VectorBase::operator-=(const VectorType& rhs) +inline VectorType& VectorBase::operator-=(const VectorType& rhs) { - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) (*this)[i] -= rhs[i]; - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> +template typename VectorType, typename T, int N> template -inline VectorType& VectorBase::operator*=(T1 rhs) +inline VectorType& VectorBase::operator*=(T1 rhs) { - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) (*this)[i] *= rhs; - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> +template typename VectorType, typename T, int N> template -inline VectorType& VectorBase::operator*=(const VectorType& rhs) +inline VectorType& VectorBase::operator*=(const VectorType& rhs) { - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) (*this)[i] *= rhs[i]; - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> +template typename VectorType, typename T, int N> template -inline VectorType& VectorBase::operator/=(T1 rhs) +inline VectorType& VectorBase::operator/=(T1 rhs) { - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) (*this)[i] /= rhs; - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> +template typename VectorType, typename T, int N> template -inline VectorType& VectorBase::operator/=(const VectorType& rhs) +inline VectorType& VectorBase::operator/=(const VectorType& rhs) { - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) (*this)[i] /= rhs[i]; - return *static_cast*>(this); + return *static_cast*>(this); } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline T& VectorBase::operator[](int pos) +template typename VectorType, typename T, int N> +inline T& VectorBase::operator[](int pos) { // TODO: recursion possibility - return (*static_cast*>(this))[pos]; + return (*static_cast*>(this))[pos]; } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline const T& VectorBase::operator[](int pos) const +template typename VectorType, typename T, int N> +inline const T& VectorBase::operator[](int pos) const { // TODO: recursion possibility - return (*static_cast*>(this))[pos]; + return (*static_cast*>(this))[pos]; } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline int VectorBase::getSize() const +template typename VectorType, typename T, int N> +inline constexpr int VectorBase::getSize() const noexcept { - // TODO: recursion possibility - return static_cast*>(this)->getSize(); + return N; } /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline T VectorBase::getLength() const +template typename VectorType, typename T, int N> +inline T VectorBase::getLength() const { using std::sqrt; return static_cast(sqrt(getLengthSquared())); @@ -782,12 +762,12 @@ inline T VectorBase::getLength() const /* ************************************************************************ */ -template typename VectorType, typename T, int... Tags> -inline decltype(std::declval() * std::declval()) VectorBase::getLengthSquared() const +template typename VectorType, typename T, int N> +inline decltype(std::declval() * std::declval()) VectorBase::getLengthSquared() const { decltype(std::declval() * std::declval()) res{}; - for (int i = 0; i < getSize(); ++i) + for (int i = 0; i < N; ++i) res += (*this)[i] * (*this)[i]; return res; @@ -795,19 +775,15 @@ inline decltype(std::declval() * std::declval()) VectorBase typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() + std::declval()), Tags...> operator+( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() + std::declval()), N> operator+( + const VectorType& lhs, + const VectorType& rhs ) { - VectorType() + std::declval()), Tags...> res; - - CECE_ASSERT(lhs.getSize() == rhs.getSize()); - CECE_ASSERT(res.getSize() == lhs.getSize()); - CECE_ASSERT(res.getSize() == rhs.getSize()); + VectorType() + std::declval()), N> res; - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] + rhs[i]; return res; @@ -815,19 +791,15 @@ inline VectorType() + std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() - std::declval()), Tags...> operator-( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() - std::declval()), N> operator-( + const VectorType& lhs, + const VectorType& rhs ) { - VectorType() - std::declval()), Tags...> res; - - CECE_ASSERT(lhs.getSize() == rhs.getSize()); - CECE_ASSERT(res.getSize() == lhs.getSize()); - CECE_ASSERT(res.getSize() == rhs.getSize()); + VectorType() - std::declval()), N> res; - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] - rhs[i]; return res; @@ -835,19 +807,15 @@ inline VectorType() - std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() * std::declval()), Tags...> operator*( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() * std::declval()), N> operator*( + const VectorType& lhs, + const VectorType& rhs ) { - VectorType() * std::declval()), Tags...> res; + VectorType() * std::declval()), N> res; - CECE_ASSERT(lhs.getSize() == rhs.getSize()); - CECE_ASSERT(res.getSize() == lhs.getSize()); - CECE_ASSERT(res.getSize() == rhs.getSize()); - - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] * rhs[i]; return res; @@ -855,17 +823,15 @@ inline VectorType() * std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() * std::declval()), Tags...> operator*( - const VectorType& lhs, +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() * std::declval()), N> operator*( + const VectorType& lhs, const T2& rhs ) { - VectorType() * std::declval()), Tags...> res; - - CECE_ASSERT(res.getSize() == lhs.getSize()); + VectorType() * std::declval()), N> res; - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] * rhs; return res; @@ -873,17 +839,15 @@ inline VectorType() * std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() * std::declval()), Tags...> operator*( +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() * std::declval()), N> operator*( const T1& lhs, - const VectorType& rhs + const VectorType& rhs ) { - VectorType() * std::declval()), Tags...> res; - - CECE_ASSERT(res.getSize() == rhs.getSize()); + VectorType() * std::declval()), N> res; - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs * rhs[i]; return res; @@ -891,19 +855,15 @@ inline VectorType() * std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() / std::declval()), Tags...> operator/( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() / std::declval()), N> operator/( + const VectorType& lhs, + const VectorType& rhs ) { - VectorType() / std::declval()), Tags...> res; + VectorType() / std::declval()), N> res; - CECE_ASSERT(lhs.getSize() == rhs.getSize()); - CECE_ASSERT(res.getSize() == lhs.getSize()); - CECE_ASSERT(res.getSize() == rhs.getSize()); - - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] / rhs[i]; return res; @@ -911,17 +871,15 @@ inline VectorType() / std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() / std::declval()), Tags...> operator/( - const VectorType& lhs, +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() / std::declval()), N> operator/( + const VectorType& lhs, const T2& rhs ) { - VectorType() / std::declval()), Tags...> res; - - CECE_ASSERT(res.getSize() == lhs.getSize()); + VectorType() / std::declval()), N> res; - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs[i] / rhs; return res; @@ -929,17 +887,15 @@ inline VectorType() / std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline VectorType() / std::declval()), Tags...> operator/( +template typename VectorType, typename T1, typename T2, int N> +inline VectorType() / std::declval()), N> operator/( const T1& lhs, - const VectorType& rhs + const VectorType& rhs ) { - VectorType() / std::declval()), Tags...> res; - - CECE_ASSERT(res.getSize() == rhs.getSize()); + VectorType() / std::declval()), N> res; - for (int i = 0; i < res.getSize(); ++i) + for (int i = 0; i < N; ++i) res[i] = lhs / rhs[i]; return res; @@ -947,17 +903,15 @@ inline VectorType() / std::declval()), Tags...> op /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> +template typename VectorType, typename T1, typename T2, int N> inline bool operator==( - const VectorType& lhs, - const VectorType& rhs + const VectorType& lhs, + const VectorType& rhs ) { bool res = true; - CECE_ASSERT(lhs.getSize() == rhs.getSize()); - - for (int i = 0; i < lhs.getSize(); ++i) + for (int i = 0; i < N; ++i) res = res && lhs[i] == rhs[i]; return res; @@ -965,32 +919,32 @@ inline bool operator==( /* ************************************************************************ */ -template typename VectorType, typename T1, int... Tags> +template typename VectorType, typename T1, int N> inline bool operator==( - const VectorType& lhs, + const VectorType& lhs, const Zero_t& rhs ) { - return operator==(lhs, VectorType(Zero)); + return operator==(lhs, VectorType(Zero)); } /* ************************************************************************ */ -template typename VectorType, typename T2, int... Tags> +template typename VectorType, typename T2, int N> inline bool operator==( const Zero_t& lhs, - const VectorType& rhs + const VectorType& rhs ) { - return operator==(VectorType(lhs), rhs); + return operator==(VectorType(lhs), rhs); } /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> +template typename VectorType, typename T1, typename T2, int N> inline bool operator!=( - const VectorType& lhs, - const VectorType& rhs + const VectorType& lhs, + const VectorType& rhs ) { return !operator==(lhs, rhs); @@ -998,9 +952,9 @@ inline bool operator!=( /* ************************************************************************ */ -template typename VectorType, typename T1, int... Tags> +template typename VectorType, typename T1, int N> inline bool operator!=( - const VectorType& lhs, + const VectorType& lhs, const Zero_t& rhs ) { @@ -1009,10 +963,10 @@ inline bool operator!=( /* ************************************************************************ */ -template typename VectorType, typename T2, int... Tags> +template typename VectorType, typename T2, int N> inline bool operator!=( const Zero_t& lhs, - const VectorType& rhs + const VectorType& rhs ) { return !operator==(lhs, rhs); @@ -1020,93 +974,68 @@ inline bool operator!=( /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline bool operator<( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline decltype(std::declval() * std::declval()) dot( + const VectorType& lhs, + const VectorType& rhs ) { - bool res = true; - - CECE_ASSERT(lhs.getSize() == rhs.getSize()); + decltype(std::declval() * std::declval()) res{}; - for (int i = 0; i < lhs.getSize(); ++i) - res = res && (lhs[i] < rhs[i]); + for (int i = 0; i < N; ++i) + res += lhs[i] * rhs[i]; return res; } /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline bool operator<=( - const VectorType& lhs, - const VectorType& rhs -) -{ - return !operator>(lhs, rhs); -} - -/* ************************************************************************ */ - -template typename VectorType, typename T1, typename T2, int... Tags> -inline bool operator>( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline decltype(std::declval() - std::declval())>() * std::declval() - std::declval())>()) distanceSquared( + const VectorType& lhs, + const VectorType& rhs ) { - return operator<(rhs, lhs); + return (lhs - rhs).getLengthSquared(); } /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline bool operator>=( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T1, typename T2, int N> +inline decltype(std::declval() - std::declval()) distance( + const VectorType& lhs, + const VectorType& rhs ) { - return !operator<(lhs, rhs); + return (lhs - rhs).getLength(); } /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline decltype(std::declval() * std::declval()) dot( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T, int N> +inline bool inRange( + const VectorType& value, + const VectorType& low, + const VectorType& high ) { - decltype(std::declval() * std::declval()) res{}; + bool res = true; - CECE_ASSERT(lhs.getSize() == rhs.getSize()); - - for (int i = 0; i < lhs.getSize(); ++i) - res += lhs[i] * rhs[i]; + for (int i = 0; i < N; ++i) + res = res && (value[i] >= low[i] && value[i] < high[i]); return res; } /* ************************************************************************ */ -template typename VectorType, typename T1, typename T2, int... Tags> -inline decltype(std::declval() - std::declval())>() * std::declval() - std::declval())>()) distanceSquared( - const VectorType& lhs, - const VectorType& rhs +template typename VectorType, typename T, int N> +inline bool inRange( + const VectorType& value, + const VectorType& high ) { - return (lhs - rhs).getLengthSquared(); -} - -/* ************************************************************************ */ - -template typename VectorType, typename T1, typename T2, int... Tags> -inline decltype(std::declval() - std::declval()) distance( - const VectorType& lhs, - const VectorType& rhs -) -{ - return (lhs - rhs).getLength(); + return inRange(value, VectorType(Zero), high); } /* ************************************************************************ */ diff --git a/include/cece/math/VectorIo.hpp b/include/cece/math/VectorIo.hpp new file mode 100644 index 0000000..a4ae960 --- /dev/null +++ b/include/cece/math/VectorIo.hpp @@ -0,0 +1,125 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +#pragma once + +/* ************************************************************************ */ + +// CeCe +#include "cece/common.hpp" +#include "cece/Assert.hpp" +#include "cece/io/InStream.hpp" +#include "cece/io/OutStream.hpp" +#include "cece/math/VectorBase.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +/** + * @brief Input stream operator. + * + * @param is Input stream. + * @param vector Result value. + * + * @tparam VectorType Vector type. + * @tparam T Type of value. + * @tparam Tags Vector type tags. + * + * @return Input stream. + */ +template typename VectorType, typename T, int... Tags> +io::InStream& operator>>(io::InStream& is, VectorType& vector); + +/* ************************************************************************ */ + +/** + * @brief Output stream operator. + * + * @param os Output stream. + * @param vector Input value. + * + * @tparam VectorType Vector type. + * @tparam T Type of value. + * @tparam Tags Vector type tags. + * + * @return Output stream. + */ +template typename VectorType, typename T, int... Tags> +io::OutStream& operator<<(io::OutStream& os, const VectorType& vector); + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline io::InStream& operator>>(io::InStream& is, VectorType& vector) +{ + // Read all elements + for (int i = 0; i < vector.getSize(); ++i) + { + // Unable to read element + if (!(is >> std::skipws >> vector[i])) + break; + } + + return is; +} + +/* ************************************************************************ */ + +template typename VectorType, typename T, int... Tags> +inline io::OutStream& operator<<(io::OutStream& os, const VectorType& vector) +{ + for (int i = 0; i < vector.getSize(); ++i) + { + if (i != 0) + os << " "; + + os << vector[i]; + } + + return os; +} + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ diff --git a/include/cece/unit/VectorUnits.hpp b/include/cece/unit/VectorUnits.hpp index 2cecbdd..bd06b2a 100644 --- a/include/cece/unit/VectorUnits.hpp +++ b/include/cece/unit/VectorUnits.hpp @@ -106,12 +106,11 @@ namespace math { /* ************************************************************************ */ -extern template class BasicVector; -extern template class BasicVector; -extern template class BasicVector; -extern template class BasicVector; -extern template class BasicVector; -extern template class BasicVector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; +extern template class Vector; /* ************************************************************************ */ diff --git a/src/math/CMakeLists.txt b/src/math/CMakeLists.txt index ca0401b..5aac37e 100644 --- a/src/math/CMakeLists.txt +++ b/src/math/CMakeLists.txt @@ -25,8 +25,6 @@ set(SRCS Vector.cpp - Vector2.cpp - Vector3.cpp Grid.cpp ) diff --git a/src/math/Vector.cpp b/src/math/Vector.cpp index 4e89d5d..2cfb36e 100644 --- a/src/math/Vector.cpp +++ b/src/math/Vector.cpp @@ -33,9 +33,16 @@ namespace math { /* ************************************************************************ */ -template class BasicVector; -template class BasicVector; -template class BasicVector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; /* ************************************************************************ */ diff --git a/src/math/Vector3.cpp b/src/math/Vector3.cpp deleted file mode 100644 index 8904c16..0000000 --- a/src/math/Vector3.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2017 */ -/* ************************************************************************ */ -/* Department of Cybernetics */ -/* Faculty of Applied Sciences */ -/* University of West Bohemia in Pilsen */ -/* ************************************************************************ */ -/* */ -/* This file is part of CeCe. */ -/* */ -/* CeCe is free software: you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation, either version 3 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* CeCe is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with CeCe. If not, see . */ -/* */ -/* ************************************************************************ */ - -// Declaration -#include "cece/math/Vector3.hpp" - -/* ************************************************************************ */ - -namespace cece { -namespace math { - -/* ************************************************************************ */ - -template class Vector3; -template class Vector3; -template class Vector3; -template class Vector3; - -/* ************************************************************************ */ - -} -} - -/* ************************************************************************ */ diff --git a/src/simulation/DefaultSimulation.cpp b/src/simulation/DefaultSimulation.cpp index fb1556b..4caa039 100644 --- a/src/simulation/DefaultSimulation.cpp +++ b/src/simulation/DefaultSimulation.cpp @@ -41,6 +41,7 @@ #include "cece/Exception.hpp" #include "cece/log/Log.hpp" #include "cece/unit/UnitIo.hpp" +#include "cece/math/VectorIo.hpp" #include "cece/io/FileStream.hpp" #include "cece/io/OutStream.hpp" #include "cece/plugin/Api.hpp" diff --git a/src/simulation/Object.cpp b/src/simulation/Object.cpp index cee26c1..44931d0 100644 --- a/src/simulation/Object.cpp +++ b/src/simulation/Object.cpp @@ -37,6 +37,7 @@ #include "cece/Assert.hpp" #include "cece/log/Log.hpp" #include "cece/unit/UnitIo.hpp" +#include "cece/math/VectorIo.hpp" #include "cece/io/FileStream.hpp" #include "cece/config/Configuration.hpp" #include "cece/plugin/Context.hpp" diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 9f2e197..4b04f75 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -31,6 +31,7 @@ // CeCe #include "cece/unit/UnitIo.hpp" +#include "cece/math/VectorIo.hpp" #include "cece/plugin/Api.hpp" #include "cece/simulation/Initializer.hpp" #include "cece/simulation/Module.hpp" diff --git a/src/unit/VectorUnits.cpp b/src/unit/VectorUnits.cpp index 7972d18..af6e05e 100644 --- a/src/unit/VectorUnits.cpp +++ b/src/unit/VectorUnits.cpp @@ -33,12 +33,11 @@ namespace math { /* ************************************************************************ */ -template class BasicVector; -template class BasicVector; -template class BasicVector; -template class BasicVector; -template class BasicVector; -template class BasicVector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; +template class Vector; /* ************************************************************************ */ diff --git a/unittests/math/CMakeLists.txt b/unittests/math/CMakeLists.txt index 97ea6a5..1e1fc3f 100644 --- a/unittests/math/CMakeLists.txt +++ b/unittests/math/CMakeLists.txt @@ -30,6 +30,7 @@ cece_add_test(math Vector2_test.cpp Vector3_test.cpp VectorRangeTest.cpp + VectorIo_test.cpp ) # ######################################################################### # diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp index e6bad88..03dadcc 100644 --- a/unittests/math/Vector2_test.cpp +++ b/unittests/math/Vector2_test.cpp @@ -27,7 +27,7 @@ #include "gtest/gtest.h" // CeCe -#include "cece/math/Vector2.hpp" +#include "cece/math/Vector.hpp" #include "cece/unit/math.hpp" /* ************************************************************************ */ @@ -44,6 +44,8 @@ TEST(Vector2, ctor) EXPECT_EQ(0, vec.getX()); EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getWidth()); + EXPECT_EQ(0, vec.getHeight()); EXPECT_EQ(0, vec[0]); EXPECT_EQ(0, vec[1]); } @@ -53,6 +55,8 @@ TEST(Vector2, ctor) EXPECT_EQ(0, vec.getX()); EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getWidth()); + EXPECT_EQ(0, vec.getHeight()); EXPECT_EQ(0, vec[0]); EXPECT_EQ(0, vec[1]); } @@ -62,6 +66,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(12.3f, vec.getX()); EXPECT_FLOAT_EQ(12.3f, vec.getY()); + EXPECT_FLOAT_EQ(12.3f, vec.getWidth()); + EXPECT_FLOAT_EQ(12.3f, vec.getHeight()); EXPECT_FLOAT_EQ(12.3f, vec[0]); EXPECT_FLOAT_EQ(12.3f, vec[1]); } @@ -72,6 +78,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.2f, vec.getX()); EXPECT_FLOAT_EQ(3.0f, vec.getY()); + EXPECT_FLOAT_EQ(1.2f, vec.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec.getHeight()); EXPECT_FLOAT_EQ(1.2f, vec[0]); EXPECT_FLOAT_EQ(3.0f, vec[1]); } @@ -81,6 +89,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.2f, vec1.getX()); EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(1.2f, vec1.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec1.getHeight()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); EXPECT_FLOAT_EQ(3.0f, vec1[1]); @@ -88,6 +98,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.2f, vec2.getX()); EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.2f, vec2.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec2.getHeight()); EXPECT_FLOAT_EQ(1.2f, vec2[0]); EXPECT_FLOAT_EQ(3.0f, vec2[1]); } @@ -97,6 +109,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.2f, vec1.getX()); EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(1.2f, vec1.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec1.getHeight()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); EXPECT_FLOAT_EQ(3.0f, vec1[1]); @@ -104,6 +118,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.2f, vec2.getX()); EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.2f, vec2.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec2.getHeight()); EXPECT_FLOAT_EQ(1.2f, vec2[0]); EXPECT_FLOAT_EQ(3.0f, vec2[1]); } @@ -113,6 +129,8 @@ TEST(Vector2, ctor) EXPECT_EQ(1, vec1.getX()); EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(1, vec1.getWidth()); + EXPECT_EQ(3, vec1.getHeight()); EXPECT_EQ(1, vec1[0]); EXPECT_EQ(3, vec1[1]); @@ -120,6 +138,8 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.0f, vec2.getX()); EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.0f, vec2.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec2.getHeight()); EXPECT_FLOAT_EQ(1.0f, vec2[0]); EXPECT_FLOAT_EQ(3.0f, vec2[1]); } @@ -341,6 +361,29 @@ TEST(Vector2, mutators) EXPECT_EQ(100, vec.x); EXPECT_EQ(50, vec.y); } + + { + Vector2 vec; + + EXPECT_EQ(0, vec.x); + EXPECT_EQ(0, vec.y); + EXPECT_EQ(0, vec.width); + EXPECT_EQ(0, vec.height); + + vec.width = 100; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(0, vec.y); + EXPECT_EQ(100, vec.width); + EXPECT_EQ(0, vec.height); + + vec.height = 50; + + EXPECT_EQ(100, vec.x); + EXPECT_EQ(50, vec.y); + EXPECT_EQ(100, vec.width); + EXPECT_EQ(50, vec.height); + } } /* ************************************************************************ */ diff --git a/unittests/math/Vector3_test.cpp b/unittests/math/Vector3_test.cpp index ddb7eee..e57c107 100644 --- a/unittests/math/Vector3_test.cpp +++ b/unittests/math/Vector3_test.cpp @@ -27,7 +27,7 @@ #include "gtest/gtest.h" // CeCe -#include "cece/math/Vector3.hpp" +#include "cece/math/Vector.hpp" /* ************************************************************************ */ diff --git a/unittests/math/VectorBase_test.cpp b/unittests/math/VectorBase_test.cpp index 770d3bf..d963584 100644 --- a/unittests/math/VectorBase_test.cpp +++ b/unittests/math/VectorBase_test.cpp @@ -27,6 +27,7 @@ #include "gtest/gtest.h" // CeCe +#include "cece/math/Zero.hpp" #include "cece/math/VectorBase.hpp" /* ************************************************************************ */ @@ -36,10 +37,11 @@ using namespace cece::math; /* ************************************************************************ */ -template -struct Vec2 : public VectorBase +template +struct Vec2 : public VectorBase { Vec2() : x{}, y{} {} + Vec2(Zero_t) : x{}, y{} {} Vec2(T x, T y) : x{x}, y{y} {} T& operator[](int pos) { return (&x)[pos]; } @@ -104,6 +106,19 @@ TEST(VectorBase, operators) EXPECT_FLOAT_EQ(4.0f, vec1[1]); } + { + Vec2 vec1{1, 2}; + + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(2, vec1[1]); + + Vec2 vec2{1.0f, 2.0f}; + vec1 += vec2; + + EXPECT_EQ(2, vec1[0]); + EXPECT_EQ(4, vec1[1]); + } + { Vec2 vec1{1.0f, 2.0f}; @@ -264,6 +279,33 @@ TEST(VectorBase, functions) res ); } + + { + const Vec2 vecMin{-10.0f, -5.0f}; + const Vec2 vecMax{10.0f, 20.0f}; + + Vec2 vec1; + Vec2 vec2{-15.0f, 0.0f}; + Vec2 vec3{5.0f, 0.0f}; + Vec2 vec4{5.0f, 25.0f}; + + EXPECT_TRUE(inRange(vec1, vecMin, vecMax)); + EXPECT_FALSE(inRange(vec2, vecMin, vecMax)); + EXPECT_TRUE(inRange(vec3, vecMin, vecMax)); + EXPECT_FALSE(inRange(vec4, vecMin, vecMax)); + } + + { + const Vec2 vecMax{10.0f, 20.0f}; + + Vec2 vec1; + Vec2 vec2{-15.0f, 0.0f}; + Vec2 vec3{5.0f, 0.0f}; + + EXPECT_TRUE(inRange(vec1, vecMax)); + EXPECT_FALSE(inRange(vec2, vecMax)); + EXPECT_TRUE(inRange(vec3, vecMax)); + } } /* ************************************************************************ */ @@ -383,12 +425,16 @@ TEST(VectorBase, freeOperators) } { + const Vec2 vec0(Zero); const Vec2 vec1(5.3f, 8.9f); const Vec2 vec2(5.3f, 8.9f); const Vec2 vec3(1.3f, 8.9f); const Vec2 vec4(5.3f, 0.9f); const Vec2 vec5(1.3f, 0.9f); + EXPECT_EQ(vec0, Zero); + EXPECT_EQ(Zero, vec0); + EXPECT_EQ(vec1, vec1); EXPECT_EQ(vec1, vec2); EXPECT_NE(vec1, vec3); @@ -408,22 +454,6 @@ TEST(VectorBase, freeOperators) EXPECT_NE(vec4, vec2); EXPECT_NE(vec4, vec3); EXPECT_EQ(vec4, vec4); - - EXPECT_FALSE(vec1 < vec2); - - EXPECT_GE(vec1, vec1); - EXPECT_GE(vec1, vec2); - EXPECT_GE(vec1, vec3); - EXPECT_GE(vec1, vec4); - - EXPECT_GT(vec1, vec5); - - EXPECT_LE(vec1, vec1); - EXPECT_LE(vec1, vec2); - EXPECT_LE(vec3, vec1); - EXPECT_LE(vec4, vec1); - - EXPECT_LT(vec5, vec1); } } diff --git a/src/math/Vector2.cpp b/unittests/math/VectorIo_test.cpp similarity index 53% rename from src/math/Vector2.cpp rename to unittests/math/VectorIo_test.cpp index 824623e..bcff064 100644 --- a/src/math/Vector2.cpp +++ b/unittests/math/VectorIo_test.cpp @@ -1,5 +1,5 @@ /* ************************************************************************ */ -/* Georgiev Lab (c) 2015-2017 */ +/* Georgiev Lab (c) 2015-2016 */ /* ************************************************************************ */ /* Department of Cybernetics */ /* Faculty of Applied Sciences */ @@ -23,24 +23,114 @@ /* */ /* ************************************************************************ */ -// Declaration -#include "cece/math/Vector2.hpp" +// GTest +#include "gtest/gtest.h" + +// CeCe +#include "cece/io/StringStream.hpp" +#include "cece/math/VectorIo.hpp" +#include "cece/math/Vector.hpp" /* ************************************************************************ */ -namespace cece { -namespace math { +using namespace cece; +using namespace cece::math; /* ************************************************************************ */ -template class Vector2; -template class Vector2; -template class Vector2; -template class Vector2; +TEST(VectorIo, read) +{ + { + io::InStringStream iss("200 100"); + + Vector2 vec; + iss >> vec; + + EXPECT_EQ(200, vec.x); + EXPECT_EQ(100, vec.y); + } + + { + io::InStringStream iss("200 100"); + + Vector2 vec; + iss >> vec; + + EXPECT_FLOAT_EQ(200.f, vec.x); + EXPECT_FLOAT_EQ(100.f, vec.y); + } + + { + io::InStringStream iss("2.3 100.15"); + + Vector2 vec; + iss >> vec; + + EXPECT_FLOAT_EQ(2.3f, vec.x); + EXPECT_FLOAT_EQ(100.15f, vec.y); + } +} /* ************************************************************************ */ +TEST(VectorIo, readFail) +{ + { + io::InStringStream iss("200"); + + Vector2 vec; + iss >> vec; + EXPECT_FALSE(iss); + } + + { + io::InStringStream iss("23.3"); + + Vector2 vec; + iss >> vec; + EXPECT_FALSE(iss); + } } + +/* ************************************************************************ */ + +TEST(VectorIo, write) +{ + { + io::OutStringStream oss; + + Vector2 vec{200, 100}; + EXPECT_EQ(200, vec.x); + EXPECT_EQ(100, vec.y); + + oss << vec; + + EXPECT_EQ("200 100", oss.str()); + } + + { + io::OutStringStream oss; + + Vector2 vec{200.f, 100.f}; + EXPECT_FLOAT_EQ(200.f, vec.x); + EXPECT_FLOAT_EQ(100.f, vec.y); + + oss << vec; + + EXPECT_EQ("200 100", oss.str()); + } + + { + io::OutStringStream oss; + + Vector2 vec{2.3f, 100.15f}; + EXPECT_FLOAT_EQ(2.3f, vec.x); + EXPECT_FLOAT_EQ(100.15f, vec.y); + + oss << vec; + + EXPECT_EQ("2.3 100.15", oss.str()); + } } /* ************************************************************************ */ From 53beb29141ae53f57503c49ef5244d7c335ff0db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Thu, 8 Jun 2017 17:27:54 +0200 Subject: [PATCH 09/11] Added constexpr to math::Vector classes. --- include/cece/math/Vector.hpp | 126 +++++++++++++++------------- include/cece/math/VectorBase.hpp | 4 +- unittests/math/Vector2_test.cpp | 139 ++++++++++++++++++++++++++++++- unittests/math/Vector3_test.cpp | 73 ++++++++++++++++ unittests/math/Vector_test.cpp | 102 +++++++++++------------ 5 files changed, 329 insertions(+), 115 deletions(-) diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index c4dd936..cd01f0e 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -83,7 +83,7 @@ class Vector : public VectorBase /** * @brief Default constructor. */ - Vector() noexcept; + constexpr Vector() noexcept; /** @@ -239,7 +239,7 @@ class Vector : public VectorBase * * @return Reference to the element. */ - const T& operator[](int pos) const noexcept; + constexpr const T& operator[](int pos) const noexcept; }; @@ -297,7 +297,7 @@ struct Vector : public VectorBase /** * @brief Default constructor. */ - Vector(); + constexpr Vector(); /** @@ -305,7 +305,7 @@ struct Vector : public VectorBase * * @param x The X and Y coordinate. */ - explicit Vector(T value); + explicit constexpr Vector(T value); /** @@ -314,7 +314,7 @@ struct Vector : public VectorBase * @param x The X coordinate. * @param y The Y coordinate. */ - Vector(T x, T y); + constexpr Vector(T x, T y); /** @@ -322,7 +322,7 @@ struct Vector : public VectorBase * * @param[in] zero The zero value. */ - Vector(Zero_t zero); + constexpr Vector(Zero_t zero); /** @@ -330,7 +330,7 @@ struct Vector : public VectorBase * * @param[in] src The source vector. */ - Vector(const Vector& src); + constexpr Vector(const Vector& src); /** @@ -338,7 +338,7 @@ struct Vector : public VectorBase * * @param[in] src The source vector. */ - Vector(Vector&& src); + constexpr Vector(Vector&& src); /** @@ -349,7 +349,7 @@ struct Vector : public VectorBase * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - Vector(const Vector& rhs); + constexpr Vector(const Vector& rhs); // Public Operators @@ -416,7 +416,7 @@ struct Vector : public VectorBase * * @return Reference to the element. */ - const T& operator[](int pos) const noexcept; + constexpr const T& operator[](int pos) const noexcept; // Public Accessors @@ -428,7 +428,7 @@ struct Vector : public VectorBase * * @return The X coordinate. */ - const T& getX() const noexcept; + constexpr const T& getX() const noexcept; /** @@ -444,7 +444,7 @@ struct Vector : public VectorBase * * @return The Y coordinate. */ - const T& getY() const noexcept; + constexpr const T& getY() const noexcept; /** @@ -460,7 +460,7 @@ struct Vector : public VectorBase * * @return The width. */ - const T& getWidth() const noexcept; + constexpr const T& getWidth() const noexcept; /** @@ -476,7 +476,7 @@ struct Vector : public VectorBase * * @return The height. */ - const T& getHeight() const noexcept; + constexpr const T& getHeight() const noexcept; /** @@ -588,7 +588,7 @@ struct Vector : public VectorBase /** * @brief Default constructor. */ - Vector() noexcept; + constexpr Vector() noexcept; /** @@ -596,7 +596,7 @@ struct Vector : public VectorBase * * @param val The X, Y and Z coordinate. */ - explicit Vector(T val); + explicit constexpr Vector(T val); /** @@ -606,7 +606,7 @@ struct Vector : public VectorBase * @param y The Y coordinate. * @param y The Z coordinate. */ - Vector(T x, T y, T z); + constexpr Vector(T x, T y, T z); /** @@ -614,7 +614,7 @@ struct Vector : public VectorBase * * @param[in] zero The zero value. */ - Vector(Zero_t zero); + constexpr Vector(Zero_t zero); /** @@ -622,7 +622,7 @@ struct Vector : public VectorBase * * @param[in] src The source vector. */ - Vector(const Vector& src); + constexpr Vector(const Vector& src); /** @@ -630,7 +630,7 @@ struct Vector : public VectorBase * * @param[in] src The source vector. */ - Vector(Vector&& src); + constexpr Vector(Vector&& src); /** @@ -641,7 +641,7 @@ struct Vector : public VectorBase * @tparam T2 The source vector element type. */ template::value>::type* = nullptr> - Vector(const Vector& rhs); + constexpr Vector(const Vector& rhs); // Public Operators @@ -708,7 +708,7 @@ struct Vector : public VectorBase * * @return Reference to the element. */ - const T& operator[](int pos) const noexcept; + constexpr const T& operator[](int pos) const noexcept; // Public Accessors @@ -720,7 +720,7 @@ struct Vector : public VectorBase * * @return The X coordinate. */ - const T& getX() const noexcept; + constexpr const T& getX() const noexcept; /** @@ -736,7 +736,7 @@ struct Vector : public VectorBase * * @return The Y coordinate. */ - const T& getY() const noexcept; + constexpr const T& getY() const noexcept; /** @@ -752,7 +752,7 @@ struct Vector : public VectorBase * * @return The Z coordinate. */ - const T& getZ() const noexcept; + constexpr const T& getZ() const noexcept; /** @@ -768,7 +768,7 @@ struct Vector : public VectorBase * * @return The width. */ - const T& getWidth() const noexcept; + constexpr const T& getWidth() const noexcept; /** @@ -784,7 +784,7 @@ struct Vector : public VectorBase * * @return The height. */ - const T& getHeight() const noexcept; + constexpr const T& getHeight() const noexcept; /** @@ -800,7 +800,7 @@ struct Vector : public VectorBase * * @return The depth. */ - const T& getDepth() const noexcept; + constexpr const T& getDepth() const noexcept; /** @@ -978,7 +978,7 @@ using SizeVector = Vector; * @return Rotated vector. */ template -Vector rotate(const Vector& vec, unit::Angle angle) noexcept; +constexpr Vector rotate(const Vector& vec, unit::Angle angle) noexcept; /* ************************************************************************ */ @@ -994,7 +994,7 @@ Vector rotate(const Vector& vec, unit::Angle angle) noexcept; * @return Cross product. */ template -Vector() * std::declval()), 3> +constexpr Vector() * std::declval()), 3> cross(const Vector& lhs, const Vector& rhs); /* ************************************************************************ */ @@ -1031,7 +1031,7 @@ namespace math { /* ************************************************************************ */ template -inline Vector::Vector() noexcept +inline constexpr Vector::Vector() noexcept : m{} { // Nothing to do @@ -1207,17 +1207,19 @@ inline T& Vector::operator[](int pos) noexcept /* ************************************************************************ */ template -inline const T& Vector::operator[](int pos) const noexcept +inline constexpr const T& Vector::operator[](int pos) const noexcept { +#if __cplusplus >= 201402L CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < N); +#endif return m[pos]; } /* ************************************************************************ */ template -inline Vector::Vector() +inline constexpr Vector::Vector() : x{} , y{} { @@ -1227,7 +1229,7 @@ inline Vector::Vector() /* ************************************************************************ */ template -inline Vector::Vector(T val) +inline constexpr Vector::Vector(T val) : x{val} , y{val} { @@ -1237,7 +1239,7 @@ inline Vector::Vector(T val) /* ************************************************************************ */ template -inline Vector::Vector(T x, T y) +inline constexpr Vector::Vector(T x, T y) : x{std::move(x)} , y{std::move(y)} { @@ -1247,7 +1249,7 @@ inline Vector::Vector(T x, T y) /* ************************************************************************ */ template -inline Vector::Vector(Zero_t zero) +inline constexpr Vector::Vector(Zero_t zero) : x{} , y{} { @@ -1257,7 +1259,7 @@ inline Vector::Vector(Zero_t zero) /* ************************************************************************ */ template -inline Vector::Vector(const Vector& src) +inline constexpr Vector::Vector(const Vector& src) : x{src.getX()} , y{src.getY()} { @@ -1267,7 +1269,7 @@ inline Vector::Vector(const Vector& src) /* ************************************************************************ */ template -inline Vector::Vector(Vector&& src) +inline constexpr Vector::Vector(Vector&& src) : x{std::move(src.x)} , y{std::move(src.y)} { @@ -1278,7 +1280,7 @@ inline Vector::Vector(Vector&& src) template template::value>::type*> -inline Vector::Vector(const Vector& rhs) +inline constexpr Vector::Vector(const Vector& rhs) : x(rhs.getX()) , y(rhs.getY()) { @@ -1343,17 +1345,19 @@ inline T& Vector::operator[](int pos) noexcept /* ************************************************************************ */ template -inline const T& Vector::operator[](int pos) const noexcept +inline constexpr const T& Vector::operator[](int pos) const noexcept { +#if __cplusplus >= 201402L CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 2); +#endif return (&x)[pos]; } /* ************************************************************************ */ template -inline const T& Vector::getX() const noexcept +inline constexpr const T& Vector::getX() const noexcept { return x; } @@ -1369,7 +1373,7 @@ inline void Vector::setX(T x) /* ************************************************************************ */ template -inline const T& Vector::getY() const noexcept +inline constexpr const T& Vector::getY() const noexcept { return y; } @@ -1385,7 +1389,7 @@ inline void Vector::setY(T y) /* ************************************************************************ */ template -inline const T& Vector::getWidth() const noexcept +inline constexpr const T& Vector::getWidth() const noexcept { return width; } @@ -1401,7 +1405,7 @@ inline void Vector::setWidth(T width) /* ************************************************************************ */ template -inline const T& Vector::getHeight() const noexcept +inline constexpr const T& Vector::getHeight() const noexcept { return height; } @@ -1417,7 +1421,7 @@ inline void Vector::setHeight(T height) /* ************************************************************************ */ template -inline Vector::Vector() noexcept +inline constexpr Vector::Vector() noexcept : x{} , y{} , z{} @@ -1428,7 +1432,7 @@ inline Vector::Vector() noexcept /* ************************************************************************ */ template -inline Vector::Vector(T val) +inline constexpr Vector::Vector(T val) : x{val} , y{val} , z{val} @@ -1439,7 +1443,7 @@ inline Vector::Vector(T val) /* ************************************************************************ */ template -inline Vector::Vector(T x, T y, T z) +inline constexpr Vector::Vector(T x, T y, T z) : x{std::move(x)} , y{std::move(y)} , z{std::move(z)} @@ -1450,7 +1454,7 @@ inline Vector::Vector(T x, T y, T z) /* ************************************************************************ */ template -inline Vector::Vector(Zero_t zero) +inline constexpr Vector::Vector(Zero_t zero) : x{} , y{} , z{} @@ -1461,7 +1465,7 @@ inline Vector::Vector(Zero_t zero) /* ************************************************************************ */ template -inline Vector::Vector(const Vector& src) +inline constexpr Vector::Vector(const Vector& src) : x{src.getX()} , y{src.getY()} , z{src.getZ()} @@ -1472,7 +1476,7 @@ inline Vector::Vector(const Vector& src) /* ************************************************************************ */ template -inline Vector::Vector(Vector&& src) +inline constexpr Vector::Vector(Vector&& src) : x{std::move(src.x)} , y{std::move(src.y)} , z{std::move(src.z)} @@ -1484,7 +1488,7 @@ inline Vector::Vector(Vector&& src) template template::value>::type*> -inline Vector::Vector(const Vector& rhs) +inline constexpr Vector::Vector(const Vector& rhs) : x(rhs.getX()) , y(rhs.getY()) , z(rhs.getZ()) @@ -1554,17 +1558,19 @@ inline T& Vector::operator[](int pos) noexcept /* ************************************************************************ */ template -inline const T& Vector::operator[](int pos) const noexcept +inline constexpr const T& Vector::operator[](int pos) const noexcept { +#if __cplusplus >= 201402L CECE_ASSERT(pos >= 0); CECE_ASSERT(pos < 3); +#endif return (&x)[pos]; } /* ************************************************************************ */ template -inline const T& Vector::getX() const noexcept +inline constexpr const T& Vector::getX() const noexcept { return x; } @@ -1580,7 +1586,7 @@ inline void Vector::setX(T x) /* ************************************************************************ */ template -inline const T& Vector::getY() const noexcept +inline constexpr const T& Vector::getY() const noexcept { return y; } @@ -1596,7 +1602,7 @@ inline void Vector::setY(T y) /* ************************************************************************ */ template -inline const T& Vector::getZ() const noexcept +inline constexpr const T& Vector::getZ() const noexcept { return z; } @@ -1612,7 +1618,7 @@ inline void Vector::setZ(T z) /* ************************************************************************ */ template -inline const T& Vector::getWidth() const noexcept +inline constexpr const T& Vector::getWidth() const noexcept { return width; } @@ -1628,7 +1634,7 @@ inline void Vector::setWidth(T width) /* ************************************************************************ */ template -inline const T& Vector::getHeight() const noexcept +inline constexpr const T& Vector::getHeight() const noexcept { return height; } @@ -1644,7 +1650,7 @@ inline void Vector::setHeight(T height) /* ************************************************************************ */ template -inline const T& Vector::getDepth() const noexcept +inline constexpr const T& Vector::getDepth() const noexcept { return depth; } @@ -1660,7 +1666,7 @@ inline void Vector::setDepth(T depth) /* ************************************************************************ */ template -inline Vector rotate(const Vector& vec, unit::Angle angle) noexcept +inline constexpr Vector rotate(const Vector& vec, unit::Angle angle) noexcept { return { static_cast(vec.getX() * cos(static_cast(angle)) - vec.getY() * sin(static_cast(angle))), @@ -1671,7 +1677,7 @@ inline Vector rotate(const Vector& vec, unit::Angle angle) noexcept /* ************************************************************************ */ template -inline Vector() * std::declval()), 3> cross( +inline constexpr Vector() * std::declval()), 3> cross( const Vector& lhs, const Vector& rhs ) diff --git a/include/cece/math/VectorBase.hpp b/include/cece/math/VectorBase.hpp index a9f5ee1..18ed4d5 100644 --- a/include/cece/math/VectorBase.hpp +++ b/include/cece/math/VectorBase.hpp @@ -181,7 +181,7 @@ class VectorBase * * @return Reference to the element. */ - const T& operator[](int pos) const; + constexpr const T& operator[](int pos) const; // Public Accessors @@ -737,7 +737,7 @@ inline T& VectorBase::operator[](int pos) /* ************************************************************************ */ template typename VectorType, typename T, int N> -inline const T& VectorBase::operator[](int pos) const +inline constexpr const T& VectorBase::operator[](int pos) const { // TODO: recursion possibility return (*static_cast*>(this))[pos]; diff --git a/unittests/math/Vector2_test.cpp b/unittests/math/Vector2_test.cpp index 03dadcc..ec9cb93 100644 --- a/unittests/math/Vector2_test.cpp +++ b/unittests/math/Vector2_test.cpp @@ -50,6 +50,17 @@ TEST(Vector2, ctor) EXPECT_EQ(0, vec[1]); } + { + constexpr Vector2 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getWidth()); + EXPECT_EQ(0, vec.getHeight()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + } + { Vector2 vec(Zero); @@ -61,6 +72,17 @@ TEST(Vector2, ctor) EXPECT_EQ(0, vec[1]); } + { + constexpr Vector2 vec(Zero); + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getWidth()); + EXPECT_EQ(0, vec.getHeight()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + } + { Vector2 vec(12.3f); @@ -72,6 +94,16 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(12.3f, vec[1]); } + { + constexpr Vector2 vec(12.3f); + + EXPECT_FLOAT_EQ(12.3f, vec.getX()); + EXPECT_FLOAT_EQ(12.3f, vec.getY()); + EXPECT_FLOAT_EQ(12.3f, vec.getWidth()); + EXPECT_FLOAT_EQ(12.3f, vec.getHeight()); + EXPECT_FLOAT_EQ(12.3f, vec[0]); + EXPECT_FLOAT_EQ(12.3f, vec[1]); + } { Vector2 vec = {1.2f, 3.0f}; @@ -84,6 +116,17 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(3.0f, vec[1]); } + { + constexpr Vector2 vec = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec.getX()); + EXPECT_FLOAT_EQ(3.0f, vec.getY()); + EXPECT_FLOAT_EQ(1.2f, vec.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec.getHeight()); + EXPECT_FLOAT_EQ(1.2f, vec[0]); + EXPECT_FLOAT_EQ(3.0f, vec[1]); + } + { const Vector2 vec1 = {1.2f, 3.0f}; @@ -104,6 +147,26 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(3.0f, vec2[1]); } + { + constexpr const Vector2 vec1 = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec1.getX()); + EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(1.2f, vec1.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec1.getHeight()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + + constexpr Vector2 vec2(vec1); + + EXPECT_FLOAT_EQ(1.2f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.2f, vec2.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec2.getHeight()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } + { Vector2 vec1 = {1.2f, 3.0f}; @@ -124,6 +187,26 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(3.0f, vec2[1]); } + { + constexpr Vector2 vec1 = {1.2f, 3.0f}; + + EXPECT_FLOAT_EQ(1.2f, vec1.getX()); + EXPECT_FLOAT_EQ(3.0f, vec1.getY()); + EXPECT_FLOAT_EQ(1.2f, vec1.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec1.getHeight()); + EXPECT_FLOAT_EQ(1.2f, vec1[0]); + EXPECT_FLOAT_EQ(3.0f, vec1[1]); + + constexpr Vector2 vec2(std::move(vec1)); + + EXPECT_FLOAT_EQ(1.2f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.2f, vec2.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec2.getHeight()); + EXPECT_FLOAT_EQ(1.2f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } + { const Vector2 vec1 = {1, 3}; @@ -143,6 +226,26 @@ TEST(Vector2, ctor) EXPECT_FLOAT_EQ(1.0f, vec2[0]); EXPECT_FLOAT_EQ(3.0f, vec2[1]); } + + { + constexpr const Vector2 vec1 = {1, 3}; + + EXPECT_EQ(1, vec1.getX()); + EXPECT_EQ(3, vec1.getY()); + EXPECT_EQ(1, vec1.getWidth()); + EXPECT_EQ(3, vec1.getHeight()); + EXPECT_EQ(1, vec1[0]); + EXPECT_EQ(3, vec1[1]); + + constexpr Vector2 vec2(vec1); + + EXPECT_FLOAT_EQ(1.0f, vec2.getX()); + EXPECT_FLOAT_EQ(3.0f, vec2.getY()); + EXPECT_FLOAT_EQ(1.0f, vec2.getWidth()); + EXPECT_FLOAT_EQ(3.0f, vec2.getHeight()); + EXPECT_FLOAT_EQ(1.0f, vec2[0]); + EXPECT_FLOAT_EQ(3.0f, vec2[1]); + } } /* ************************************************************************ */ @@ -370,14 +473,14 @@ TEST(Vector2, mutators) EXPECT_EQ(0, vec.width); EXPECT_EQ(0, vec.height); - vec.width = 100; + vec.setWidth(100); EXPECT_EQ(100, vec.x); EXPECT_EQ(0, vec.y); EXPECT_EQ(100, vec.width); EXPECT_EQ(0, vec.height); - vec.height = 50; + vec.setHeight(50); EXPECT_EQ(100, vec.x); EXPECT_EQ(50, vec.y); @@ -426,6 +529,18 @@ TEST(Vector2, functions) EXPECT_EQ(0, rot.getY()); } + { + constexpr Vector2 vec(1, 0); + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(0, vec.getY()); + + /*constexpr*/ auto rot = rotate(vec, unit::deg2rad(180)); + + EXPECT_EQ(-1, rot.getX()); + EXPECT_EQ(0, rot.getY()); + } + { Vector2 vec1(0.94333f, 0.73733f); Vector2 vec2(0.16110f, 0.61872f); @@ -445,6 +560,26 @@ TEST(Vector2, functions) ); } + { + constexpr Vector2 vec1(0.94333f, 0.73733f); + constexpr Vector2 vec2(0.16110f, 0.61872f); + + EXPECT_FLOAT_EQ(0.94333f, vec1.getX()); + EXPECT_FLOAT_EQ(0.73733f, vec1.getY()); + + EXPECT_FLOAT_EQ(0.16110f, vec2.getX()); + EXPECT_FLOAT_EQ(0.61872f, vec2.getY()); + + /*constexpr*/ auto res = dot(vec1, vec2); + + EXPECT_FLOAT_EQ( + 0.94333f * 0.16110f + + 0.73733f * 0.61872f, + res + ); + } + + { const Vector2 vec; diff --git a/unittests/math/Vector3_test.cpp b/unittests/math/Vector3_test.cpp index e57c107..b997726 100644 --- a/unittests/math/Vector3_test.cpp +++ b/unittests/math/Vector3_test.cpp @@ -49,6 +49,17 @@ TEST(Vector3, ctorDefault) EXPECT_EQ(0, vec[2]); } + { + constexpr Vector3 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + { Vector3 vec; @@ -60,6 +71,17 @@ TEST(Vector3, ctorDefault) EXPECT_EQ(0, vec[2]); } + { + constexpr Vector3 vec; + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + { Vector3 vec; @@ -98,6 +120,17 @@ TEST(Vector3, ctorZero) EXPECT_EQ(0, vec[2]); } + { + constexpr Vector3 vec(Zero); + + EXPECT_EQ(0, vec.getX()); + EXPECT_EQ(0, vec.getY()); + EXPECT_EQ(0, vec.getZ()); + EXPECT_EQ(0, vec[0]); + EXPECT_EQ(0, vec[1]); + EXPECT_EQ(0, vec[2]); + } + { Vector3 vec(Zero); @@ -147,6 +180,17 @@ TEST(Vector3, ctorSingle) EXPECT_EQ(1, vec[2]); } + { + constexpr Vector3 vec{1}; + + EXPECT_EQ(1, vec.getX()); + EXPECT_EQ(1, vec.getY()); + EXPECT_EQ(1, vec.getZ()); + EXPECT_EQ(1, vec[0]); + EXPECT_EQ(1, vec[1]); + EXPECT_EQ(1, vec[2]); + } + { Vector3 vec{3}; @@ -1250,6 +1294,35 @@ TEST(Vector3, mutators) EXPECT_DOUBLE_EQ(10, vec.getZ()); } + { + Vector3 vec; + + EXPECT_DOUBLE_EQ(0, vec.getX()); + EXPECT_DOUBLE_EQ(0, vec.getY()); + EXPECT_DOUBLE_EQ(0, vec.getZ()); + + vec.setWidth(100.3); + + EXPECT_DOUBLE_EQ(100.3, vec.getX()); + EXPECT_DOUBLE_EQ(0, vec.getY()); + EXPECT_DOUBLE_EQ(0, vec.getZ()); + + vec.setHeight(50); + + EXPECT_DOUBLE_EQ(100.3, vec.getX()); + EXPECT_DOUBLE_EQ(50, vec.getY()); + EXPECT_DOUBLE_EQ(0, vec.getZ()); + + vec.setDepth(10); + + EXPECT_DOUBLE_EQ(100.3, vec.getX()); + EXPECT_DOUBLE_EQ(50, vec.getY()); + EXPECT_DOUBLE_EQ(10, vec.getZ()); + EXPECT_DOUBLE_EQ(100.3, vec.getWidth()); + EXPECT_DOUBLE_EQ(50, vec.getHeight()); + EXPECT_DOUBLE_EQ(10, vec.getDepth()); + } + { Vector3 vec; diff --git a/unittests/math/Vector_test.cpp b/unittests/math/Vector_test.cpp index e65f32d..4f18e8c 100644 --- a/unittests/math/Vector_test.cpp +++ b/unittests/math/Vector_test.cpp @@ -39,7 +39,7 @@ using namespace cece::math; TEST(Vector, ctor) { { - BasicVector vec; + Vector vec; EXPECT_EQ(5, vec.getSize()); EXPECT_EQ(0, vec[0]); @@ -50,7 +50,7 @@ TEST(Vector, ctor) } { - BasicVector vec(Zero); + Vector vec(Zero); EXPECT_EQ(10, vec.getSize()); EXPECT_EQ(0, vec[0]); @@ -66,7 +66,7 @@ TEST(Vector, ctor) } { - BasicVector vec = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + Vector vec = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; EXPECT_EQ(5, vec.getSize()); EXPECT_FLOAT_EQ(1.2f, vec[0]); @@ -79,7 +79,7 @@ TEST(Vector, ctor) { float data[5] = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; - BasicVector vec(data); + Vector vec(data); EXPECT_EQ(5, vec.getSize()); EXPECT_FLOAT_EQ(1.2f, vec[0]); @@ -92,7 +92,7 @@ TEST(Vector, ctor) { StaticArray data = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; - BasicVector vec(data); + Vector vec(data); EXPECT_EQ(5, vec.getSize()); EXPECT_FLOAT_EQ(1.2f, vec[0]); @@ -103,7 +103,7 @@ TEST(Vector, ctor) } { - const BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + const Vector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); @@ -112,7 +112,7 @@ TEST(Vector, ctor) EXPECT_FLOAT_EQ(45.1f, vec1[3]); EXPECT_FLOAT_EQ(-34.0f, vec1[4]); - BasicVector vec2(vec1); + Vector vec2(vec1); EXPECT_EQ(5, vec2.getSize()); EXPECT_FLOAT_EQ(1.2f, vec2[0]); @@ -123,7 +123,7 @@ TEST(Vector, ctor) } { - BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + Vector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); @@ -132,7 +132,7 @@ TEST(Vector, ctor) EXPECT_FLOAT_EQ(45.1f, vec1[3]); EXPECT_FLOAT_EQ(-34.0f, vec1[4]); - BasicVector vec2(std::move(vec1)); + Vector vec2(std::move(vec1)); EXPECT_EQ(5, vec2.getSize()); EXPECT_FLOAT_EQ(1.2f, vec2[0]); @@ -143,7 +143,7 @@ TEST(Vector, ctor) } { - const BasicVector vec1 = {1, 3, 0, 45, -34}; + const Vector vec1 = {1, 3, 0, 45, -34}; EXPECT_EQ(5, vec1.getSize()); EXPECT_EQ(1, vec1[0]); @@ -152,7 +152,7 @@ TEST(Vector, ctor) EXPECT_EQ(45, vec1[3]); EXPECT_EQ(-34, vec1[4]); - BasicVector vec2(vec1); + Vector vec2(vec1); EXPECT_EQ(5, vec2.getSize()); EXPECT_FLOAT_EQ(1.0, vec2[0]); @@ -168,7 +168,7 @@ TEST(Vector, ctor) TEST(Vector, assignment) { { - BasicVector vec{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + Vector vec{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; EXPECT_EQ(10, vec.getSize()); EXPECT_EQ(1, vec[0]); @@ -198,7 +198,7 @@ TEST(Vector, assignment) } { - BasicVector vec; + Vector vec; EXPECT_EQ(5, vec.getSize()); EXPECT_EQ(0, vec[0]); @@ -218,7 +218,7 @@ TEST(Vector, assignment) } { - BasicVector vec; + Vector vec; EXPECT_EQ(5, vec.getSize()); EXPECT_EQ(0, vec[0]); @@ -240,7 +240,7 @@ TEST(Vector, assignment) } { - BasicVector vec; + Vector vec; EXPECT_EQ(5, vec.getSize()); EXPECT_EQ(0, vec[0]); @@ -262,7 +262,7 @@ TEST(Vector, assignment) } { - const BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + const Vector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); @@ -271,7 +271,7 @@ TEST(Vector, assignment) EXPECT_FLOAT_EQ(45.1f, vec1[3]); EXPECT_FLOAT_EQ(-34.0f, vec1[4]); - BasicVector vec2; + Vector vec2; vec2 = vec1; @@ -284,7 +284,7 @@ TEST(Vector, assignment) } { - BasicVector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; + Vector vec1 = {1.2f, 3.0f, 0.0f, 45.1f, -34.f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.2f, vec1[0]); @@ -293,7 +293,7 @@ TEST(Vector, assignment) EXPECT_FLOAT_EQ(45.1f, vec1[3]); EXPECT_FLOAT_EQ(-34.0f, vec1[4]); - BasicVector vec2; + Vector vec2; vec2 = std::move(vec1); @@ -306,7 +306,7 @@ TEST(Vector, assignment) } { - const BasicVector vec1 = {1, 3, 0, 45, -34}; + const Vector vec1 = {1, 3, 0, 45, -34}; EXPECT_EQ(5, vec1.getSize()); EXPECT_EQ(1, vec1[0]); @@ -315,7 +315,7 @@ TEST(Vector, assignment) EXPECT_EQ(45, vec1[3]); EXPECT_EQ(-34, vec1[4]); - BasicVector vec2; + Vector vec2; vec2 = vec1; @@ -333,7 +333,7 @@ TEST(Vector, assignment) TEST(Vector, operators) { { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -300.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -300.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -342,7 +342,7 @@ TEST(Vector, operators) EXPECT_FLOAT_EQ(0.0f, vec1[3]); EXPECT_FLOAT_EQ(-300.8f, vec1[4]); - BasicVector vec2 = +vec1; + Vector vec2 = +vec1; EXPECT_EQ(5, vec2.getSize()); EXPECT_FLOAT_EQ(1.0f, vec2[0]); @@ -353,7 +353,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -300.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -300.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -362,7 +362,7 @@ TEST(Vector, operators) EXPECT_FLOAT_EQ(0.0f, vec1[3]); EXPECT_FLOAT_EQ(-300.8f, vec1[4]); - BasicVector vec2 = -vec1; + Vector vec2 = -vec1; EXPECT_EQ(5, vec2.getSize()); EXPECT_FLOAT_EQ(-1.0f, vec2[0]); @@ -373,7 +373,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -382,7 +382,7 @@ TEST(Vector, operators) EXPECT_FLOAT_EQ(0.0f, vec1[3]); EXPECT_FLOAT_EQ(-3.8f, vec1[4]); - BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + Vector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; vec1 += vec2; EXPECT_EQ(5, vec1.getSize()); @@ -394,7 +394,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -403,7 +403,7 @@ TEST(Vector, operators) EXPECT_FLOAT_EQ(0.0f, vec1[3]); EXPECT_FLOAT_EQ(-3.8f, vec1[4]); - BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + Vector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; vec1 -= vec2; EXPECT_EQ(5, vec1.getSize()); @@ -415,7 +415,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -435,7 +435,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -444,7 +444,7 @@ TEST(Vector, operators) EXPECT_FLOAT_EQ(0.0f, vec1[3]); EXPECT_FLOAT_EQ(-3.8f, vec1[4]); - BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + Vector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; vec1 *= vec2; EXPECT_EQ(5, vec1.getSize()); @@ -456,7 +456,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -476,7 +476,7 @@ TEST(Vector, operators) } { - BasicVector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; + Vector vec1{1.0f, 2.0f, -5.0f, 0.0f, -3.8f}; EXPECT_EQ(5, vec1.getSize()); EXPECT_FLOAT_EQ(1.0f, vec1[0]); @@ -485,7 +485,7 @@ TEST(Vector, operators) EXPECT_FLOAT_EQ(0.0f, vec1[3]); EXPECT_FLOAT_EQ(-3.8f, vec1[4]); - BasicVector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + Vector vec2{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; vec1 /= vec2; EXPECT_EQ(5, vec1.getSize()); @@ -502,77 +502,77 @@ TEST(Vector, operators) TEST(Vector, memberFunctions) { { - const BasicVector vec; + const Vector vec; EXPECT_FLOAT_EQ(0, vec.getLength()); } { - const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; EXPECT_FLOAT_EQ(7.4162f, vec.getLength()); } { - const BasicVector vec; + const Vector vec; EXPECT_FLOAT_EQ(0, vec.getLengthSquared()); } { - const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; EXPECT_FLOAT_EQ(55, vec.getLengthSquared()); } { - const BasicVector vec; + const Vector vec; EXPECT_FLOAT_EQ(vec.getLengthSquared(), dot(vec, vec)); } { - const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; EXPECT_FLOAT_EQ(vec.getLengthSquared(), dot(vec, vec)); } { - const BasicVector vec1; - const BasicVector vec2; + const Vector vec1; + const Vector vec2; EXPECT_FLOAT_EQ(0, dot(vec1, vec2)); } { - const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + const Vector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; EXPECT_FLOAT_EQ(35, dot(vec1, vec2)); } { - const BasicVector vec; + const Vector vec; EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); } { - const BasicVector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; EXPECT_FLOAT_EQ(0.0f, distanceSquared(vec, vec)); } { - const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + const Vector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; EXPECT_FLOAT_EQ(40.0f, distanceSquared(vec1, vec2)); } { - const BasicVector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; - const BasicVector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; + const Vector vec1{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + const Vector vec2{5.0f, 4.0f, 3.0f, 2.0f, 1.0f}; EXPECT_FLOAT_EQ(6.3245554f, distance(vec1, vec2)); } From 34e225ae0df67857086fdb3372568632a6b5536c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Wed, 14 Jun 2017 16:07:22 +0200 Subject: [PATCH 10/11] Vector changes to prevent CRTP function call recusion. --- include/cece/math/Vector.hpp | 52 +++++++++++++++ include/cece/math/VectorBase.hpp | 110 +++++++++++-------------------- 2 files changed, 90 insertions(+), 72 deletions(-) diff --git a/include/cece/math/Vector.hpp b/include/cece/math/Vector.hpp index cd01f0e..3a8bba9 100644 --- a/include/cece/math/Vector.hpp +++ b/include/cece/math/Vector.hpp @@ -241,6 +241,18 @@ class Vector : public VectorBase */ constexpr const T& operator[](int pos) const noexcept; + +// Public Accessors +public: + + + /** + * @brief Returns vector size. + * + * @return The size. + */ + constexpr int getSize() const noexcept; + }; /* ************************************************************************ */ @@ -423,6 +435,14 @@ struct Vector : public VectorBase public: + /** + * @brief Returns vector size. + * + * @return The size. + */ + constexpr int getSize() const noexcept; + + /** * @brief Returns X coordinate. * @@ -715,6 +735,14 @@ struct Vector : public VectorBase public: + /** + * @brief Returns vector size. + * + * @return The size. + */ + constexpr int getSize() const noexcept; + + /** * @brief Returns X coordinate. * @@ -1218,6 +1246,14 @@ inline constexpr const T& Vector::operator[](int pos) const noexcept /* ************************************************************************ */ +template +inline constexpr int Vector::getSize() const noexcept +{ + return N; +} + +/* ************************************************************************ */ + template inline constexpr Vector::Vector() : x{} @@ -1356,6 +1392,14 @@ inline constexpr const T& Vector::operator[](int pos) const noexcept /* ************************************************************************ */ +template +inline constexpr int Vector::getSize() const noexcept +{ + return 2; +} + +/* ************************************************************************ */ + template inline constexpr const T& Vector::getX() const noexcept { @@ -1577,6 +1621,14 @@ inline constexpr const T& Vector::getX() const noexcept /* ************************************************************************ */ +template +inline constexpr int Vector::getSize() const noexcept +{ + return 3; +} + +/* ************************************************************************ */ + template inline void Vector::setX(T x) { diff --git a/include/cece/math/VectorBase.hpp b/include/cece/math/VectorBase.hpp index 18ed4d5..e55c2d4 100644 --- a/include/cece/math/VectorBase.hpp +++ b/include/cece/math/VectorBase.hpp @@ -164,38 +164,6 @@ class VectorBase VectorType& operator/=(const VectorType& rhs); - /** - * @brief Access operator. - * - * @param pos The position. - * - * @return Reference to the element. - */ - T& operator[](int pos); - - - /** - * @brief Access operator. - * - * @param pos The position. - * - * @return Reference to the element. - */ - constexpr const T& operator[](int pos) const; - - -// Public Accessors -public: - - - /** - * @brief Returns vector size. - * - * @return The size. - */ - constexpr int getSize() const noexcept; - - // Public Operations public: @@ -647,8 +615,11 @@ inline VectorType VectorBase::operator-() const noexcept { VectorType res; + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - res[i] = -(*this)[i]; + res[i] = -self[i]; return res; } @@ -659,10 +630,13 @@ template typename VectorType, typename T, int N> template inline VectorType& VectorBase::operator+=(const VectorType& rhs) { + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - (*this)[i] += rhs[i]; + self[i] += rhs[i]; - return *static_cast*>(this); + return self; } /* ************************************************************************ */ @@ -671,10 +645,13 @@ template typename VectorType, typename T, int N> template inline VectorType& VectorBase::operator-=(const VectorType& rhs) { + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - (*this)[i] -= rhs[i]; + self[i] -= rhs[i]; - return *static_cast*>(this); + return self; } /* ************************************************************************ */ @@ -683,10 +660,13 @@ template typename VectorType, typename T, int N> template inline VectorType& VectorBase::operator*=(T1 rhs) { + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - (*this)[i] *= rhs; + self[i] *= rhs; - return *static_cast*>(this); + return self; } /* ************************************************************************ */ @@ -695,10 +675,13 @@ template typename VectorType, typename T, int N> template inline VectorType& VectorBase::operator*=(const VectorType& rhs) { + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - (*this)[i] *= rhs[i]; + self[i] *= rhs[i]; - return *static_cast*>(this); + return self; } /* ************************************************************************ */ @@ -707,10 +690,13 @@ template typename VectorType, typename T, int N> template inline VectorType& VectorBase::operator/=(T1 rhs) { + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - (*this)[i] /= rhs; + self[i] /= rhs; - return *static_cast*>(this); + return self; } /* ************************************************************************ */ @@ -719,36 +705,13 @@ template typename VectorType, typename T, int N> template inline VectorType& VectorBase::operator/=(const VectorType& rhs) { - for (int i = 0; i < N; ++i) - (*this)[i] /= rhs[i]; - - return *static_cast*>(this); -} - -/* ************************************************************************ */ - -template typename VectorType, typename T, int N> -inline T& VectorBase::operator[](int pos) -{ - // TODO: recursion possibility - return (*static_cast*>(this))[pos]; -} + // Typed alias + auto& self = *static_cast*>(this); -/* ************************************************************************ */ - -template typename VectorType, typename T, int N> -inline constexpr const T& VectorBase::operator[](int pos) const -{ - // TODO: recursion possibility - return (*static_cast*>(this))[pos]; -} - -/* ************************************************************************ */ + for (int i = 0; i < N; ++i) + self[i] /= rhs[i]; -template typename VectorType, typename T, int N> -inline constexpr int VectorBase::getSize() const noexcept -{ - return N; + return self; } /* ************************************************************************ */ @@ -767,8 +730,11 @@ inline decltype(std::declval() * std::declval()) VectorBase() * std::declval()) res{}; + // Typed alias + auto& self = *static_cast*>(this); + for (int i = 0; i < N; ++i) - res += (*this)[i] * (*this)[i]; + res += self[i] * self[i]; return res; } From 591c7c809ecc4039257ca372573f5fea81702646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fatka?= Date: Mon, 1 Jul 2019 19:28:43 +0200 Subject: [PATCH 11/11] Added Matrix classes. --- .clang-format | 86 +++++++ .clang_complete | 5 + include/cece/math/Matrix.hpp | 316 +++++++++++++++++++++++++ include/cece/math/MatrixBase.hpp | 390 +++++++++++++++++++++++++++++++ 4 files changed, 797 insertions(+) create mode 100644 .clang-format create mode 100644 .clang_complete create mode 100644 include/cece/math/Matrix.hpp create mode 100644 include/cece/math/MatrixBase.hpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d9cf81d --- /dev/null +++ b/.clang-format @@ -0,0 +1,86 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/.clang_complete b/.clang_complete new file mode 100644 index 0000000..25ea966 --- /dev/null +++ b/.clang_complete @@ -0,0 +1,5 @@ +-I. +-Iinclude +-Ibuild-debug/src +-Ivendor/Box2D/Box2D/include +-Ivendor/googletest/include \ No newline at end of file diff --git a/include/cece/math/Matrix.hpp b/include/cece/math/Matrix.hpp new file mode 100644 index 0000000..b11861f --- /dev/null +++ b/include/cece/math/Matrix.hpp @@ -0,0 +1,316 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +#pragma once + +/* ************************************************************************ */ + +// CeCe +#include "cece/math/Zero.hpp" +#include "cece/math/MatrixBase.hpp" +#include "cece/math/Vector.hpp" +#include "cece/unit/Units.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +/** + * @brief 2D matrix implementation. + * + * @tparam T Type of stored value. + * @tparam R Number of rows. + * @tparam C Number of columns. + */ +template +struct Matrix : public MatrixBase +{ + +// Public Types +public: + + + /// Row type. + using RowType = Vector; + + /// Column type. + using ColumnType = Vector; + + +// Public Data Members +public: + + + /// Matrix data. + Vector m; + + +// Public Ctors +public: + + + /** + * @brief Default constructor. + */ + Matrix(); + + + /** + * @brief Zero constructor. + * + * @param[in] zero Zero value. + */ + Matrix(Zero_t zero); + + + /** + * @brief Constructor. + * + * @param src Initial data + */ + Matrix(const T (&src)[R][C]); + + + /** + * @brief Constructor. + * + * @param src Initial data + */ + Matrix(const RowType (&src)[R]); + + + /** + * @brief Copy constructor. + * + * @param src Source matrix. + */ + Matrix(const Matrix& src); + + + /** + * @brief Move constructor. + * + * @param src Source matrix. + */ + Matrix(Matrix&& src); + + +// Public Operators +public: + + + /** + * @brief Copy assignment operator. + * + * @param src The source matrix. + * + * @return *this. + */ + Matrix& operator=(const Matrix& src); + + + /** + * @brief Move assignment operator. + * + * @param src The source matrix. + * + * @return *this. + */ + Matrix& operator=(Matrix&& src); + + + /** + * @brief Row access operator. + * + * @param[in] pos The row number. + * + * @return Row. + */ + RowType& operator[](int pos) noexcept; + + + /** + * @brief Row access operator. + * + * @param pos The row number. + * + * @return Row. + */ + const RowType& operator[](int pos) const noexcept; + + + /** + * @brief Element access operator. + * + * @param coord Coordinates. + * + * @return Element. + */ + T& operator[](Vector2 coord) noexcept; + + + /** + * @brief Element access operator. + * + * @param coord Coordinates. + * + * @return Element. + */ + const T& operator[](Vector2 coord) const noexcept; + +}; + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template +inline Matrix::Matrix() +{ + // Nothing to do +} + +/* ************************************************************************ */ + +template +inline Matrix::Matrix(Zero_t zero) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = Zero; +} + +/* ************************************************************************ */ + +template +inline Matrix::Matrix(const T (&src)[R][C]) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = src[row][col]; +} + +/* ************************************************************************ */ + +template +inline Matrix::Matrix(const RowType (&src)[R]) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = src[row][col]; +} + +/* ************************************************************************ */ + +template +inline Matrix::Matrix(const Matrix& src) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = src[row][col]; +} + +/* ************************************************************************ */ + +template +inline Matrix::Matrix(Matrix&& src) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = std::move(src[row][col]); +} + +/* ************************************************************************ */ + +template +inline Matrix& Matrix::operator=(const Matrix& src) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = src[row][col]; +} + +/* ************************************************************************ */ + +template +inline Matrix& Matrix::operator=(Matrix&& src) +{ + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + m[row][col] = std::move(src[row][col]); +} + +/* ************************************************************************ */ + +template +inline Matrix::RowType& Matrix::operator[](int pos) noexcept +{ + return m[pos]; +} + +/* ************************************************************************ */ + +template +inline const Matrix::RowType& Matrix::operator[](int pos) const noexcept +{ + return m[pos]; +} + +/* ************************************************************************ */ + +template +inline T& Matrix::operator[](Vector2 coord) noexcept +{ + return m[coord.x][coord.y]; +} + +/* ************************************************************************ */ + +template +inline const T& Matrix::operator[](Vector2 coord) const noexcept +{ + return m[coord.x][coord.y]; +} + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ + diff --git a/include/cece/math/MatrixBase.hpp b/include/cece/math/MatrixBase.hpp new file mode 100644 index 0000000..13785c3 --- /dev/null +++ b/include/cece/math/MatrixBase.hpp @@ -0,0 +1,390 @@ +/* ************************************************************************ */ +/* Georgiev Lab (c) 2015-2017 */ +/* ************************************************************************ */ +/* Department of Cybernetics */ +/* Faculty of Applied Sciences */ +/* University of West Bohemia in Pilsen */ +/* ************************************************************************ */ +/* */ +/* This file is part of CeCe. */ +/* */ +/* CeCe is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation, either version 3 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* CeCe is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with CeCe. If not, see . */ +/* */ +/* ************************************************************************ */ + +#pragma once + +/* ************************************************************************ */ + +// CeCe +#include "cece/math/Vector.hpp" + +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +/** + * @brief 2D fixed size matrix base class. + * + * @tparam MatrixType Matrix type. + * @tparam T Type of stored value. + * @tparam R Number of rows. + * @tparam C Number of cols. + */ +template< + template typename MatrixType, + typename T, + int R, + int C +> +struct MatrixBase +{ + +// Public Types +public: + + + /// VectorBase value type. + using ValueType = T; + + +// Public Operators +public: + + + /** + * @brief Addition operator. + * + * @param rhs Right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + MatrixType& operator+=(const MatrixType& rhs); + + + /** + * @brief Substraction operator. + * + * @param rhs Right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + MatrixType& operator-=(const MatrixType& rhs); + + + /** + * @brief Multiplication operator. + * + * @param rhs Right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + MatrixType& operator*=(const T1& rhs); + + + /** + * @brief Division operator. + * + * @param rhs Right operand. + * + * @tparam T1 The second type. + * + * @return *this. + */ + template + MatrixType& operator/=(const T1& rhs); + +}; + +/* ************************************************************************ */ + +/** + * @brief Addition operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first matrix. + * @tparam T2 Type of value in second matrix. + * @tparam R Number of rows. + * @tparam C Number of columns. + * + * @return Result matrix. + */ +template +MatrixBase() + std::declval()), R, C> operator+( + const MatrixBase& lhs, + const MatrixBase& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Substraction operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first matrix. + * @tparam T2 Type of value in second matrix. + * @tparam R Number of rows. + * @tparam C Number of columns. + * + * @return Result matrix. + */ +template +MatrixBase() - std::declval()), R, C> operator-( + const MatrixBase& lhs, + const MatrixBase& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first matrix. + * @tparam T2 Type of value in second matrix. + * @tparam R Number of rows. + * @tparam C Number of columns. + * + * @return Result matrix. + */ +template +MatrixBase() * std::declval()), R, C> operator*( + const MatrixBase& lhs, + const T2& rhs +); + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first matrix. + * @tparam T2 Type of value in second matrix. + * @tparam R Number of rows. + * @tparam C Number of columns. + * + * @return Result matrix. + */ +template +MatrixBase() * std::declval()), R, C> operator*( + const T2& lhs + const MatrixBase& rhs, +); + +/* ************************************************************************ */ + +/** + * @brief Multiplication operator. + * + * @param lhs Left operand. + * @param rhs Right operand. + * + * @tparam T1 Type of value in first matrix. + * @tparam T2 Type of value in second matrix. + * @tparam R Number of rows. + * @tparam C Number of columns. + * + * @return Result matrix. + */ +template +MatrixBase() / std::declval()), R, C> operator/( + const MatrixBase& lhs, + const T2& rhs +); + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +/* ************************************************************************ */ +/* ************************************************************************ */ + +namespace cece { +namespace math { + +/* ************************************************************************ */ + +template typename MatrixType, typename T, int R, int C> +template +inline MatrixType& MatrixBase::operator+=(const MatrixType& rhs) +{ + auto& self = *static_cast*>(this); + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + self[row][col] += rhs[row][col]; + + return self; +} + +/* ************************************************************************ */ + +template typename MatrixType, typename T, int R, int C> +template +inline MatrixType& MatrixBase::operator-=(const MatrixType& rhs) +{ + auto& self = *static_cast*>(this); + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + self[row][col] -= rhs[row][col]; + + return self; +} + +/* ************************************************************************ */ + +template typename MatrixType, typename T, int R, int C> +template +inline MatrixType& MatrixBase::operator*=(const T1& rhs) +{ + auto& self = *static_cast*>(this); + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + self[row][col] *= rhs; + + return self; +} + +/* ************************************************************************ */ + +template typename MatrixType, typename T, int R, int C> +template +inline MatrixType& MatrixBase::operator/=(const T1& rhs) +{ + auto& self = *static_cast*>(this); + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + self[row][col] /= rhs; + + return self; +} + +/* ************************************************************************ */ + +template +inline MatrixBase() + std::declval()), R, C> operator+( + const MatrixBase& lhs, + const MatrixBase& rhs +) +{ + MatrixBase() + std::declval()), R, C> res; + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + res[row][col] = lhs[row][col] + rhs[row][col]; + + return res; +} + +/* ************************************************************************ */ + +template +inline MatrixBase() - std::declval()), R, C> operator-( + const MatrixBase& lhs, + const MatrixBase& rhs +) +{ + MatrixBase() + std::declval()), R, C> res; + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + res[row][col] = lhs[row][col] - rhs[row][col]; + + return res; +} + +/* ************************************************************************ */ + +template +inline MatrixBase() * std::declval()), R, C> operator*( + const MatrixBase& lhs, + const T2& rhs +) +{ + MatrixBase() * std::declval()), R, C> res; + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + res[row][col] = lhs[row][col] * rhs; + + return res; +} + +/* ************************************************************************ */ + +template +inline MatrixBase() * std::declval()), R, C> operator*( + const T2& lhs + const MatrixBase& rhs, +) +{ + MatrixBase() * std::declval()), R, C> res; + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + res[row][col] = rhs * lhs[row][col]; + + return res; +} + +/* ************************************************************************ */ + +template +inline MatrixBase() / std::declval()), R, C> operator/( + const MatrixBase& lhs, + const T2& rhs +) +{ + MatrixBase() + std::declval()), R, C> res; + + for (int row = 0; row < R; ++row) + for (int col = 0; col < C; ++col) + res[row][col] = lhs[row][col] / rhs; + + return res; +} + +/* ************************************************************************ */ + +} +} + +/* ************************************************************************ */ +