sf::Rect::contains and sf::Rect::intersects now handle rectangles with negative dimensions correctly (#219)

This commit is contained in:
Laurent Gomila 2013-05-11 22:56:17 +02:00
parent c4999f0890
commit 11837e9fc8

View File

@ -75,7 +75,15 @@ height(static_cast<T>(rectangle.height))
template <typename T> template <typename T>
bool Rect<T>::contains(T x, T y) const bool Rect<T>::contains(T x, T y) const
{ {
return (x >= left) && (x < left + width) && (y >= top) && (y < top + height); // Rectangles with negative dimensions are allowed, so we must handle them correctly
// Compute the real min and max of the rectangle on both axes
T minX = std::min(left, left + width);
T maxX = std::max(left, left + width);
T minY = std::min(top, top + height);
T maxY = std::max(top, top + height);
return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY);
} }
@ -100,11 +108,25 @@ bool Rect<T>::intersects(const Rect<T>& rectangle) const
template <typename T> template <typename T>
bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
{ {
// Rectangles with negative dimensions are allowed, so we must handle them correctly
// Compute the min and max of the first rectangle on both axes
T r1MinX = std::min(left, left + width);
T r1MaxX = std::max(left, left + width);
T r1MinY = std::min(top, top + height);
T r1MaxY = std::max(top, top + height);
// Compute the min and max of the second rectangle on both axes
T r2MinX = std::min(rectangle.left, rectangle.left + rectangle.width);
T r2MaxX = std::max(rectangle.left, rectangle.left + rectangle.width);
T r2MinY = std::min(rectangle.top, rectangle.top + rectangle.height);
T r2MaxY = std::max(rectangle.top, rectangle.top + rectangle.height);
// Compute the intersection boundaries // Compute the intersection boundaries
T interLeft = std::max(left, rectangle.left); T interLeft = std::max(r1MinX, r2MinX);
T interTop = std::max(top, rectangle.top); T interTop = std::max(r1MinY, r2MinY);
T interRight = std::min(left + width, rectangle.left + rectangle.width); T interRight = std::min(r1MaxX, r2MaxX);
T interBottom = std::min(top + height, rectangle.top + rectangle.height); T interBottom = std::min(r1MaxY, r2MaxY);
// If the intersection is valid (positive non zero area), then there is an intersection // If the intersection is valid (positive non zero area), then there is an intersection
if ((interLeft < interRight) && (interTop < interBottom)) if ((interLeft < interRight) && (interTop < interBottom))