atan2#
Arc tangent of Y/X in the range -π to π.
atan2 is the two-argument arctangent — the inverse of tangent that
keeps enough information about its inputs to return the correct
quadrant. Unlike a single-argument atan, which collapses the two
signs of Y and X into one ratio and cannot distinguish the upper
half-plane from the lower, atan2 looks at both arguments and returns
an angle covering the full circle: (-π, π] radians. It is the
canonical way in Perl to convert Cartesian coordinates (X, Y) into
the polar angle θ.
Synopsis#
atan2 Y, X
What you get back#
A floating-point number, the angle in radians between the positive
x-axis and the point (X, Y), measured counter-clockwise. Range:
-π < result ≤ π. Sign follows Y: positive Y gives a positive
angle (upper half-plane), negative Y gives a negative angle (lower
half-plane). To convert to degrees multiply by 180 / π:
my $deg = atan2($y, $x) * 180 / 3.14159265358979;
Examples#
Compute π to machine precision. The angle from the origin to (0, 1)
is exactly π/2, so atan2(1, 0) * 2 gives π:
my $pi = atan2(1, 0) * 2;
printf "%.15f\n", $pi; # 3.141592653589793
Quadrant handling. The four cardinal directions land on exact
multiples of π/2, with (−1, 0) at the boundary +π, not -π:
print atan2( 1, 0), "\n"; # 1.5707963267949 (+π/2, up)
print atan2( 0, 1), "\n"; # 0 (right)
print atan2(-1, 0), "\n"; # -1.5707963267949 (-π/2, down)
print atan2( 0, -1), "\n"; # 3.14159265358979 (+π, left)
Polar conversion. Given a point (X, Y), recover radius and angle:
my ($x, $y) = (3, 4);
my $r = sqrt($x*$x + $y*$y); # 5
my $theta = atan2($y, $x); # 0.927295218001612 rad ≈ 53.13°
Tangent via the standard identity. Perl has no built-in tan, but
sin and cos give it directly — and atan2 inverts the result
unambiguously:
sub tan { sin($_[0]) / cos($_[0]) }
my $angle = 0.7;
print atan2(tan($angle), 1), "\n"; # 0.7 (recovers the input)
Full-circle sweep. Iterating Y around the unit circle shows the
range covers (-π, π]:
for my $deg (0, 45, 90, 135, 180, -135, -90, -45) {
my $rad = $deg * 3.14159265358979 / 180;
printf "%4d° -> %+.4f rad\n",
$deg, atan2(sin($rad), cos($rad));
}
Edge cases#
Both arguments zero:
atan2(0, 0)is mathematically undefined. The value Perl returns is whatever the platform’s Catan2(3)returns for this case — on glibc and musl that is0, and POSIX permits any value in[-π, π]. Do not rely on a specific result; check for($x == 0 && $y == 0)before calling if zero is a real possibility in your inputs.Signed zeros: on IEEE-754 platforms
atan2(+0, -0)returns+πandatan2(-0, -0)returns-π. This only matters in code that deliberately tracks zero signs; most Perl code never distinguishes them.Infinities:
atan2(Inf, Inf) == π/4,atan2(Inf, -Inf) == 3π/4,atan2(-Inf, Inf) == -π/4,atan2(-Inf, -Inf) == -3π/4. The direction “toward(±Inf, ±Inf)” is still a well-defined angle bisecting the appropriate quadrant.NaN inputs: if either
YorXisNaN, the result isNaN. Propagates through any further arithmetic — guard with aScalar::Util::looks_like_numbercheck on inputs from untrusted sources.Non-numeric arguments: strings are coerced to numbers by the usual Perl rules.
atan2("3", "4")works;atan2("abc", 1)is equivalent toatan2(0, 1)and emits anArgument "abc" isn't numericwarning underuse warnings.Argument order is
Y, X, notX, Y: this matches C’satan2(3), FORTRAN’sATAN2, and every other language’s two-argument arctangent. Reversing the arguments gives the complement angle — a subtle bug that tests in only one quadrant will miss.atan2is notatan: there is no one-argument form.atan2($ratio)is a syntax error at the call site. For the single-argument arctangent, useMath::Trig::atanorPOSIX::atan, or write it asatan2($ratio, 1).
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
sin— sine; paired withcosto reconstruct an angle’s coordinates afteratan2has extracted itcos— cosine; theXcomponent when converting a radius and angle back to Cartesian coordinatessqrt— square root; used withatan2in the Cartesian → polar conversion($r, $theta) = (sqrt($x**2+$y**2), atan2($y,$x))Math::Trigext — shipstan,atan,asin,acos, and the hyperbolic family; also exportspias a constant so you do not have to writeatan2(1,0)*2