Let’s see the Javadoc of method atan2(double, double)
, already translated into Portuguese by me:
public static double atan2(double y,
double x)
Returns the angle tit conversion of rectangular coordinates (x, y)
to the polar coordinates (r, teta)
. This method computes the phase tit when computing an arc-tangent of y/x
in the interval -pi to pi. Special cases:
If any argument is NaN
, then the result is NaN
.
If the first argument is positive zero and the second argument is positive, or the first argument is positive and finite and the second argument is positive infinite, then the result is positive zero.
If the first argument is negative zero and the second argument is positive, or the first argument is negative and finite and the second argument is positive infinite, then the result is negative zero.
If the first argument is positive zero and the second argument is negative, or the first argument is positive and finite and the second argument is negative infinite, then the result is the value double
closest to pi.
If the first argument is negative zero and the second argument is negative, or the first argument is negative and finite and the second argument is negative infinite, then the result is the value double
closest to -pi.
If the first argument is positive and the second argument is positive zero or negative zero, or the first argument is positive infinite and the second argument is finite, then the result is the value double
closest to pi/2.
If the first argument is negative and the second argument is positive zero or negative zero, or the first argument is negative infinite and the second argument is finite, then the result is the value double
closest to -pi/2.
If both arguments are infinite positive, then the result is the value double
closest to pi/4.
If the first argument is infinite positive and the second argument is infinite negative, then the result is the value double
closest to 3*pi/4.
If the first argument is infinite negative and the second positive is infinite negative, then the result is the value double
closest to -pi/4.
If both arguments are infinite negative, then the result is the value double
closest to -3*pi/4.
The computed result should be within 2 ulps of the exact result. Results should be semi-monotonic.
Parameters:
y
- the orderly coordinate
x
- the abscised coordinate
Returns:
The component tit point (r, teta)
in polar coordinates corresponding to the point (x, y)
in Cartesian coordinates.
Okay, maybe you don’t understand anything about documentation, after all it uses rather complicated mathematical concepts. To understand it, let’s consider it:
Forget special cases, they are only there to solve indeterminations that would occur in very peculiar and unusual situations.
This 2 ulps business is just a way to specify an error margin. This is because the double
uses a finite number of bits (64), but the exact result of atan2
can be (and almost always is) an irrational number, and therefore cannot be accurately represented in any finite number of bits. This semi-monotonic business is to indicate that very close numbers within the margin of error will not produce results in inverse orders to those expected. However, these details here should not matter for the problem you want to solve.
The Java method works with double
s and not with float
s. I imagine Processing is providing a atan2
with float
s for simplicity. However, in any case, the practical effect will be the same.
Note that the order of the parameters is y
and x
, and not x
and y
.
The float
and the double
keep the signal from zero, differentiating +0 from 0. They can also represent + e is a thing called NaN
. This is probably not going to be important to you. Why these things happen is subject to some other question.
Tit is the name of a Greek letter: θ. As well as pi is π.
The point is that you have to imagine that we have the Cartesian and polar systems:
In the Cartesian system, you have coordinates (x, y)
where x
is the distance between the point you have and the line vertical which passes through the origin (ie how much that point is moved sideways) and the y
is the distance between the point you have and the line horizontal which passes through the origin (i.e., how much the point is moved up or down).
In the polar system, you have coordinates (r, teta)
where teta
is the direction in which the point you have is from the origin and r
is the distance to him.
If you were in a flat field, in search of a buried treasure, with a paper containing the instructions to find it in hand, and on that paper was written, "turn 60 degrees to the left and walk 500 meters", this would be an orientation using polar coordinates. But if it is written "walk 250 meters forward and then 433 meters to your left", then cartesian coordinates are used. The two orientations arrive in the same place1, though at first you will travel a shorter distance.
1: Actually there is a difference of about one centimeter. The correct value would be 433,012701892... meters.
However, the question remains:
If the paper says I have to walk 250 meters forward and then 433 meters to my left, but I’m in a hurry because the time is short and I can’t walk more than I need to, how could I know what I would have to do is turn 60 degrees to the left and then walk 500 meters?
Distance can be solved by Pythagoras' theorem. We have that 250 meters and 433 meters are the catetos of a rectangular triangle and the stretch to go is the hypotenuse. Soon:
Rounding the error of one centimeter, gave 500 meters.
And now that we know the distance to travel, how can we know the direction?
Looking at the Cartesian coordinates, the x
is the distance I would travel forward (or backward if negative) and the y
is the distance I follow somewhere. Which side? Right or left? The Cartesian plan is usually drawn with the positive direction of the x
going to the right and the y
up. So if you draw this on paper and spin the paper by placing it on the floor with the axis x
facing its front, the axle y
will be pointing to your left, and therefore the y
would be the distance you would go left (or right if negative). It is important to do so, as the angles with the polar coordinates are measured from the axis x
and rotate towards the axis y
reaching it at 90 degrees. With this coordinate system that we have, the positive angles would then be expressed counterclockwise, that is, turning to the left (and the negative angles would be to the right, clockwise).
Finally, to convert the Cartesian coordinates to polar and get the tit (i.e., θ) is where the atan2
enters:
(despising that error of about 1 cm since it is not exactly 433 meters)
That one is a measure in radians.
Converting to degrees:
That is, 60 degrees turning to the left.
That said, let’s see your code:
float getAngle() {
return atan2(height-mouseY, mouseX);
}
The origin of the system is the pixel in the corner upper left. So, mouseX
is the distance (horizontal) from the left edge of the screen to the mouse position and mouseY
is the distance (vertical) from the top edge of the screen to the mouse position.
However, we have to note that the positive direction of y
on the screen is not up, but down. This will cause the polar coordinates to rotate to the right instead of to the left.
That one height-mouseY
is interesting. Imagine a vertical line segment cutting the screen from the top edge to the bottom edge and passing through the point where the mouse is. This point will divide this line segment into two parts, one above and one below the mouse position. The size of the two parts together is height
, which is the height of the screen (which is the distance between the upper and lower edges). The size of the part above the mouse position is equal to the distance between the top edge and that position, i.e., mouseY
. Therefore, the size of the part below this position is the total size less the size of the top, i.e. height-mouseY
.
What height-mouseY
be the bottom means? Means that is the distance between the mouse position and the edge inferior from the screen. This is a trick to move the source to the corner inferior left instead of the corner superior left. However, this trick generates a side effect that is to reverse the direction of the axis y
, after all, the sign of mouseY
is negative, and therefore its meaning is reversed. This causes the new y
resulting from this transformation again point upward and cause the angles of the polar coordinates to turn left again.
With this we apply the atan2
. It will give the direction between the bottom left corner of the screen and the mouse position in radians, whereas the zero angle would be the one where the mouse is on the bottom edge.
If the point of origin is in the lower left corner, then unless the mouse could be outside the screen, there is no way it is below and not to the left of the point of origin, it necessarily has to be above and to the right (or at most on the same line, either horizontally or vertically). Considering that the zero angle would be the one on the bottom edge (right to right from the origin) and that the coordinates are rotating to the left, we have that 90 degrees will be the angle on the left edge of the screen (right up from the origin). This means that whatever the resulting angle of any point within the screen, it will be between 0 and 90 degrees. Or if you prefer, between 0 and π/2 radians.
Finally, there is still an interesting case: If the mouse is in the bottom left corner, we have that the angle formed between the bottom left corner and the mouse position is... undetermined! You can’t calculate an angle between two points if those two points are really one! That’s where the special cases come in. This will probably fall in the second special case and result in +0.
I use this tangent in the text of my question: https://answall.com/q/260764/64969 Including I counter it to "arctangent 1"
– Jefferson Quesado