Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] Rect.Contains() don't behave Correctly in some cases  (Read 4745 times)

0 Members and 1 Guest are viewing this topic.

eyad

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
hello there, i'am new to this forums and ofcourse SFML and i like it so far.
i'am following an old tutorial (2010) about how to use SFML (v1.6 i think) -am now using v2.3.2 with vs2015- to make a simple game.
in the tutorial there is a point where i need to determine the mouse coordinates in an image menu to act accordingly. when i used the "Contains" function it always select the first option even tho i click on the other one, it only chooses the second options when i click Significantly lower than its position on the screen.
then i tried the normal (x >= left) && (x < width) && (y >= top) && (y < height) test and it worked correctly.

i will post the Project code here so you can check it yourself.
i managed to fix the "Contains" function by checking (if any of its parts is less than 0) so i process your code, else it makes a normal detection...
template <typename T>
bool Rect<T>::contains(T x, T y) const
{
    // Rectangles with negative dimensions are allowed, so we must handle them correctly

        if (left < 0 || top < 0 || width < 0 || height < 0 )
        {
                // Compute the real min and max of the rectangle on both axes
                T minX = std::min( left, static_cast<T>( left + width ) );
                T maxX = std::max( left, static_cast<T>( left + width ) );
                T minY = std::min( top, static_cast<T>( top + height ) );
                T maxY = std::max( top, static_cast<T>( top + height ) );
                return ( x >= minX ) && ( x < maxX ) && ( y >= minY ) && ( y < maxY );
        }
        else
    return (x >= left) && (x < width) && (y >= top) && (y < height);
}
 

the function to check is found in MainMenu.cpp -> HandleClick(int x, int y) ------ line57
« Last Edit: June 15, 2016, 12:49:21 am by eyad »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #1 on: June 10, 2016, 05:39:58 pm »
Your formula is wrong. (x < width) and (y < height) will act as if x and y were both zero, you must add them to the expression. If your wrong formula works, there's most likely an error in your program too.
Laurent Gomila - SFML developer

eyad

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #2 on: June 11, 2016, 02:05:02 am »
okay, you are right , it should be "Logically" as you said top+height and width+left. however , that don't explain why checking if a coordinate(point) inside a rectangle return the the wrong answer.. -the contains function-

and ofcourse that means the editing in the code doesn't make a difference

summary: the wrong(old) way of testing return the right answer -looks like it-  and the more logical one doesn't act as it should be. my question is,
why is that happening? and if you intended that it should behave like that , when its appropriate to use it?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #3 on: June 11, 2016, 09:07:40 am »
I'm pretty sure that Rect::contains works as intended. If it doesn't for you, then show a complete and minimal piece of code that reproduces the problem.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: Rect.Contains() don't behave Correctly in some cases
« Reply #4 on: June 11, 2016, 11:54:11 am »
Since you're dealing with mouse positions, did you make sure that the position is relative to your window (sf::Mouse::getPosition(window))?

If anything print out the mouse position and the four points of the rect and the manually calculate in your head if that is inside or outside.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #5 on: June 11, 2016, 04:31:25 pm »
        playBtn.rect.top = 145;
        playBtn.rect.height = 380;
         exitBtn.rect.top = 383;
         exitBtn.rect.height = 560;
These overlap.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

eyad

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: AW: Rect.Contains() don't behave Correctly in some cases
« Reply #6 on: June 12, 2016, 09:44:49 pm »
sorry for the late reply.
Since you're dealing with mouse positions, did you make sure that the position is relative to your window (sf::Mouse::getPosition(window))?
i use sf::event.mousbutton.x and sf::event.mousbutton.y (is that wrong? , and whats the right way to do it?)

        playBtn.rect.top = 145;
        playBtn.rect.height = 380;
         exitBtn.rect.top = 383;
         exitBtn.rect.height = 560;
These overlap.
yes it overlaps but after fixing it, the other problem which is( clicking lower than the "Exit game" option) still triggers it.....


eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: AW: Rect.Contains() don't behave Correctly in some cases
« Reply #7 on: June 12, 2016, 09:53:32 pm »
i use sf::event.mousbutton.x and sf::event.mousbutton.y (is that wrong? , and whats the right way to do it?)
If you use events then the position is already relative.

Don't forget to follow up on the other suggestions!

...show a complete and minimal piece of code that reproduces the problem.

If anything print out the mouse position and the four points of the rect and the manually calculate in your head if that is inside or outside.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #8 on: June 13, 2016, 06:20:14 am »
Make sure that you're not confusing "height" and "bottom". 560 pixels high seems like a huge button.
Laurent Gomila - SFML developer

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: AW: Rect.Contains() don't behave Correctly in some cases
« Reply #9 on: June 14, 2016, 03:54:27 am »
        playBtn.rect.top = 145;
        playBtn.rect.height = 380;
         exitBtn.rect.top = 383;
         exitBtn.rect.height = 560;
These overlap.
yes it overlaps but after fixing it, the other problem which is( clicking lower than the "Exit game" option) still triggers it.....
How did you fix it?

Make sure that you're not confusing "height" and "bottom". 560 pixels high seems like a huge button.
Pretty much what I was trying to hint at  ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

eyad

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #10 on: June 14, 2016, 02:42:28 pm »
oh well, iam Deeply Sorry about opening this thread as i have figured out whats the problem is, which i feel that i wasted your time with this simple problem.
the tutorial was written in about 2010 and at this time the author was using sfml 1.6 (i think) which defines a rect as (top,bot,left,right) so
 playbtn.rect.top =145;  playBtn.rect.height = 380;
was written as
playbtn.rect.top =145;  playBtn.rect.bottom = 380;
means that the top line is at 145 and the bottom is at 380. after you clarified that it is now "Height" not "bottom" (i previously just changed it to work without noticing the difference as i was just trying to follow up the tutorial). i figured out that i just need to recalculate the height -which is not instantly obvious btw- so it worked
playBtn.rect.top = 145;
playBtn.rect.height = 233; //380= 145 + 233
exitBtn.rect.top = 383;
exitBtn.rect.height = 185; //576 = 383 + 186

so what to do, to mark this thread as solved/closed etc
and ofcourse thanks for everyone who tried to help, and iam sorry for not noticing it before and ofcourse for wasting your time.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Rect.Contains() don't behave Correctly in some cases
« Reply #11 on: June 14, 2016, 09:42:23 pm »
I, for one, don't mind that you asked about this topic. It would have been much worse if you'd've not noticed it and just continued to assumed that height meant bottom and would have probably been harder to fix and to explain to everyone.

what to do, to mark this thread as solved/closed
You can just edit the original/first post and change its subject so that it has "[SOLVED] " before the actual subject:
[SOLVED] Rect.Contains() don't behave Correctly in some cases
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*