I'm trying to use atan2 to turn a range of - 1 to 1 into radians and then from radians into degrees.
However atan2(0,1) is equal to 0 when it should be equal 90.0 what am I doing wrong here?
float radians = atan2(0, 1);
float degrees = (radians * 180 / PI);
if(radians < 0)
{
degrees += 360;
}
Edit: Okay so i've plugged in the values the right way round this time.
float xaxisval = controller->left_stick_x_axis();
float yaxisval = controller->left_stick_y_axis();
// plug values into atan2
float radians = atan2(yaxisval, xaxisval);
float degrees = (radians * 180 / PI);
if (radians < 0)
{
degrees += 360;
}
For context xaxisval and yaxisval are grabbing a value from an analog stick with a max value of 1 to the right and a minimum value of -1 to the left. So when i press the analog stick to the right the yaxisval is equal to 0 and the xaxisval is equal to 1.
This should return 90 degrees, as if you imagine the analog stick as a full 360 degree circle. Up direction is 360/0 right is 90 down is 180 left is 270 etc.
I stuck these values into the debugger and this is what it returned.
xaxisval: 1.00000
yaxisval: 0.00000
degrees: 0.00000
However I want this direction to come up as 90 degrees it has seemed to jumped up by 90 degrees and i tested the down position and it was equal to 90. Any suggestions?
Debugging Output: Joystick Up position
xaxisval: 0.00000
yaxisval: -1.00000
degrees: 270.00000
Joystick Right position
xaxisval: 1.00000
yaxisval: 0.00000
degrees: 0.00000
Joystick Down position
xaxisval: 0.00000
yaxisval: 1.00000
degrees: 90.00000
Joystick Left position
xaxisval: -1.00000
yaxisval: 0.00000
degrees: 180.00000
Joystick North East position
xaxisval: 0.929412
yaxisval: 0.592157
degrees: 327.497528
You're passing in the arguments in the wrong order.
std::atan2
expects the arguments in the ordery,x
, notx,y
.Yes, that is incredibly dumb, but it's related to how the tangent function is defined in the first place (which is defined as a ratio of the y-component to the x-component, not the other way around), and like many notational mistakes in mathematics, inertia set in thousands of years ago and you can't push back against it without being a crank.
So write your code like this:
Or, if you want everything as explicit as possible:
And you'll get the results you expect.
Your second problem is that the values that
atan2
correspond to don't match up with the directions you want. What you want is a circle where the top is 0°, the right side is 90°, the bottom is 180°, and the left side is 270°. Punching the values intoatan2
is instead going to produce values where the right side is 0°, up is 90°, left is 180°, and down is 270°.Also, in comparing with my own hardware, my y-axis is flipped compared to yours. Mine is y+↑, whereas your setup appears to be y-↑
So if you want to transform the normal
atan2
rotation into the rotation you want, you'll need to transform it like this:Then, all you have to do from there is possibly transform the y-axis depending on whether you expect the joystick pushed up to return a positive or negative value. That's up to the domain of your program.