SFML community forums

Help => Graphics => Topic started by: battosaijenkins on April 03, 2020, 11:16:57 pm

Title: getPixel with sf::RectangleShape
Post by: battosaijenkins on April 03, 2020, 11:16:57 pm
Hi , this may sound like a noobish question but is there a way to get a pixel color information from a rotated rectangle?

I'm asking this because so far I've been using texture images to getPixel just fine, but what if I want to rotate a simple rectangle and then check to see it's color?

My current workaround was to simply create a png file with an image of a rectangle already rotated and then checking getPixel() from there, but I thought maybe there's a better method to this? Thank you!
Title: Re: getPixel with sf::RectangleShape
Post by: Hapax on April 04, 2020, 12:34:36 am
Yes, but will take a few short reversal steps.

We must presume you have the sf::Image of which to get the pixel information.
I will also presume you mean a rotated sf::RectangleShape...

1) get the global point position (i.e. the position that you want to sample)
2) use the rectangle's inverse transform to transform that point (you are now in local space - the rectangle is 0, 0 to rectangleSize.x, rectangleSize.y) - this may be enough information and you can stop here...
3) to find the ratio of the point within that rectangle, divide the point components (x and y) by the rectangle's size components
4) multiply those component ratios (x and y) with the respective texture rectangle size components
5) add the texture rectangle position/top-left (if zero, this can obviously be skipped)

You now have the co-ordinate in the texture that was at that point on the screen.
To get its colour, use that co-ordinate on the matching sf::Image (getPixel). If the texture or image is only a cropped part of the other, you will need to add/subtract that offset.
Title: Re: getPixel with sf::RectangleShape
Post by: battosaijenkins on April 04, 2020, 01:44:10 am
Is there a difference from using
Code: [Select]
sf::Transform transform;
transform.rotate(angle);
window.draw(rect, transform);
as opposed to just
Code: [Select]
rect.setPosition(pos);
rect.setOrigin(rect.getSize().x/2, rect.getSize().y/2);
rect.setFillColor(sf::Color::Red);
rect.rotate(angle);
window.draw(rect);

 Also when I use getGlobalBounds() after the rotation it seems to ignore the rotation, it still checks it's normal non rotated bounds.
Title: Re: getPixel with sf::RectangleShape
Post by: Hapax on April 04, 2020, 06:26:30 pm
Very little difference. You'd still need to set the position or adjust the transform to include the position.

getGlobalBounds() always returns an axis-aligned bounding box (AABB). This it the box that contains the rectangle even when rotated by the bounding box is not rotated; this means it gets larger when the rectangle is rotated.

Using the approach above (or some/similar parts of), you can easily determine the 4 corners of the rotated rectangle. sf::Rect, doesn't have positional or rotational information; it cannot store the rotation of the rectangle.
Title: Re: getPixel with sf::RectangleShape
Post by: battosaijenkins on April 04, 2020, 08:57:11 pm
That's what I figured. My other 'hacky' solution was to create a png file with a red rectangle already rotated. And from that I load the texture into the image and then check getPixel() for red. When I have more time I need to redo this and use your method.
Title: Re: getPixel with sf::RectangleShape
Post by: Hapax on April 05, 2020, 04:23:57 am
Sounds like you're trying to see if a point is inside a rotated rectangle. That's simpler:

if (rectangle.getLocalBounds().contains(rectangle.getInverseTransform().transformPoint(point)))
    pointIsInsideRectangle = true;
Title: Re: getPixel with sf::RectangleShape
Post by: battosaijenkins on April 05, 2020, 07:59:15 pm
Oooo, I'm going to have to test that out!! That looks real promising.
Title: Re: getPixel with sf::RectangleShape
Post by: battosaijenkins on April 05, 2020, 10:07:12 pm
Sounds like you're trying to see if a point is inside a rotated rectangle. That's simpler:

if (rectangle.getLocalBounds().contains(rectangle.getInverseTransform().transformPoint(point)))
    pointIsInsideRectangle = true;

@Hapax, Dude thanks so much. This did it exactly. I was looking for something similar to JavaScript's ctx.isPointInPath() and this did it perfectly. My other method was image getPixel() but I had to rotate the png rectangle image ahead of time which was very cumbersome. Thanks again!
Title: Re: getPixel with sf::RectangleShape
Post by: Hapax on April 06, 2020, 05:03:52 pm
If I'd've known from the beginning that all you wanted was to know if a point was inside a rotated rectangle, I would've provided this immediately ;D

Glad you got what you needed ;)