While I was playing around with intersects on SFML::Rect I noticed that it seamed like it intersected even though it shouldn't. For instance I have the rect: [0, 0, 44, 16] and when I call intersects with [0, -35, 42, 34] it returns [0, 0, 44, 16]
I must have done something wrong unless I misunderstand intersects. Here's the original C++ code:
template <typename T>
bool Rect<T>::Intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
{
// Compute the intersection boundaries
T left = std::max(Left, rectangle.Left);
T top = std::max(Top, rectangle.Top);
T right = std::min(Left + Width, rectangle.Left + rectangle.Width);
T bottom = std::min(Top + Height, rectangle.Top + rectangle.Height);
// If the intersection is valid (positive non zero area), then there is an intersection
if ((left < right) && (top < bottom))
{
intersection = Rect<T>(left, top, right - left, bottom - top);
return true;
}
else
{
intersection = Rect<T>(0, 0, 0, 0);
return false;
}
}
And here's the original ruby code(with added comments to show what's what):
/* call-seq:
* rect.intersects( rectangle ) -> intersection rectangel or nil
*
* Check the intersection between two rectangles.
*
* This method returns the overlapped rectangle if intersecting otherwise nil.
*/
static VALUE Rect_Intersects( VALUE self, VALUE aRect )
{
VALUE selfLeft = rb_funcall( self, rb_intern( "left" ), 0 );
VALUE selfTop = rb_funcall( self, rb_intern( "top" ), 0 );
VALUE selfWidth = rb_funcall( self, rb_intern( "width" ), 0 );
VALUE selfHeight = rb_funcall( self, rb_intern( "height" ), 0 );
VALUE selfRight = rb_funcall( selfLeft, rb_intern( "+" ), 1, selfWidth );
VALUE selfBottom = rb_funcall( selfTop, rb_intern( "+" ), 1, selfHeight );
VALUE rectLeft = rb_funcall( aRect, rb_intern( "left" ), 0 );
VALUE rectTop = rb_funcall( aRect, rb_intern( "top" ), 0 );
VALUE rectWidth = rb_funcall( aRect, rb_intern( "width" ), 0 );
VALUE rectHeight = rb_funcall( aRect, rb_intern( "height" ), 0 );
VALUE rectRight = rb_funcall( rectLeft, rb_intern( "+" ), 1, rectWidth );
VALUE rectBottom = rb_funcall( rectTop, rb_intern( "+" ), 1, rectHeight );
VALUE left, top, right, bottom;
// T left = std::max(Left, rectangle.Left);
if( rb_funcall( selfLeft, rb_intern( ">" ), 1, rectLeft ) == Qtrue )
{
left = selfLeft;
}
else
{
left = rectLeft;
}
// T top = std::max(Top, rectangle.Top);
if( rb_funcall( selfTop, rb_intern( ">" ), 1, rectTop ) == Qtrue )
{
top = selfTop;
}
else
{
top = rectTop;
}
// T right = std::min(Left + Width, rectangle.Left + rectangle.Width);
if( rb_funcall( selfRight , rb_intern( ">" ), 1, rectRight ) == Qtrue )
{
right = selfRight;
}
else
{
right = rectRight;
}
// T bottom = std::min(Top + Height, rectangle.Top + rectangle.Height);
if( rb_funcall( selfBottom , rb_intern( ">" ), 1, rectBottom ) == Qtrue )
{
bottom = selfBottom;
}
else
{
bottom = rectBottom;
}
// if ((left < right) && (top < bottom))
if( rb_funcall( left, rb_intern( "<" ), 1, right) == Qtrue && rb_funcall( top, rb_intern( "<" ), 1, bottom) == Qtrue )
{
// intersection = Rect<T>(left, top, right - left, bottom - top);
VALUE newWidth = rb_funcall( right, rb_intern( "-" ), 1, left );
VALUE newHeight = rb_funcall( bottom, rb_intern( "-" ), 1, top );
return rb_funcall( globalRectClass, rb_intern( "new" ), 4, left, top, newWidth, newHeight );
}
else
{
// return false
return Qnil;
}
}
from what I understand, those two rects shouldn't intersect and thus the intersects method should return the ruby value nil. But I must have missed something somewhere in the algorithm. Does anybody see it?