Search code examples
mathatan2

Is there a way to reverse the effect of atan2?


I have a specific question about reversing atan2, I will write my code example in PHP.

$radial = 1.12*PI();
$transformed = -atan2(cos($radial)*2, sin($radial)*1.5);
$backToRadial = ?

Is there a way to reverse the transformed value to the start radial, without knowing the start radial? This is how code flow should be: $radial => transform($radial) => transformback(transform($radial)) => $radial.

I have searched on the web (incl. stack) but I couldn't find any correct code. Also looked on Wikipedia, but it was overwhelming. My question is more a algebra question I think ;).

Let me know what you think!

_

Answered by Jason S:

Answer (by radial range: -PI-PI):
$backToRadial = atan2(2*cos($transformed), -1.5*sin($transformed));

Answer (by radial range: 0-2PI):
$backToRadial = PI() + atan2(-(2*cos($transformed)), -(-1.5*sin($transformed)));

Solution

  • A simple answer that will work for principal angles (angles over the range θ = -π to +π) is as follows:

    θ' = -atan2(2cos θ, 1.5sin θ)

    θ = atan2(2cos θ', -1.5sin θ')

    where the first equation is your forward transformation, and the second equation is one of many inverse transformations.

    The reason for this is that what you're doing is equivalent to a reflection + scaling + unit-magnitude-normalization of the cartesian coordinate pair (x,y) = (r cos θ, r sin θ) for r =1, since atan2(y,x) = θ.

    A specific transformation that will work is (x',y') = (1.5y, -2x).

    θ' = atan2(y',x') = atan2(-2x, 1.5y) = atan2(-2Rcos θ, 1.5Rsin θ) = -atan2(2 cos θ, 1.5 sin θ), with the last step true since atan2(ky,kx) = atan2(y,x) for any k > 0, and -atan2(y,x) = atan2(-y, x).

    This can be reversed by solving for x and y, namely y = 1/1.5 * x' and x = -1/2 * y':

    θ = atan2(y,x) = atan2(1/1.5 * x', -1/2 * y')

    and we choose to multiply (x,y) by k = 3/R to leave the angle unchanged:

    θ = atan2(2x'/R, -1.5y'/R) = atan2(2 cos θ', -1.5 sin θ')

    Q.E.D.


    edit: Jason points out, correctly, that your example angle 1.12π is not in the principal angle range -π to +π. You need to define the range of angles you wish to be able to handle, and it has to be a range of at most length 2π.

    My answer can be adjusted accordingly, but it takes a bit of work to verify, and you would make it easier on yourself if you stuck to the -π to +π range, since you are using atan2() and its output is in this range.

    If you want to use a modified version of atan2() that outputs angles in the 0-2π range, I'd recommend using

    atan2b(y,x) = pi+atan2(-y,-x)
    

    where atan2b now outputs between 0 and 2π, since the calculation atan2(-y,-x) differs from atan2(y,x) by an angle of π (mod 2π)

    If you're going to take this approach, don't calculate -atan2b(y,x); instead calculate atan2b(-y,x), (equivalent mod 2π) so that the range of output angles is left unchanged.