Math.tan()
Returns the tangent of an angle given in radians — the slope of the ray at that angle.
Math.tan(x)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$x | number | A number representing an angle in radians. |
Return value
numberThe tangent of x. If x is Infinity, -Infinity, or NaN, returns NaN. Because the exact value π/2 is not representable as a double, the result is always finite when it is not NaN.
Math.tan(x) returns sin(x) / cos(x) for an angle in radians. Read geometrically it is a slope: the rise-over-run of a ray drawn at that angle, or opposite over adjacent in a right triangle.
When to reach for it
Given an angle and one side, tangent gets you the other: the height of a building from its distance and an elevation angle, the gradient of a ramp, the reach of a cone. In graphics it sizes the view frustum — a perspective projection's scale factor is 1 / Math.tan(fov / 2). It also converts a heading into a line's slope for hit-testing and ray casting.
What trips people up
Tangent has vertical asymptotes at π/2 plus any multiple of π, where it should be undefined. It never actually returns Infinity, because π/2 is not exactly representable as a double — instead Math.tan(Math.PI / 2) returns a huge finite 16331239353195370. Code that guards against Infinity will not catch it. Test the magnitude, or check the angle before calling.
Precision is poor near those asymptotes: a tiny error in the input produces an enormous error in the output. And the familiar radians trap applies — Math.tan(45) is 1.6198, while the intended Math.tan(45 * Math.PI / 180) is 0.9999999999999999.
Example
When to use it
- Compute a height from a horizontal distance and an elevation angle
- Derive the projection scale from a camera field of view
- Turn a heading in degrees into a line slope for a ray cast
- Size a shadow or cone footprint from a light angle
Frequently asked questions
Why does Math.tan(Math.PI / 2) not return Infinity?
Math.PI / 2 is a double approximation, not the true π/2, so the argument is a hair off the asymptote and its tangent is a large but finite 16331239353195370. Guard by testing Math.abs(result) against a large threshold rather than with Number.isFinite().
How do I calculate a height from an angle in JavaScript?
Multiply the horizontal distance by the tangent of the elevation angle in radians: distance * Math.tan(degrees * Math.PI / 180). For 10 metres at 30 degrees that gives about 5.7735 metres.
Why does Math.tan(Math.PI / 4) return 0.9999999999999999?
The true tangent of π/4 is 1, but Math.PI is rounded to the nearest double, so the input is slightly off and the result misses by one unit in the last place. Round or compare with an epsilon when you need the exact value.
More examples
The asymptote is finite
The vertical asymptote produces 16331239353195370 rather than Infinity, so Number.isFinite() reports true and any guard built on it lets the value through. Comparing the magnitude against a large threshold catches it. Nudging the input by 1e-10 flips the result to a large negative — precision is worthless in that neighbourhood.
const near = Math.tan(Math.PI / 2);
console.log(near);
console.log(Number.isFinite(near)); // true, so isFinite guards fail
console.log(Math.abs(near) > 1e15); // this is the real check
console.log(Math.tan(Math.PI / 2 + 1e-10));
console.log(Math.tan(Math.PI)); // -1.2246467991473532e-16Field of view to projection scale
A wider field of view means a smaller scale factor: 2.4142 at 45 degrees down to 0.5774 at 120. At 90 degrees the half-angle is 45, whose tangent is 1, so the scale is essentially exactly 1.
const fovScale = (fovDegrees) =>
1 / Math.tan((fovDegrees * Math.PI) / 180 / 2);
for (const fov of [45, 60, 90, 120]) {
console.log(fov + "deg fov", fovScale(fov).toFixed(4));
}Slope of a heading
Ordinary headings return usable slopes: 0, 0.5774, 1.0000, 57.2900 and -1.0000 at 135 degrees. The 90-degree case reports "vertical" only because of the magnitude threshold — without it the function would hand back a 16-quadrillion slope.
function slope(headingDeg) {
const rad = (headingDeg * Math.PI) / 180;
const m = Math.tan(rad);
return Math.abs(m) > 1e12 ? "vertical" : m.toFixed(4);
}
console.log([0, 30, 45, 89, 90, 135].map(slope));
Discussion