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

Author Topic: I can't get the math right. [SOLVED]  (Read 3099 times)

0 Members and 1 Guest are viewing this topic.

Riser

  • Newbie
  • *
  • Posts: 33
    • View Profile
I can't get the math right. [SOLVED]
« on: October 02, 2020, 07:30:14 pm »
So I have a player character sprite, that rotates to follow the mouse cursor around, and a circle centered around the cursor:



I'm trying to calculate the coordinates of one of the points of the circle, that changes depending on the rotation of the player character, where the argument of the point will be equal to the rotation of the player character +90 degrees, so let's say I want to position a 10x10 blue rectangle shape at this point, it will looks like this:

If the player's rotation is equal to 180 => the point will have an argument of -90:

If the player's rotation is equal to 90 => the point will have an argument of 180:

If the player's rotation is equal to 135 => the point will have an argument of -135:


And, I'm half way there, here is my attempt at calculating the position of the rectangle (in the main loop), knowing that:

test is the blue square.
scope is the circle
25 is the radius if the circle (scope)
scope's rotation is literally equal to that of the player character:
scope.setRotation(entity_sprite.getRotation());

So the player character's rotation and the circle's rotation are interchangeable.

 test.setPosition(sf::Vector2f(player.scope.getPosition().x + cos(player.scope.getRotation() + 90) * 25, player.scope.getPosition().y + sin(player.scope.getRotation() + 90) * 25));

It...sort of works:


It doesn't appear in the gif because of low frame-rate, but the rectangle is spinning around the circle in the right directions, but it's doing it too quickly, I've had a similar problem when coding the character to follow the cursor, but I solved it by multiplying the angle outputted by the atan2 function by by 180/3.14, it doesn't seem to be as straight forward here...

So, how do I calculate the coordinates of this point correctly?
« Last Edit: October 03, 2020, 10:42:54 pm by Riser »

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: I can't get the math right.
« Reply #1 on: October 02, 2020, 07:50:51 pm »
std::cos and std::sin use radians

Riser

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: I can't get the math right.
« Reply #2 on: October 02, 2020, 08:33:03 pm »
I already figured that out when getting the character to follow the cursor, I simply used atan2 to calculate the angle then multiplied it by 180/3.14 to get the angle in degrees, but here when using sine and cosine it doesn't seem to be that straight forward.
« Last Edit: October 02, 2020, 08:36:00 pm by Riser »

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: I can't get the math right.
« Reply #3 on: October 03, 2020, 12:42:54 pm »
(Assuming I understand correctly:) If you want the point to be fixed at 90 degrees to the direction of the player you can actually take the rotation out of this and just use vectors.

First find the direction from the scope to the player

auto direction = scope.getPosition() - player.getPosition();

Then normalise the direction (so that it has a length of 1)

direction = normalise(direction);

To rotate a vector 90 degrees you can swap its components then negate one of them. Which one you negate affects whether the vector is rotated +/- 90 degrees.

direction = { -direction.y, direction.x };

or

direction = { direction.y, -direction.x };

Multiply the direction by the radius of the scope to bring it out to the edge:

direction *= radius;

Then finally add it back to the position of the circle.

auto finalPoint = scope.getPosition() + direction;


In general though (and cases where you want angles other than 90 degrees) this sounds like a good case for a Scene Graph, where the square is parented to the circle, which is then parented to the player. There are SFML specific tutorials on how to create a scene graph in the tutorial section and, once again (I swear I'm not sponsored ;)), in the SFML Game Development book:

https://www.sfml-dev.org/tutorials/2.5/graphics-transform.php#object-hierarchies-scene-graph
https://github.com/SFML/SFML-Game-Development-Book/blob/master/03_World/Include/Book/SceneNode.hpp

Riser

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: I can't get the math right.
« Reply #4 on: October 03, 2020, 10:42:40 pm »
Nope, nevermind, apparently all it took was to was to divide the rotation by 180 and multiply it by 3.14 (Which is something I DID actually try, but I think I messed up and typed it outside the parenthesis of the cos/sin functions, as opposed to inside, where it's supposed to be)...

So now the line looks like this:

test.setPosition(sf::Vector2f(player.scope.getPosition().x + cos(player.scope.getRotation() / 180 * 3.14) * 25, player.scope.getPosition().y + sin(player.scope.getRotation() / 180 * 3.14) * 25));

And just like that:

I'm facepalming so hard right now...

Now, there is something odd, in this updated line, the part where I add 90 degrees to the scope's rotation has been removed, but as you can see the rectangle is still fixed at 90 degrees to the direction of the player, and while that is what I want, I'm not sure why it's that way...
No big deal though, if I want a different angle I can just add it to the rotation just like I did in the original post.

The techniques you posted can still come in handy down the line, since I'm planing on learning more about both graphics as well data structures and algorithms, just so you know your effort wasn't really in vain, thank you!

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: I can't get the math right. [SOLVED]
« Reply #5 on: October 04, 2020, 09:53:12 am »
In trigonometry, 0 radians (or 0°) is on the right of the circle.


Riser

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: I can't get the math right. [SOLVED]
« Reply #6 on: October 04, 2020, 11:25:29 am »
Again, I know that, but this still doesn't answer my question as to why is the rectangle is positioned where it is without me specifying an angle, remember, without me specifying an angle, the rectangle would be rotating around the circle with the same angle the sprite is rotating at.

EDIT: I found this exactly after typing this reply, but it turns I forgot I set the entity sprite to be rotated at a 90 degrees angle so that the gun would be aligned with the mouse cursor, that must be it.

void Player::mouse_controls(sf::Vector2f cursor) {
        sf::Vector2f direction;
        direction.x = entity_sprite.getPosition().x - cursor.x;
        direction.y = entity_sprite.getPosition().y - cursor.y;
        float angle = atan2(direction.y, direction.x) * 180 / 3.14;
        entity_sprite.setRotation(angle - 90);// <-------
        std::cout << angle << std::endl;
}
 
« Last Edit: October 04, 2020, 08:43:44 pm by Riser »