atan() 函数用于计算反正切值,返回以弧度表示的角,其正切值等于指定数字。
atan() 函数返回一个数的反正切值(arctangent)。参数可以是任意实数,返回值的范围是 -π/2 到 π/2 弧度。
atan(float $num): float
| 参数 | 类型 | 描述 | 必需 |
|---|---|---|---|
$num |
float | 要计算反正切值的数字,可以是任意实数 | 是 |
返回参数 $num 的反正切值,以弧度为单位。返回值范围是 -π/2 到 π/2(约 -1.5707963267949 到 1.5707963267949)。
计算不同数字的反正切值:
<?php
// 计算反正切值
echo "atan(0) = " . atan(0) . " 弧度\n"; // 0
echo "atan(1) = " . atan(1) . " 弧度\n"; // 约 0.78539816339745 (π/4)
echo "atan(-1) = " . atan(-1) . " 弧度\n"; // 约 -0.78539816339745 (-π/4)
echo "atan(0.57735026918963) = " . atan(0.57735026918963) . " 弧度\n"; // 约 0.5235987755983 (π/6)
echo "atan(-0.57735026918963) = " . atan(-0.57735026918963) . " 弧度\n"; // 约 -0.5235987755983 (-π/6)
// 处理大数
echo "atan(1000) = " . atan(1000) . " 弧度\n"; // 约 1.5697963271282
echo "atan(-1000) = " . atan(-1000) . " 弧度\n"; // 约 -1.5697963271282
// 转换弧度到角度
$radians = atan(1);
$degrees = rad2deg($radians);
echo "atan(1) = " . $radians . " 弧度 (" . $degrees . " 度)\n";
// 验证 tan(atan(x)) = x
$x = 2.5;
$atan_x = atan($x);
$tan_atan_x = tan($atan_x);
echo "验证: tan(atan(" . $x . ")) = tan(" . $atan_x . ") = " . $tan_atan_x . "\n";
echo "误差: " . abs($tan_atan_x - $x) . "\n";
?>
在角度和弧度之间进行转换:
<?php
// 创建一个角度计算类
class AngleCalculator {
const PI = M_PI;
// 计算角度(度)的反正切
public static function atanDeg($value) {
return rad2deg(atan($value));
}
// 计算正切为指定值的角度(度)
public static function angleFromTangent($tangent) {
$radians = atan($tangent);
return rad2deg($radians);
}
// 计算斜边和邻边的夹角
public static function angleFromOppositeAdjacent($opposite, $adjacent) {
if ($adjacent == 0) {
// 处理除零情况
return $opposite > 0 ? 90 : ($opposite < 0 ? -90 : 0);
}
return self::angleFromTangent($opposite / $adjacent);
}
}
// 使用示例
echo "常见正切值对应的角度:\n";
$tangentValues = [0, 0.5773503, 1, 1.7320508, 1000, -0.5773503, -1, -1.7320508, -1000];
foreach ($tangentValues as $tan) {
$angle = AngleCalculator::angleFromTangent($tan);
echo "tan(θ) = " . round($tan, 4) . " → θ = " . round($angle, 2) . "°\n";
}
echo "\n从对边和邻边计算角度:\n";
$sides = [
[3, 4], // 对边=3, 邻边=4
[4, 3], // 对边=4, 邻边=3
[1, 1], // 对边=1, 邻边=1 (45°)
[1, 0], // 对边=1, 邻边=0 (90°)
[0, 1], // 对边=0, 邻边=1 (0°)
[-3, 4], // 对边=-3, 邻边=4
[3, -4] // 对边=3, 邻边=-4
];
foreach ($sides as $i => $side) {
$opposite = $side[0];
$adjacent = $side[1];
$angle = AngleCalculator::angleFromOppositeAdjacent($opposite, $adjacent);
echo "对边=$opposite, 邻边=$adjacent → 角度 = " . round($angle, 2) . "°\n";
}
// 计算atan和atan2的关系
echo "\natan和atan2关系:\n";
$testPairs = [[1, 1], [1, -1], [-1, 1], [-1, -1], [0, 1], [1, 0]];
foreach ($testPairs as $pair) {
$y = $pair[0];
$x = $pair[1];
$atan2_result = rad2deg(atan2($y, $x));
if ($x != 0) {
$atan_result = rad2deg(atan($y / $x));
echo "点($x, $y): atan(y/x) = " . round($atan_result, 2) . "°, atan2(y, x) = " . round($atan2_result, 2) . "°\n";
} else {
echo "点($x, $y): atan2(y, x) = " . round($atan2_result, 2) . "° (atan无法计算,因为x=0)\n";
}
}
?>
在几何中使用atan()计算角度:
<?php
// 计算直线与x轴的夹角
class GeometryCalculator {
// 计算两点确定的直线与x轴的夹角(弧度)
public static function lineAngle($x1, $y1, $x2, $y2) {
$dx = $x2 - $x1;
$dy = $y2 - $y1;
if (abs($dx) < 0.000001) {
// 垂直线
return $dy > 0 ? M_PI_2 : -M_PI_2;
}
return atan($dy / $dx);
}
// 计算三角形中的角度
public static function triangleAngle($side1, $side2, $side3) {
// 使用余弦定理计算角度
// 角A的对边是side1
$cosA = ($side2*$side2 + $side3*$side3 - $side1*$side1) / (2 * $side2 * $side3);
// 使用acos计算角度
$angleA = acos($cosA);
// 也可以使用反正切计算
// sinA = sqrt(1 - cosA*cosA)
// tanA = sinA / cosA
// $angleA = atan(sqrt(1 - $cosA*$cosA) / $cosA);
return $angleA;
}
// 计算向量的方向角
public static function vectorDirection($x, $y) {
// 返回向量(x, y)与x轴的夹角
if (abs($x) < 0.000001) {
return $y > 0 ? M_PI_2 : -M_PI_2;
}
$angle = atan($y / $x);
// 调整角度到正确的象限
if ($x < 0) {
$angle += M_PI;
}
// 确保角度在[-π, π]范围内
if ($angle > M_PI) {
$angle -= 2 * M_PI;
}
return $angle;
}
}
// 使用示例
echo "计算直线与x轴的夹角:\n";
$points = [
[0, 0, 1, 0], // 水平线 (0°)
[0, 0, 0, 1], // 垂直线 (90°)
[0, 0, 1, 1], // 45°线
[0, 0, 1, -1], // -45°线
[0, 0, -1, 1], // 135°线
[0, 0, -1, -1] // -135°线
];
foreach ($points as $point) {
$x1 = $point[0]; $y1 = $point[1];
$x2 = $point[2]; $y2 = $point[3];
$angle = GeometryCalculator::lineAngle($x1, $y1, $x2, $y2);
$angleDeg = rad2deg($angle);
echo "点($x1,$y1)到点($x2,$y2): 角度 = " . round($angleDeg, 2) . "°\n";
}
echo "\n计算三角形角度:\n";
$sideA = 3;
$sideB = 4;
$sideC = 5;
$angleA = GeometryCalculator::triangleAngle($sideA, $sideB, $sideC);
$angleB = GeometryCalculator::triangleAngle($sideB, $sideA, $sideC);
$angleC = GeometryCalculator::triangleAngle($sideC, $sideA, $sideB);
echo "三角形边长: a = $sideA, b = $sideB, c = $sideC\n";
echo "角A: " . round(rad2deg($angleA), 2) . "°\n";
echo "角B: " . round(rad2deg($angleB), 2) . "°\n";
echo "角C: " . round(rad2deg($angleC), 2) . "°\n";
echo "角度总和: " . round(rad2deg($angleA + $angleB + $angleC), 2) . "°\n";
echo "\n计算向量方向角:\n";
$vectors = [[1, 0], [0, 1], [1, 1], [-1, 1], [-1, -1], [1, -1]];
foreach ($vectors as $vector) {
$x = $vector[0];
$y = $vector[1];
$direction = GeometryCalculator::vectorDirection($x, $y);
$directionDeg = rad2deg($direction);
echo "向量($x, $y): 方向角 = " . round($directionDeg, 2) . "°\n";
}
?>
在物理和工程问题中应用atan()函数:
<?php
// 抛体运动中的角度计算
class ProjectileMotion {
// 计算抛体运动的发射角度以达到指定目标
public static function launchAngle($v0, $x, $y, $g = 9.81) {
// 公式: tan(θ) = (v0² ± √(v0⁴ - g(gx² + 2yv0²))) / (gx)
// 可能存在两个解
$v0_2 = $v0 * $v0;
$v0_4 = $v0_2 * $v0_2;
$discriminant = $v0_4 - $g * ($g * $x * $x + 2 * $y * $v0_2);
if ($discriminant < 0) {
throw new InvalidArgumentException("无法达到目标点");
}
$sqrt_discriminant = sqrt($discriminant);
$tan1 = ($v0_2 + $sqrt_discriminant) / ($g * $x);
$tan2 = ($v0_2 - $sqrt_discriminant) / ($g * $x);
$angle1 = atan($tan1);
$angle2 = atan($tan2);
return [
'angle1_rad' => $angle1,
'angle1_deg' => rad2deg($angle1),
'angle2_rad' => $angle2,
'angle2_deg' => rad2deg($angle2)
];
}
// 计算抛体落点
public static function landingPoint($v0, $angle_deg, $g = 9.81) {
$angle_rad = deg2rad($angle_deg);
$range = ($v0 * $v0 * sin(2 * $angle_rad)) / $g;
$max_height = ($v0 * $v0 * sin($angle_rad) * sin($angle_rad)) / (2 * $g);
return [
'range' => $range,
'max_height' => $max_height,
'time_of_flight' => (2 * $v0 * sin($angle_rad)) / $g
];
}
}
// 使用示例
echo "抛体运动计算:\n";
$v0 = 20; // 初速度 20 m/s
$x = 30; // 目标x坐标 30 m
$y = 5; // 目标y坐标 5 m
try {
$angles = ProjectileMotion::launchAngle($v0, $x, $y);
echo "初速度: {$v0} m/s, 目标点: ($x, $y) m\n";
echo "可能的发射角度:\n";
echo "角度1: " . round($angles['angle1_deg'], 2) . "° (" . round($angles['angle1_rad'], 4) . " 弧度)\n";
echo "角度2: " . round($angles['angle2_deg'], 2) . "° (" . round($angles['angle2_rad'], 4) . " 弧度)\n";
// 计算两个角度的轨迹
foreach ([$angles['angle1_deg'], $angles['angle2_deg']] as $i => $angle) {
$trajectory = ProjectileMotion::landingPoint($v0, $angle);
echo "\n角度" . ($i+1) . " ($angle°):\n";
echo " 射程: " . round($trajectory['range'], 2) . " m\n";
echo " 最大高度: " . round($trajectory['max_height'], 2) . " m\n";
echo " 飞行时间: " . round($trajectory['time_of_flight'], 2) . " s\n";
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
// 计算斜坡上的摩擦力角度
echo "\n斜坡上的物体:\n";
function calculateCriticalAngle($friction_coefficient) {
// 当物体刚好开始滑动时,摩擦角 = atan(摩擦系数)
$critical_angle_rad = atan($friction_coefficient);
$critical_angle_deg = rad2deg($critical_angle_rad);
return [
'coefficient' => $friction_coefficient,
'critical_angle_rad' => $critical_angle_rad,
'critical_angle_deg' => $critical_angle_deg
];
}
$friction_coefficients = [0.1, 0.2, 0.3, 0.5, 0.7, 1.0];
echo "摩擦系数与临界角:\n";
foreach ($friction_coefficients as $mu) {
$result = calculateCriticalAngle($mu);
echo "摩擦系数 μ = $mu → 临界角 = " . round($result['critical_angle_deg'], 2) . "°\n";
}
// 计算力与水平面的夹角
echo "\n力的分解:\n";
function forceComponents($force, $angle_deg) {
$angle_rad = deg2rad($angle_deg);
$horizontal = $force * cos($angle_rad);
$vertical = $force * sin($angle_rad);
return [
'force' => $force,
'angle' => $angle_deg,
'horizontal' => $horizontal,
'vertical' => $vertical
];
}
$force = 100; // 100 N
$angles = [0, 30, 45, 60, 90];
foreach ($angles as $angle) {
$components = forceComponents($force, $angle);
echo "力 = {$force}N, 角度 = {$angle}°:\n";
echo " 水平分量: " . round($components['horizontal'], 2) . " N\n";
echo " 垂直分量: " . round($components['vertical'], 2) . " N\n";
}
?>
高级应用和数值方法中使用atan()函数:
<?php
// 数值计算反正切的方法
class NumericalMethods {
// 使用泰勒级数计算反正切
public static function atanTaylor($x, $terms = 10) {
// 泰勒展开:atan(x) = x - x³/3 + x⁵/5 - x⁷/7 + ...
// 仅适用于 |x| < 1
$result = 0;
$sign = 1;
for ($n = 0; $n < $terms; $n++) {
$exponent = 2 * $n + 1;
$term = pow($x, $exponent) / $exponent * $sign;
$result += $term;
$sign *= -1;
}
return $result;
}
// 使用反正切公式计算π
public static function calculatePiMachin() {
// Machin公式:π/4 = 4*atan(1/5) - atan(1/239)
$term1 = 4 * atan(1/5);
$term2 = atan(1/239);
return 4 * ($term1 - $term2);
}
// 使用反正切公式计算π(高精度)
public static function calculatePiHighPrecision($iterations = 10) {
// 使用反正切公式:π = 16*atan(1/5) - 4*atan(1/239)
$pi = 0;
for ($n = 0; $n < $iterations; $n++) {
// 计算atan(1/5)的级数项
$x1 = 1/5;
$term1 = pow($x1, 2*$n+1) / (2*$n+1);
$term1 *= ($n % 2 == 0 ? 1 : -1);
// 计算atan(1/239)的级数项
$x2 = 1/239;
$term2 = pow($x2, 2*$n+1) / (2*$n+1);
$term2 *= ($n % 2 == 0 ? 1 : -1);
$pi += 16 * $term1 - 4 * $term2;
}
return $pi;
}
// 计算复数的辐角(argument)
public static function complexArgument($real, $imag) {
// 复数的辐角 = atan(imag/real)
// 需要考虑象限
if (abs($real) < 0.000001) {
if ($imag > 0) return M_PI_2;
if ($imag < 0) return -M_PI_2;
return 0; // 原点
}
$angle = atan($imag / $real);
// 调整到正确的象限
if ($real < 0) {
$angle += $imag >= 0 ? M_PI : -M_PI;
}
return $angle;
}
}
// 使用示例
echo "泰勒级数计算反正切:\n";
$testValues = [0.1, 0.5, 0.9];
foreach ($testValues as $x) {
$taylor = NumericalMethods::atanTaylor($x, 20);
$builtin = atan($x);
$error = abs($taylor - $builtin);
echo "atan($x): 泰勒 = " . sprintf("%.10f", $taylor) .
", 内置 = " . sprintf("%.10f", $builtin) .
", 误差 = " . sprintf("%.2e", $error) . "\n";
}
echo "\n使用反正切公式计算π:\n";
$piMachin = NumericalMethods::calculatePiMachin();
$piHighPrecision = NumericalMethods::calculatePiHighPrecision(20);
echo "Machin公式计算: π = " . sprintf("%.15f", $piMachin) . "\n";
echo "级数展开计算: π = " . sprintf("%.15f", $piHighPrecision) . "\n";
echo "PHP常量M_PI: π = " . sprintf("%.15f", M_PI) . "\n";
echo "Machin公式误差: " . abs($piMachin - M_PI) . "\n";
echo "级数展开误差: " . abs($piHighPrecision - M_PI) . "\n";
echo "\n计算复数的辐角:\n";
$complexNumbers = [
[1, 0], // 正实轴
[0, 1], // 正虚轴
[-1, 0], // 负实轴
[0, -1], // 负虚轴
[1, 1], // 第一象限
[-1, 1], // 第二象限
[-1, -1], // 第三象限
[1, -1] // 第四象限
];
foreach ($complexNumbers as $i => $number) {
$real = $number[0];
$imag = $number[1];
$arg = NumericalMethods::complexArgument($real, $imag);
$argDeg = rad2deg($arg);
echo "复数 {$real}+{$imag}i: 辐角 = " . round($argDeg, 2) . "° (" . round($arg, 4) . " 弧度)\n";
}
// 计算反正切的导数
echo "\n反正切函数的导数:\n";
function atanDerivative($x) {
// d(atan(x))/dx = 1/(1+x²)
return 1 / (1 + $x * $x);
}
function numericalDerivative($x, $h = 0.0001) {
// 数值导数
return (atan($x + $h) - atan($x - $h)) / (2 * $h);
}
$testPoints = [-2, -1, 0, 1, 2];
foreach ($testPoints as $x) {
$exact = atanDerivative($x);
$numeric = numericalDerivative($x);
$error = abs($exact - $numeric);
echo "x = $x: 精确导数 = " . round($exact, 6) .
", 数值导数 = " . round($numeric, 6) .
", 误差 = " . sprintf("%.2e", $error) . "\n";
}
// 计算反正切的积分
echo "\n反正切函数的积分:\n";
function atanIntegral($x) {
// ∫atan(x)dx = x·atan(x) - 0.5·ln(1+x²)
return $x * atan($x) - 0.5 * log(1 + $x * $x);
}
function numericalIntegral($a, $b, $n = 1000) {
// 数值积分(辛普森法则)
$h = ($b - $a) / $n;
$sum = atan($a) + atan($b);
for ($i = 1; $i < $n; $i++) {
$x = $a + $i * $h;
$sum += 4 * atan($x - $h/2) + 2 * atan($x);
}
$sum += 4 * atan($b - $h/2);
return $sum * $h / 6;
}
$a = 0;
$b = 1;
$exactIntegral = atanIntegral($b) - atanIntegral($a);
$numericIntegral = numericalIntegral($a, $b);
$error = abs($exactIntegral - $numericIntegral);
echo "∫atan(x)dx 从 $a 到 $b:\n";
echo "精确积分: " . round($exactIntegral, 6) . "\n";
echo "数值积分: " . round($numericIntegral, 6) . "\n";
echo "误差: " . sprintf("%.2e", $error) . "\n";
?>
对于任意实数 x,反正切函数 y = atan(x) 定义为:
y ∈ (-π/2, π/2) 使得 tan(y) = x
反正切是正切函数的反函数,限制在 (-π/2, π/2) 区间内。
定义域: (-∞, ∞)
值域: (-π/2, π/2) 弧度
| 场景 | 描述 | 公式/代码 |
|---|---|---|
| 角度计算 | 计算直角三角形中锐角的大小 | atan($opposite/$adjacent) |
| 抛体运动 | 计算发射角度以达到目标点 | atan(($v²±√(v⁴-g(gx²+2yv²)))/(gx)) |
| 斜坡物理 | 计算临界滑动角 | atan($friction_coefficient) |
| 复数运算 | 计算复数的辐角(相角) | atan($imag/$real) |
| 信号处理 | 计算相位差 | atan($imaginary/$real) |
atan2()函数atan2(y, x) = atan(y/x)atan(NAN)返回NAN,atan(INF)返回π/2tan()计算正切值
atan2()计算两个变量的反正切
asin()计算反正弦值
acos()计算反余弦值
deg2rad()将角度转换为弧度
rad2deg()将弧度转换为角度
atan(x):计算一个数字的反正切,返回角度在(-π/2, π/2)之间。
atan2(y, x):计算y/x的反正切,但考虑两个参数的符号来确定正确的象限,返回角度在(-π, π]之间。
主要区别:
当使用atan(y/x)时,如果x=0会出现除零错误。解决方法:
atan2(y, x)函数,它能自动处理x=0的情况if (abs($x) < 0.000001) { return $y > 0 ? M_PI_2 : ($y < 0 ? -M_PI_2 : 0); }try { $angle = atan($y/$x); } catch (DivisionByZeroError $e) { ... }atan($y/($x + 1e-15))推荐使用atan2()函数,它专门设计来处理这种情况。