diff --git a/src/Math/Geometry/CMakeLists.txt b/src/Math/Geometry/CMakeLists.txt index 35e4ba1e0..fb55add04 100644 --- a/src/Math/Geometry/CMakeLists.txt +++ b/src/Math/Geometry/CMakeLists.txt @@ -2,7 +2,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(MagnumMathGeometry_HEADERS Distance.h - Intersection.h) + Intersection.h + Rectangle.h) install(FILES ${MagnumMathGeometry_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Math/Geometry) if(BUILD_TESTS) diff --git a/src/Math/Geometry/Rectangle.h b/src/Math/Geometry/Rectangle.h new file mode 100644 index 000000000..fea8225cd --- /dev/null +++ b/src/Math/Geometry/Rectangle.h @@ -0,0 +1,110 @@ +#ifndef Magnum_Math_Geometry_Rectangle_h +#define Magnum_Math_Geometry_Rectangle_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Math::Geometry::Rectangle + */ + +#include "Math/Vector2.h" + +namespace Magnum { namespace Math { namespace Geometry { + +/** +@brief %Rectangle + +Helper class for storing axis-aligned rectangles consisting of bottom left and +top right corner positions. Bottom left position is inclusive, while top right +position is exclusive. +*/ +template class Rectangle { + public: + /** + * Create rectangle from position and size + * @param bottomLeft Bottom left rectangle corner + * @param size %Rectangle size + */ + inline static Rectangle fromSize(const Vector2& bottomLeft, const Vector2& size) { + return {bottomLeft, bottomLeft+size}; + } + + /** + * @brief Default constructor + * + * Construct zero-area rectangle positioned at origin. + */ + inline constexpr Rectangle() = default; + + /** + * @brief Constructor + * @param bottomLeft Bottom left rectangle corner + * @param topRight Top right rectangle corner + */ + inline constexpr Rectangle(const Vector2& bottomLeft, const Vector2& topRight): _bottomLeft(bottomLeft), _topRight(topRight) {} + + /** @brief Equality operator */ + inline constexpr bool operator==(const Rectangle& other) const { + return _bottomLeft == other._bottomLeft && _topRight == other._topRight; + } + + /** @brief Non-equality operator */ + inline constexpr bool operator!=(const Rectangle& other) const { + return !operator==(other); + } + + /** @brief Bottom left corner */ + inline Vector2& bottomLeft() { return _bottomLeft; } + inline constexpr Vector2 bottomLeft() const { return _bottomLeft; } /**< @overload */ + + /** @brief Top right corner */ + inline Vector2& topRight() { return _topRight; } + inline constexpr Vector2 topRight() const { return _topRight; } /**< @overload */ + + /** @brief Bottom edge */ + inline T& bottom() { return _bottomLeft.y(); } + inline constexpr T bottom() const { return _bottomLeft.y(); } /**< @overload */ + + /** @brief Top edge */ + inline T& top() { return _topRight.y(); } + inline constexpr T top() const { return _topRight.y(); } /**< @overload */ + + /** @brief Left edge */ + inline T& left() { return _bottomLeft.x(); } + inline constexpr T left() const { return _bottomLeft.x(); } /**< @overload */ + + /** @brief Right edge */ + inline T& right() { return _topRight.x(); } + inline constexpr T right() const { return _topRight.x(); } /**< @overload */ + + /** @brief %Rectangle size */ + inline constexpr Vector2 size() const { + return _topRight-_bottomLeft; + } + + /** @brief %Rectangle width */ + inline constexpr T width() const { return _topRight.x() - _bottomLeft.x(); } + + /** @brief %Rectangle height */ + inline constexpr T height() const { return _topRight.y() - _bottomLeft.y(); } + + private: + Vector2 _bottomLeft; + Vector2 _topRight; +}; + +}}} + +#endif diff --git a/src/Math/Geometry/Test/CMakeLists.txt b/src/Math/Geometry/Test/CMakeLists.txt index 7d6dcfa93..46ad2a19e 100644 --- a/src/Math/Geometry/Test/CMakeLists.txt +++ b/src/Math/Geometry/Test/CMakeLists.txt @@ -1,2 +1,3 @@ corrade_add_test(MathGeometryDistanceTest DistanceTest.cpp) corrade_add_test(MathGeometryIntersectionTest IntersectionTest.cpp) +corrade_add_test(MathGeometryRectangleTest RectangleTest.cpp LIBRARIES MagnumMathTestLib) diff --git a/src/Math/Geometry/Test/RectangleTest.cpp b/src/Math/Geometry/Test/RectangleTest.cpp new file mode 100644 index 000000000..315acfed4 --- /dev/null +++ b/src/Math/Geometry/Test/RectangleTest.cpp @@ -0,0 +1,71 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 Lesser General Public License version 3 for more details. +*/ + +#include "RectangleTest.h" + +#include "Rectangle.h" + +CORRADE_TEST_MAIN(Magnum::Math::Geometry::Test::RectangleTest) + +namespace Magnum { namespace Math { namespace Geometry { namespace Test { + +typedef Rectangle Rectanglei; +typedef Vector2 Vector2i; + +RectangleTest::RectangleTest() { + addTests(&RectangleTest::access, + &RectangleTest::compare, + &RectangleTest::construct, + &RectangleTest::size); +} + +void RectangleTest::access() { + Rectanglei rect({34, 23}, {47, 30}); + const Rectanglei crect({34, 23}, {47, 30}); + + CORRADE_COMPARE(rect.bottomLeft(), Vector2i(34, 23)); + CORRADE_COMPARE(rect.topRight(), Vector2i(47, 30)); + CORRADE_COMPARE(rect.bottom(), 23); + CORRADE_COMPARE(rect.top(), 30); + CORRADE_COMPARE(rect.left(), 34); + CORRADE_COMPARE(rect.right(), 47); + CORRADE_COMPARE(crect.bottomLeft(), Vector2i(34, 23)); + CORRADE_COMPARE(crect.topRight(), Vector2i(47, 30)); + CORRADE_COMPARE(crect.bottom(), 23); + CORRADE_COMPARE(crect.top(), 30); + CORRADE_COMPARE(crect.left(), 34); + CORRADE_COMPARE(crect.right(), 47); +} + +void RectangleTest::compare() { + CORRADE_VERIFY(Rectanglei({34, 23}, {47, 30}) == Rectanglei({34, 23}, {47, 30})); + CORRADE_VERIFY(Rectanglei({34, 23}, {47, 30}) != Rectanglei({34, 23}, {48, 30})); + CORRADE_VERIFY(Rectanglei({34, 23}, {47, 30}) != Rectanglei({35, 23}, {47, 30})); +} + +void RectangleTest::construct() { + CORRADE_VERIFY(Rectanglei() == Rectanglei({0, 0}, {0, 0})); + CORRADE_VERIFY(Rectanglei::fromSize({3, 5}, {23, 78}) == Rectanglei({3, 5}, {26, 83})); +} + +void RectangleTest::size() { + Rectanglei rect({34, 23}, {47, 30}); + + CORRADE_COMPARE(rect.size(), Vector2i(13, 7)); + CORRADE_COMPARE(rect.width(), 13); + CORRADE_COMPARE(rect.height(), 7); +} + +}}}} diff --git a/src/Math/Geometry/Test/RectangleTest.h b/src/Math/Geometry/Test/RectangleTest.h new file mode 100644 index 000000000..2fbfd4e3b --- /dev/null +++ b/src/Math/Geometry/Test/RectangleTest.h @@ -0,0 +1,34 @@ +#ifndef Magnum_Math_Geometry_Test_RectangleTest_h +#define Magnum_Math_Geometry_Test_RectangleTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum 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 Lesser General Public License version 3 for more details. +*/ + +#include + +namespace Magnum { namespace Math { namespace Geometry { namespace Test { + +class RectangleTest: public Corrade::TestSuite::Tester { + public: + RectangleTest(); + + void access(); + void compare(); + void construct(); + void size(); +}; + +}}}} + +#endif