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

Author Topic: [SOLVED] atan2 ineffective when Rotating x to face y?  (Read 8558 times)

0 Members and 2 Guests are viewing this topic.

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« on: October 21, 2011, 09:09:14 pm »
Yes, it's this question again. The reason I'm asking, despite the fact that there are 100 answers to be found on Google, is that they all revolve around atan2(). While atan2() is an awesome function, it's also apparently ineffective under certain circumstances.

All of this will be explained. This is my current code:

Code: [Select]
float angleBetweenVectors(sf::Vector2f a, sf::Vector2f b)
{
return 57.2957795f * atan2(b.y - a.y, b.x - a.x);
}


I take this, use it to rotate a missile sprite toward the mouse cursor, and then give it forward velocity. The problem is that the rotation is bit off for any angle not divisible by 45. In order to further prove my point, I've constructed a console program which should return a rotation of 22.5 degrees, because the ratio of x:y is 1:2. This gives me incorrect output. The code:


Code: [Select]
#include <iostream>
#include <math.h>
using namespace std;

int main(void)
{
  // the parameters to atan2() are precalculated distances,
  // so it should work
  cout << "The rotation is: " << (57.2957795f * atan2(5,10)) << \
   ", but it shouldn't be.\n";

  return 0;
}


And the output is: "The rotation is: 26.5651, but it shouldn't be." So either I'm misinterpreting how to use of atan2(), or it's just wrong. The assumption I'm making is that I'm misinterpreting/misusing it. Anybody know how to do this properly?

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #1 on: October 21, 2011, 09:25:10 pm »
You... don't understand angles very well, do you? If the ratio of x:y is 1:2, that's an angle of 26.6 degrees, like your program says.
I use the latest build of SFML2

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #2 on: October 21, 2011, 09:30:38 pm »
Quote from: "lazerblade"
I've constructed a console program which should return a rotation of 22.5 degrees, because the ratio of x:y is 1:2.
Here is your mistake, the angle is not 22.5°. Otherwise, tan(22.5°) would have to be 5/10 = 0.5.

I have implemented a function to get the signed angle between two vectors in my library, namely thor::Angle(), you could use it directly if you wanted. Even without linking the library ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #3 on: October 21, 2011, 09:31:17 pm »
Quote from: "OniLink10"
You... don't understand angles very well, do you? Is the ratio of x:y is 1:2, that's an angle of 26.6 degrees, like your program says.


I was afraid I was doing something stupid like that. I'm having trouble coming up with a good way to show the problem from a simple console application. Examples aside, shouldn't my angleBetweenVectors() function return a proper value? If not, I need to figure out why. If so, that means I should look elsewhere in my program for the bug. That's why being sure about whether or not this function works is important.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #4 on: October 21, 2011, 09:39:45 pm »
You are calculating the polar angle of the difference vector b - a. Expressed with my functions this would be PolarAngle(b - a).

But I think you rather want to know how much a has to be rotated to cover b, that would be PolarAngle(b) - PolarAngle(a) with handling of correct wraparound or just Angle(a, b).

Have you seen my upper post?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #5 on: October 21, 2011, 09:46:20 pm »
Quote from: "Nexus"
You are calculating the polar angle of the difference vector b - a. Expressed with my functions this would be PolarAngle(b - a).

But I think you rather want to know how much a has to be rotated to cover b, that would be PolarAngle(b) - PolarAngle(a) with handling of correct wraparound or just Angle(a, b).

Have you seen my upper post?


Yes, but I'm having a little trouble finding the implementation. I only see the declaration in the .hpp file.

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #6 on: October 21, 2011, 10:31:39 pm »
Found implementation and tried it out. Now it's even more erradic. I'm probably using it wrong. New code:

Code: [Select]
//  (180 / PI = 57.2957795)
float angleBetweenVectors(sf::Vector2f lhs, sf::Vector2f rhs)
{
    return 57.2957795f * atan2((lhs.x * rhs.y) - (lhs.y * rhs.x), (lhs.x * rhs.x) + (lhs.y * rhs.y));
}

sbroadfoot90

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #7 on: October 21, 2011, 11:31:29 pm »
Dude, it's not the programming you have wrong. It's the maths. You're trying to do the wrong thing... You need something like this

Code: [Select]

float angleBetweenVectors(sf::Vector2f lhs, sf::Vector2f rhs)
{
    return 57.2957795f * (atan2(lhs.x, lhs.y) - atan2(rhs.x, rhs.y));
}


Next time draw a diagram and work out the formula properly instead of trying to copy and paste things from tutorials. Nexus even told you what to do and instead of listening, you randomly multiplied the x and y components of the vectors together and shoved them into a function. Just take a step back and think about what you are doing.

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #8 on: October 22, 2011, 12:05:11 am »
Quote from: "sbroadfoot90"
Dude, it's not the programming you have wrong. It's the maths. You're trying to do the wrong thing... You need something like this

Code: [Select]

float angleBetweenVectors(sf::Vector2f lhs, sf::Vector2f rhs)
{
    return 57.2957795f * (atan2(lhs.x, lhs.y) - atan2(rhs.x, rhs.y));
}


Next time draw a diagram and work out the formula properly instead of trying to copy and paste things from tutorials. Nexus even told you what to do and instead of listening, you randomly multiplied the x and y components of the vectors together and shoved them into a function. Just take a step back and think about what you are doing.


Actually, those multiplications are an adaption of the code Nexus pointed me to. His code required cross/dot products, which is where that came from. That, and the code you recommend is something I came up with myself and already tried, based on Nexus's instructions. Both what you recommend and what I created from Nexus's code result in the same illogical rotation.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #9 on: October 22, 2011, 12:13:08 am »
Quote from: "sbroadfoot90"
Nexus even told you what to do and instead of listening, you randomly multiplied the x and y components of the vectors together and shoved them into a function.
It's not random, my implementation is as follows. Strange, but I find it quite elegant. And don't ask me how I came to it :D
Code: [Select]
template <typename T>
T Angle(const sf::Vector2<T>& lhs, const sf::Vector2<T>& rhs)
{
assert(lhs != sf::Vector2<T>() && rhs != sf::Vector2<T>());
return TrigonometricTraits<T>::ArcTan2(CrossProduct(lhs, rhs).z, DotProduct(lhs, rhs));
}


Quote from: "lazerblade"
Both what you recommend and what I created from Nexus's code result in the same illogical rotation.
What do you mean with "illogical" rotation? It looks like you don't expect the same behavior as sbroadfoot90 and I do, so you should probably explain what you exactly want to calculate, ideally with an obvious example. To find out what I expect, read the thor::Angle() doc ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #10 on: October 22, 2011, 12:24:32 am »
Quote from: "Nexus"
Quote from: "lazerblade"
Both what you recommend and what I created from Nexus's code result in the same illogical rotation.
What do you mean with "illogical" rotation? It looks like you don't expect the same behavior as sbroadfoot90 and I do, so you should probably explain what you exactly want to calculate ;)


Good point. I expect to get back how much rotation an object at vector lhs would need in order to face an object at vector rhs, where both of these objects have the center set as half their size. What I'm getting back is... hard to explain. Screenshot thumbnails anyone?







I tried to take screenshots that would give a good idea of how the rotation is turning out, but these don't exactly describe it perfectly.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #11 on: October 22, 2011, 12:35:25 am »
What do you mean with "at vector rhs/lhs"? You cannot describe position and orientation with a single vector, maybe this is your problem.

But given a spaceship at position p with velocity v and the mouse cursor at position q, you can find out the rotation needed for the spaceship to face the cursor like this:
Code: [Select]
thor::Angle(v, q - p)
q - p is the direction vector from the spaceship towards the cursor. Draw it on paper to imagine it better :)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #12 on: October 22, 2011, 01:31:32 am »
Quote from: "Nexus"
What do you mean with "at vector rhs/lhs"? You cannot describe position and orientation with a single vector, maybe this is your problem.

That's just it. I don't care what the ship's orientation is.

Quote from: "Nexus"

But given a spaceship at position p with velocity v and the mouse cursor at position q, you can find out the rotation needed for the spaceship to face the cursor like this:
Code: [Select]
thor::Angle(v, q - p)
q - p is the direction vector from the spaceship towards the cursor. Draw it on paper to imagine it better :)


Ah yes, I understand. From when I first encountered this bug, I've filled about five pages with my fundamental understanding of trig now, and I think I'm starting to get the idea. This almost worked, but then I was quite irked to find that it has the same problem as my original function.

To explain more perfectly what is happening, I will use more screenshots.



As you can see, any angle divisible by 45 degrees (or almost,) is good (enough). However...



As I leave that rotation area, the rotation starts to get messed up.

If the rotation should 100% be working, that means the only place left for the problem is my local motion code. I can provide and explain it if need be.

lazerblade

  • Newbie
  • *
  • Posts: 14
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #13 on: October 22, 2011, 01:55:23 am »
P.S:

It's probably also quite important to note that I have to negate the angle I get from the function and then subtract 180 degrees from it in order to make it behave as it does. Otherwise the rotation is 180 degrees of and backwards.

sbroadfoot90

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
[SOLVED] atan2 ineffective when Rotating x to face y?
« Reply #14 on: October 23, 2011, 07:11:49 am »
Reading through all your posts, you kinda never really explain what sort of behaviour you want. Everything you say is really confusing. Perhaps you should just start over, draw a simple diagram and let us know what you want to do.

This is not a programming problem, it's a maths problem.