Math.atan()
Returns the arctangent of a number in radians, the angle whose tangent is that value.
Math.atan(x)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$x | number | A number. |
Return value
numberThe inverse tangent — an angle in radians between -π/2 and π/2, inclusive — of x. Returns π/2 for Infinity and -π/2 for -Infinity.
Math.atan(x) takes a slope and returns the angle, in radians, whose tangent is that slope. Unlike Math.asin() and Math.acos() it accepts any finite number — every real slope corresponds to some angle — and it never returns NaN for a numeric input. Even Infinity maps cleanly to π/2.
When to reach for it
Use it when you genuinely have a ratio and not two separate components: converting a road gradient or a CSS transform's slope into an angle, mapping an unbounded value into the bounded range (-π/2, π/2) for a soft-clipping or activation curve, or fitting a line and reporting its inclination.
What trips people up
The output only spans half the circle. Because y / x discards the signs of the two components, Math.atan(1 / 1) and Math.atan(-1 / -1) both give 45°, even though the points (1,1) and (-1,-1) point in opposite directions. Worse, an x of 0 makes the division Infinity or, when y is also 0, NaN.
Whenever you are computing a direction from a pair of coordinates, use Math.atan2() instead. It takes the components separately, keeps all four quadrants distinct, and handles zeros. Math.atan() is for slopes that were never a pair to begin with.
Example
When to use it
- Convert a road gradient or ramp slope into an angle
- Report the inclination of a fitted regression line
- Squash an unbounded score into a bounded range for display
- Turn a CSS skew or shear factor into degrees
Frequently asked questions
What is the difference between Math.atan() and Math.atan2()?
Math.atan() takes a single ratio y/x and returns an angle in (-π/2, π/2), while Math.atan2(y, x) takes the components separately and returns an angle in [-π, π] covering all four quadrants. Use atan2 for directions from coordinates; atan only when the input is genuinely one slope.
Does Math.atan() ever return NaN?
Only if the argument is NaN. Every finite number has an arctangent, and Math.atan(Infinity) returns π/2 while Math.atan(-Infinity) returns -π/2 — so a NaN result means the division that produced the argument was 0/0.
How do I convert a slope to degrees in JavaScript?
Pass the slope to Math.atan() and multiply by 180 / Math.PI. A 0.1 gradient becomes Math.atan(0.1) * 180 / Math.PI, which is about 5.71 degrees.
More examples
Why atan2 exists
The ratio form reports 45 for both (1,1) and (-1,-1), while atan2 correctly separates them into 45 and -135. A zero x divides to Infinity — atan survives that with π/2 — but 0/0 is NaN, where atan2(0, 0) returns a usable 0.
const deg = (r) => Math.round((r * 180) / Math.PI);
// Two opposite directions, one ratio
console.log(deg(Math.atan(1 / 1)), deg(Math.atan(-1 / -1)));
console.log(deg(Math.atan2(1, 1)), deg(Math.atan2(-1, -1)));
// A straight-up direction
console.log(Math.atan(1 / 0), Math.atan2(1, 0));
console.log(Math.atan(0 / 0), Math.atan2(0, 0));Bounded squashing
Because Math.atan() is bounded by ±π/2, dividing by π and shifting maps the whole real line onto (0, 1): extreme inputs approach 0.000318 and 0.999682 without ever clipping, and Infinity lands exactly on 1.
// Map any score into 0..1 without a hard cutoff
const squash = (x) => Math.atan(x) / Math.PI + 0.5;
for (const x of [-1000, -1, 0, 1, 1000]) {
console.log(x, squash(x).toFixed(6));
}
console.log(squash(Infinity));Slope of a fitted line
Least squares gives a slope of 1.9800, and Math.atan() turns that gradient into 63.20 degrees. This is the case atan is actually for: a single ratio that was computed as a ratio, not a pair of coordinates.
const points = [[0, 0], [1, 2], [2, 4.1], [3, 5.9]];
const n = points.length;
const sx = points.reduce((s, [x]) => s + x, 0);
const sy = points.reduce((s, [, y]) => s + y, 0);
const sxy = points.reduce((s, [x, y]) => s + x * y, 0);
const sxx = points.reduce((s, [x]) => s + x * x, 0);
const slope = (n * sxy - sx * sy) / (n * sxx - sx * sx);
console.log(slope.toFixed(4));
console.log(((Math.atan(slope) * 180) / Math.PI).toFixed(2) + "deg");
Discussion