-
I have a square shaped sprite that is sometimes rotated.
I want to get the x,y cords of all the edges of that certain sprite even when its rotated.
What is the best way to do so?
Illustration to show what I mean (32x32 square):
http://i.imgur.com/YweUiAT.png
-
You can multiply your original point (x,y) with a rotation matrix: https://en.wikipedia.org/wiki/Rotation_matrix
Let (x,y) be your original point (x',y') the rotated point and w the angle of rotation (clockwise). Then you get your result like this:
x' = x*cos(w) - y*sin(w)
y' = x*sin(w) + y*cos(w)
Edit: You'll get a rotation around the world-origin (0,0). Since your rotation is around the sprites center point, you'll also have to do a translation before and after the above calculation.
-
Generic solution that works with all kind of entities and all kind of transformations:
sf::FloatRect rect = entity.getLocalBounds();
sf::Vector2f topLeft(rect.left, rect.top);
sf::Vector2f transformedTopLeft = entity.getTransform() * topLeft;
... same for the 3 other corners...
-
I think I need to re-explain my problem.
I am using the tmxloader to create MapObject to be able to check collisions around my map.
This is an illustration of a map and a player inside it:
http://i.imgur.com/cDzCcsJ.png
My current collision checking is based on my globalBounds, meaning, it will generate a sf::FloatRect with the global bounds of my sprite and it will pass the tmx::MapObject 4 points based on the float rect.
So I end up with something like this (red=collision rect, blue=actual player and purple is a object to check if they are colliding):
http://i.imgur.com/i6f0ZH4.png
Basically what happens there is that the red rectangle identifies a collison when in reality they didnt collide yet.
The solution for this problem is of course to put the points exactly on the edges of the rectangle.
Afaik, there is no option to rotate a tmx::MapObject.
I'd appreciate any help, I have tried what you guys suggested but it dosent seem to work properly (maybe I implemented wrong).
This is my original function:
tmx::MapObject Player::GetRect()
{
sf::FloatRect fr = this->getGlobalBounds();
sf::RectangleShape rs;
rs.setPosition(this->getPosition());
rs.setSize(sf::Vector2f(32,32));
rs.setOrigin(16, 16);
rs.setRotation(this->getRotation());
tmx::MapObject mo;
mo.SetPosition(sf::Vector2f(fr.left, fr.top));
mo.AddPoint(rs.getPoint(1));
mo.AddPoint(rs.getPoint(2));
mo.AddPoint(rs.getPoint(3));
mo.AddPoint(rs.getPoint(4));
mo.CreateDebugShape(sf::Color::Magenta);
return mo;
}
I hope I was clear enough now.
-
Your problem was already clear enough. If what was suggested doesn't work, then tell us what's wrong exactly and show your code, instead of re-explaining your initial problem ;)
-
Your problem was already clear enough. If what was suggested doesn't work, then tell us what's wrong exactly and show your code, instead of re-explaining your initial problem ;)
This is the function I implemented using the technic you gave me:
tmx::MapObject Player::GetFutureRect()
{
sf::FloatRect rect = this->getLocalBounds();
sf::Vector2f topLeft(rect.left, rect.top);
sf::Vector2f transformedTopLeft = this->getTransform() * topLeft;
sf::Vector2f topRight(rect.left+32, rect.top);
sf::Vector2f transformedTopRight = this->getTransform() * topRight;
sf::Vector2f bottomLeft(rect.left, rect.top+32);
sf::Vector2f transformedBottomLeft = this->getTransform() * bottomLeft;
sf::Vector2f bottomRight(rect.left+32, rect.top+32);
sf::Vector2f transformedBottomRight = this->getTransform() * bottomRight;
tmx::MapObject mo;
mo.SetPosition(transformedTopLeft);
mo.AddPoint(transformedTopLeft);
mo.AddPoint(transformedTopRight);
mo.AddPoint(transformedBottomRight);
mo.AddPoint(transformedBottomLeft);
mo.CreateDebugShape(sf::Color::Magenta);
return mo;
}
And for you question, "What dosent work?", well, everything ::)
They just not collide for some reaso (probably something with my math).
-
I know nothing about tmx, anyway the problem might be in your collision checking itself. If I get you right you try to check collision of rotated rectangles the same way you do for unrotated ones. Can you show your method?
-
And for you question, "What dosent work?", well, everything ::)
Solving a problem involves trying to understand exactly what's going on, not just rolling eyes on the forum :P
Since you have the debug shape displayed, it should be easy to see how it is wrong: is the shape scaled? offseted? rotated? I can't believe it's totally random compared to what it's supposed to be.
-
And for you question, "What dosent work?", well, everything ::)
Solving a problem involves trying to understand exactly what's going on, not just rolling eyes on the forum :P
Since you have the debug shape displayed, it should be easy to see how it is wrong: is the shape scaled? offseted? rotated? I can't believe it's totally random compared to what it's supposed to be.
I didn't understand what was going wrong, that's why I'm here asking this question :-\
As for the debug shape, it dosent even show, so thats why I said it's something with the math probably.
I know nothing about tmx, anyway the problem might be in your collision checking itself. If I get you right you try to check collision of rotated rectangles the same way you do for unrotated ones. Can you show your method?
The method is fine, I have tested it lots of different times.
I only have to find a way to find the points. Thank you though :).
-
As for the debug shape, it dosent even show, so thats why I said it's something with the math probably.
So print the coordinates. Or better: step with your debugger and check the coordinates of each transformed point.
-
It sounds to me like you are trying to detect collision with a rotated rectangle, not just know where the corners are (although any transformed point can also be calculated using the method already provided by Laurent).
If this is the case, since this case has been discussed on this forum previously, this thread (http://en.sfml-dev.org/forums/index.php?topic=17631) may lead you to the direction you need to find the answer ;)