PHP asin()函数

三角函数: asin() 函数用于计算反正弦值,返回以弧度表示的角,其正弦值等于指定数字。

asin() 函数返回一个数的反正弦值(arcsine)。参数必须在 -1 到 1 之间,返回值的范围是 -π/2 到 π/2 弧度。

函数语法

asin(float $num): float

参数说明

参数 类型 描述 必需
$num float 要计算反正弦值的数字,必须在 -1 到 1 之间(包含端点)

返回值

返回参数 $num 的反正弦值,以弧度为单位。返回值范围是 -π/2 到 π/2(约 -1.5707963267949 到 1.5707963267949)。

使用示例

示例1:基本用法 - 计算反正弦值

计算不同数字的反正弦值:

<?php
// 计算反正弦值
echo "asin(1) = " . asin(1) . " 弧度\n";        // 约 1.5707963267949 (π/2)
echo "asin(0.5) = " . asin(0.5) . " 弧度\n";    // 约 0.5235987755983 (π/6)
echo "asin(0) = " . asin(0) . " 弧度\n";        // 0
echo "asin(-0.5) = " . asin(-0.5) . " 弧度\n";  // 约 -0.5235987755983 (-π/6)
echo "asin(-1) = " . asin(-1) . " 弧度\n";      // 约 -1.5707963267949 (-π/2)

// 特殊值
echo "asin(0.70710678118655) = " . asin(0.70710678118655) . " 弧度\n";  // 约 0.78539816339745 (π/4)
echo "asin(-0.70710678118655) = " . asin(-0.70710678118655) . " 弧度\n"; // 约 -0.78539816339745 (-π/4)

// 转换弧度到角度
$radians = asin(0.5);
$degrees = rad2deg($radians);
echo "asin(0.5) = " . $radians . " 弧度 (" . $degrees . " 度)\n";

// 验证 sin(asin(x)) = x
$x = 0.75;
$asin_x = asin($x);
$sin_asin_x = sin($asin_x);
echo "验证: sin(asin(" . $x . ")) = sin(" . $asin_x . ") = " . $sin_asin_x . "\n";
echo "误差: " . abs($sin_asin_x - $x) . "\n";
?>

示例2:角度与弧度转换

在角度和弧度之间进行转换:

<?php
// 创建一个角度计算类
class AngleCalculator {
    const PI = M_PI;

    // 计算角度(度)的反正弦
    public static function asinDeg($value) {
        if ($value < -1 || $value > 1) {
            throw new InvalidArgumentException("值必须在 -1 到 1 之间");
        }
        return rad2deg(asin($value));
    }

    // 计算正弦为指定值的角度(度)
    public static function angleFromSine($sine) {
        $radians = asin($sine);
        return rad2deg($radians);
    }

    // 检查角度是否在有效范围内
    public static function isValidSine($value) {
        return $value >= -1 && $value <= 1;
    }

    // 计算反余弦对应的角度(使用反正弦关系)
    public static function angleFromArcsinArccos($x) {
        // 利用关系:arcsin(x) + arccos(x) = π/2
        if (!self::isValidSine($x)) {
            throw new InvalidArgumentException("x 必须在 -1 到 1 之间");
        }
        $arcsin = asin($x);
        $arccos = acos($x);
        return [
            'arcsin_deg' => rad2deg($arcsin),
            'arccos_deg' => rad2deg($arccos),
            'sum_deg' => rad2deg($arcsin + $arccos),
            'expected_sum' => 90
        ];
    }
}

// 使用示例
echo "常见正弦值对应的角度:\n";
$sineValues = [1, 0.8660254, 0.7071068, 0.5, 0, -0.5, -0.7071068, -0.8660254, -1];

foreach ($sineValues as $sine) {
    if (AngleCalculator::isValidSine($sine)) {
        $angle = AngleCalculator::angleFromSine($sine);
        echo "sin(θ) = " . round($sine, 4) . " → θ = " . round($angle, 2) . "°\n";
    }
}

echo "\n特殊角度:\n";
$specialAngles = [
    '0°'   => sin(deg2rad(0)),
    '30°'  => sin(deg2rad(30)),
    '45°'  => sin(deg2rad(45)),
    '60°'  => sin(deg2rad(60)),
    '90°'  => sin(deg2rad(90)),
    '-30°' => sin(deg2rad(-30)),
    '-45°' => sin(deg2rad(-45))
];

foreach ($specialAngles as $angle => $sine) {
    $calculatedAngle = round(asin($sine), 4);
    echo "sin(" . $angle . ") = " . round($sine, 4) . " → asin(" . round($sine, 4) . ") = " . $calculatedAngle . " 弧度\n";
}

echo "\n反正弦和反余弦关系验证:\n";
$testValues = [0, 0.5, 0.7071, -0.5];
foreach ($testValues as $x) {
    $result = AngleCalculator::angleFromArcsinArccos($x);
    echo "x = $x: arcsin = " . round($result['arcsin_deg'], 2) . "°, arccos = " .
         round($result['arccos_deg'], 2) . "°, 和 = " . round($result['sum_deg'], 2) .
         "° (期望: 90°)\n";
}
?>

示例3:三角形计算应用

在几何中使用asin()计算三角形角度:

<?php
// 使用正弦定理计算三角形角度
class TriangleSolver {

    // 使用正弦定理:a/sin(A) = b/sin(B) = c/sin(C)
    public static function solveBySineLaw($sideA, $sideB, $angleA) {
        // 角度必须转换为弧度
        $angleARad = deg2rad($angleA);

        // 计算角度B
        $sinB = ($sideB * sin($angleARad)) / $sideA;

        // 确保正弦值在有效范围内
        if ($sinB < -1 || $sinB > 1) {
            throw new InvalidArgumentException("无法构成三角形:sin(B) = $sinB");
        }

        $angleBRad = asin($sinB);
        $angleBDeg = rad2deg($angleBRad);

        // 可能存在两个解(钝角和锐角)
        $angleBRad2 = M_PI - $angleBRad;
        $angleBDeg2 = rad2deg($angleBRad2);

        // 计算角度C
        $angleCDeg = 180 - $angleA - $angleBDeg;
        $angleCDeg2 = 180 - $angleA - $angleBDeg2;

        // 验证三角形内角和为180度
        $valid1 = abs($angleA + $angleBDeg + $angleCDeg - 180) < 0.001;
        $valid2 = abs($angleA + $angleBDeg2 + $angleCDeg2 - 180) < 0.001;

        return [
            'solution1' => [
                'angleB' => $angleBDeg,
                'angleC' => $angleCDeg,
                'valid' => $valid1 && $angleCDeg > 0
            ],
            'solution2' => [
                'angleB' => $angleBDeg2,
                'angleC' => $angleCDeg2,
                'valid' => $valid2 && $angleCDeg2 > 0
            ]
        ];
    }

    // 已知两边和夹角求其他角度
    public static function solveByTwoSidesAndAngle($a, $b, $angleC) {
        // 角度C转换为弧度
        $angleCRad = deg2rad($angleC);

        // 计算边c(余弦定理)
        $c = sqrt($a*$a + $b*$b - 2*$a*$b*cos($angleCRad));

        // 计算角度A(正弦定理)
        $sinA = ($a * sin($angleCRad)) / $c;
        $angleARad = asin($sinA);
        $angleADeg = rad2deg($angleARad);

        // 计算角度B
        $angleBDeg = 180 - $angleC - $angleADeg;

        return [
            'sideC' => $c,
            'angleA' => $angleADeg,
            'angleB' => $angleBDeg
        ];
    }
}

// 使用示例
echo "正弦定理解三角形:\n";
try {
    $sideA = 10;
    $sideB = 8;
    $angleA = 30; // 30度

    $solutions = TriangleSolver::solveBySineLaw($sideA, $sideB, $angleA);

    echo "已知:边a = $sideA, 边b = $sideB, 角A = $angleA°\n";

    if ($solutions['solution1']['valid']) {
        echo "解1:角B = " . round($solutions['solution1']['angleB'], 2) .
             "°, 角C = " . round($solutions['solution1']['angleC'], 2) . "°\n";
    }

    if ($solutions['solution2']['valid']) {
        echo "解2:角B = " . round($solutions['solution2']['angleB'], 2) .
             "°, 角C = " . round($solutions['solution2']['angleC'], 2) . "°\n";
    }

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

echo "\n已知两边和夹角求其他元素:\n";
$a = 5;
$b = 7;
$angleC = 60; // 60度

$result = TriangleSolver::solveByTwoSidesAndAngle($a, $b, $angleC);
echo "已知:边a = $a, 边b = $b, 角C = $angleC°\n";
echo "计算结果:\n";
echo "边c = " . round($result['sideC'], 4) . "\n";
echo "角A = " . round($result['angleA'], 2) . "°\n";
echo "角B = " . round($result['angleB'], 2) . "°\n";
echo "验证内角和: " . round($angleC + $result['angleA'] + $result['angleB'], 2) . "°\n";
?>

示例4:物理和工程应用

在物理和工程问题中应用asin()函数:

<?php
// 抛体运动计算
class ProjectileMotion {

    // 计算发射角度以达到指定射程
    public static function launchAngleForRange($range, $velocity, $gravity = 9.81) {
        // 公式: range = (v² * sin(2θ)) / g
        // 因此: sin(2θ) = (range * g) / v²
        //      θ = 0.5 * asin((range * g) / v²)

        $sin2theta = ($range * $gravity) / ($velocity * $velocity);

        if (abs($sin2theta) > 1) {
            throw new InvalidArgumentException("无法达到该射程:sin(2θ) = $sin2theta");
        }

        $angleRad = 0.5 * asin($sin2theta);
        $angleDeg = rad2deg($angleRad);

        // 可能存在第二个解(互补角)
        $angleRad2 = M_PI/2 - $angleRad;
        $angleDeg2 = rad2deg($angleRad2);

        return [
            'primary' => [
                'radians' => $angleRad,
                'degrees' => $angleDeg
            ],
            'secondary' => [
                'radians' => $angleRad2,
                'degrees' => $angleDeg2
            ]
        ];
    }

    // 计算最大高度
    public static function maxHeight($velocity, $angleDeg, $gravity = 9.81) {
        $angleRad = deg2rad($angleDeg);
        $sinTheta = sin($angleRad);
        return ($velocity * $velocity * $sinTheta * $sinTheta) / (2 * $gravity);
    }
}

// 使用示例
echo "抛体运动计算:\n";
$range = 100; // 射程100米
$velocity = 30; // 初速度30m/s
$gravity = 9.81;

try {
    $angles = ProjectileMotion::launchAngleForRange($range, $velocity, $gravity);

    echo "要达到 {$range} 米射程(初速度 {$velocity} m/s):\n";
    echo "角度1: " . round($angles['primary']['degrees'], 2) . "° (" .
         round($angles['primary']['radians'], 4) . " 弧度)\n";
    echo "角度2: " . round($angles['secondary']['degrees'], 2) . "° (" .
         round($angles['secondary']['radians'], 4) . " 弧度)\n";

    // 计算两个角度的最大高度
    $height1 = ProjectileMotion::maxHeight($velocity, $angles['primary']['degrees'], $gravity);
    $height2 = ProjectileMotion::maxHeight($velocity, $angles['secondary']['degrees'], $gravity);

    echo "角度1的最大高度: " . round($height1, 2) . " 米\n";
    echo "角度2的最大高度: " . round($height2, 2) . " 米\n";

} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

// 声波和光波的折射计算
echo "\n折射定律计算:\n";
function calculateRefractionAngle($n1, $n2, $incidentAngleDeg) {
    // 斯涅尔定律: n1 * sin(θ1) = n2 * sin(θ2)
    $incidentAngleRad = deg2rad($incidentAngleDeg);
    $sinTheta2 = ($n1 / $n2) * sin($incidentAngleRad);

    if (abs($sinTheta2) > 1) {
        // 发生全反射
        return null;
    }

    $refractedAngleRad = asin($sinTheta2);
    return rad2deg($refractedAngleRad);
}

$n1 = 1.0;   // 空气折射率
$n2 = 1.33;  // 水折射率
$incidentAngle = 45; // 入射角45度

$refractedAngle = calculateRefractionAngle($n1, $n2, $incidentAngle);
if ($refractedAngle !== null) {
    echo "介质1折射率: $n1, 介质2折射率: $n2\n";
    echo "入射角: $incidentAngle°\n";
    echo "折射角: " . round($refractedAngle, 2) . "°\n";
} else {
    echo "入射角 $incidentAngle° 发生全反射\n";
}

// 计算临界角
$criticalAngleRad = asin($n2 / $n1); // 注意:当n1 > n2时才有意义
$criticalAngleDeg = rad2deg($criticalAngleRad);
echo "临界角: " . round($criticalAngleDeg, 2) . "°\n";
?>

示例5:错误处理和数值分析

处理asin()函数的错误和边界情况:

<?php
// 安全的asin函数,包含错误处理
class SafeTrigonometry {

    // 安全的asin计算
    public static function safeAsin($x) {
        // 检查输入类型
        if (!is_numeric($x)) {
            throw new InvalidArgumentException("参数必须是数字");
        }

        // 处理浮点精度误差
        $epsilon = 1e-15;

        // 检查边界条件
        if ($x < -1 || $x > 1) {
            // 如果非常接近边界(由于浮点误差)
            if (abs($x) - 1 < $epsilon && abs($x) - 1 >= 0) {
                $x = $x > 0 ? 1 : -1;
            } else {
                throw new RangeException("asin() 参数必须在 -1 到 1 之间。输入值: " . $x);
            }
        }

        // 特殊情况的精确值
        if (abs($x) < $epsilon) return 0.0; // x ≈ 0
        if (abs($x - 1) < $epsilon) return M_PI_2; // π/2
        if (abs($x + 1) < $epsilon) return -M_PI_2; // -π/2

        // 对于接近±1的值,使用泰勒展开提高精度
        if (abs($x) > 0.95) {
            return self::asinTaylor($x);
        }

        return asin($x);
    }

    // 使用泰勒展开计算asin(用于提高接近±1时的精度)
    private static function asinTaylor($x, $terms = 10) {
        $result = $x;
        $term = $x;
        $x2 = $x * $x;

        for ($n = 1; $n < $terms; $n++) {
            $term *= $x2 * (2*$n - 1) * (2*$n - 1) / (4 * $n * $n);
            $result += $term / (2*$n + 1);
        }

        return $result;
    }

    // 批量计算并验证
    public static function batchAsin(array $values) {
        $results = [];
        foreach ($values as $index => $value) {
            try {
                $result = self::safeAsin($value);
                $verification = sin($result);

                $results[$index] = [
                    'input' => $value,
                    'result' => $result,
                    'sin(result)' => $verification,
                    'error' => abs($verification - $value),
                    'status' => 'success'
                ];
            } catch (Exception $e) {
                $results[$index] = [
                    'input' => $value,
                    'result' => null,
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }
        return $results;
    }

    // 计算反余弦并比较
    public static function compareAsinAcos($x) {
        if ($x < -1 || $x > 1) {
            throw new InvalidArgumentException("x 必须在 -1 到 1 之间");
        }

        $asin = self::safeAsin($x);
        $acos = acos($x);

        return [
            'x' => $x,
            'asin' => $asin,
            'acos' => $acos,
            'asin_deg' => rad2deg($asin),
            'acos_deg' => rad2deg($acos),
            'sum_rad' => $asin + $acos,
            'sum_deg' => rad2deg($asin + $acos),
            'expected_sum' => M_PI_2
        ];
    }
}

// 测试边界条件和错误处理
echo "测试边界条件:\n";
$testCases = [
    0,           // 中间值
    0.5,         // 正常值
    1,           // 上边界
    -1,          // 下边界
    0.9999999999999999,  // 略小于1
    -0.9999999999999999, // 略大于-1
    1.0000000000000001,  // 略大于1
    -1.0000000000000001, // 略小于-1
    2,           // 超出范围
    -2,          // 超出范围
    "0.7",       // 字符串数字
    "abc",       // 无效字符串
    NAN,         // NAN
    INF          // 无穷大
];

foreach ($testCases as $testValue) {
    echo "输入: ";
    if (is_nan($testValue)) {
        echo "NAN";
    } elseif (is_infinite($testValue)) {
        echo $testValue > 0 ? "INF" : "-INF";
    } else {
        echo $testValue;
    }

    echo " => ";

    try {
        $result = SafeTrigonometry::safeAsin($testValue);

        if (is_nan($result)) {
            echo "NAN";
        } elseif (is_infinite($result)) {
            echo $result > 0 ? "INF" : "-INF";
        } else {
            echo round($result, 6);

            // 验证
            if (is_numeric($testValue) && $testValue >= -1 && $testValue <= 1) {
                $verification = sin($result);
                echo " (sin(asin(x)) = " . round($verification, 6) . ")";
            }
        }
    } catch (Exception $e) {
        echo "错误: " . $e->getMessage();
    }

    echo "\n";
}

// 批量计算示例
echo "\n批量计算示例:\n";
$values = [-1, -0.5, 0, 0.5, 1, 1.5];
$batchResults = SafeTrigonometry::batchAsin($values);

foreach ($batchResults as $index => $result) {
    echo "输入[" . $index . "] = " . $result['input'] . ": ";
    if ($result['status'] === 'success') {
        echo round($result['result'], 4);
        echo " (误差: " . number_format($result['error'], 10) . ")";
    } else {
        echo $result['message'];
    }
    echo "\n";
}

echo "\n反正弦和反余弦关系验证:\n";
$comparisonValues = [0, 0.3, 0.7071, 0.9, -0.5];
foreach ($comparisonValues as $x) {
    try {
        $comparison = SafeTrigonometry::compareAsinAcos($x);
        echo "x = " . str_pad($x, 6) . ": asin = " .
             round($comparison['asin_deg'], 2) . "°, acos = " .
             round($comparison['acos_deg'], 2) . "°, 和 = " .
             round($comparison['sum_deg'], 2) . "° (期望: 90°)\n";
    } catch (Exception $e) {
        echo "x = $x: " . $e->getMessage() . "\n";
    }
}
?>

数学原理

反正弦定义

对于任意实数 x ∈ [-1, 1],反正弦函数 y = asin(x) 定义为:

y ∈ [-π/2, π/2] 使得 sin(y) = x

反正弦是正弦函数的反函数,限制在 [-π/2, π/2] 区间内。

定义域: [-1, 1]

值域: [-π/2, π/2] 弧度

重要性质
  • 奇函数:asin(-x) = -asin(x)
  • 单调性:在定义域内单调递增
  • 导数:d/dx asin(x) = 1/√(1-x²)
  • 积分:∫asin(x)dx = x·asin(x) + √(1-x²) + C
  • 关系式:asin(x) + acos(x) = π/2

应用场景

场景 描述 公式/代码
三角形计算 已知对边和斜边求角度 asin($opposite/$hypotenuse)
抛体运动 计算发射角度以达到指定射程 0.5 * asin(($range*$g)/$v²)
光学折射 计算折射角(斯涅尔定律) asin(($n1/$n2)*sin($θ1))
信号处理 计算相位差 asin($imaginary/$amplitude)
机器人学 计算关节角度 asin($height/$length)

注意事项

重要提醒
  • 参数范围:参数必须在 -1 到 1 之间,超出范围会返回 NAN
  • 浮点精度:由于浮点数精度限制,接近 ±1 的值可能产生微小误差
  • 返回值单位:返回值以弧度为单位,不是角度
  • 特殊值:asin(NAN) 返回 NANasin(INF) 返回 NAN
  • 奇函数性质:asin(-x) = -asin(x),可以利用这一性质简化计算

相关函数

sin()

计算正弦值

acos()

计算反余弦值

atan()

计算反正切值

atan2()

计算两个变量的反正切

deg2rad()

将角度转换为弧度

rad2deg()

将弧度转换为角度

常见问题

因为正弦函数的输出范围就是[-1, 1]。对于任何角度θ,sin(θ)的值都在这个范围内。asin()作为反函数,其输入(原函数的输出)自然也必须在这个范围内。超出这个范围的值没有对应的角度满足sin(θ)=x,因此asin()无法计算。

这是反正弦函数的主值范围。正弦函数在[-π/2, π/2]区间内是单调的(从-1递增到1),因此在这个区间内定义的反函数是单值的。选择[-π/2, π/2]作为主值范围是数学上的标准约定,这样asin()函数对于每个输入都有唯一确定的输出,并且保持了奇函数的性质。

正弦函数是周期函数,每个y值对应无限多个x值。asin()通过限制值域到[-π/2, π/2]来解决多值性问题:

  1. 主值:使用asin()得到主值(-π/2到π/2之间)
  2. 其他解:如果需要其他解,可以利用正弦函数的周期性:
    • 第二象限解:π - asin(x)
    • 通解:(-1)ⁿ·asin(x) + nπ(n为整数)
  3. 实际应用:在物理和工程中,通常根据具体情况选择适当的解