asin、acos、atan和atan2是Fortran标准定义的泛型、元素内在函数,用于由三角函数值或坐标分量反求角度。本文讨论实数参数:结果以弧度表示,且kind跟随参数。它们常用于几何测量、姿态计算和二维向量定向;已知直角三角形边长比时适合使用asin、acos或atan,已知向量的x、y分量并且需要保留象限信息时应使用atan2。
语法结构
angle = asin(x)
angle = acos(x)
angle = atan(x)
angle = atan2(y, x)
- 实数asin(x)和acos(x)要求x位于[-1,1]。前者返回[-π/2,π/2]内的角,后者返回[0,π]内的角。
- 实数atan(x)接收正切值,只能返回-π/2到π/2之间的主值;仅有比值时无法判断原始方向属于相差π的哪一个象限。
- atan2(y,x)按y在前、x在后的顺序接收两个实数分量,利用二者的符号确定象限,返回-π到π范围内的方向角;x和y不能同时为零。
- 这些函数返回弧度。需要角度制显示时,可将结果乘以180/π;这只是单位换算,不会改变函数的计算规则。
应用模型
一段斜坡的升高、水平距离和斜边长度分别为3、4、5。斜坡角θ既可由sin(θ)=3/5反求,也可由cos(θ)=4/5或tan(θ)=3/4反求。对于平面方向向量,西北方向(-4,4)与东南方向(4,-4)都有y/x=-1;只计算atan(-1)会丢失x、y各自的符号,而atan2(y,x)能够区分两个方向。
本文代码
! 用反三角函数求斜坡角,并比较ATAN与ATAN2对方向象限的处理。
program inverseTrigDemo
use iso_fortran_env, only: real64
implicit none
real(real64), parameter :: pi = acos(-1.0_real64)
real(real64), parameter :: radToDegree = 180.0_real64 / pi
real(real64) :: rise, run, rampLength
real(real64) :: angleFromAsin, angleFromAcos, angleFromAtan
real(real64) :: xNorthwest, yNorthwest, xSoutheast, ySoutheast
rise = 3.0_real64
run = 4.0_real64
rampLength = 5.0_real64
angleFromAsin = asin(rise / rampLength)
angleFromAcos = acos(run / rampLength)
angleFromAtan = atan(rise / run)
xNorthwest = -4.0_real64
yNorthwest = 4.0_real64
xSoutheast = 4.0_real64
ySoutheast = -4.0_real64
print "(A,F8.3,1X,A)", "ASIN求斜坡角:", angleFromAsin * radToDegree, "deg"
print "(A,F8.3,1X,A)", "ACOS求斜坡角:", angleFromAcos * radToDegree, "deg"
print "(A,F8.3,1X,A)", "ATAN求斜坡角:", angleFromAtan * radToDegree, "deg"
print "(A,F8.3,1X,A)", "西北向量的ATAN角:", &
atan(yNorthwest / xNorthwest) * radToDegree, "deg"
print "(A,F8.3,1X,A)", "西北向量的ATAN2角:", &
atan2(yNorthwest, xNorthwest) * radToDegree, "deg"
print "(A,F8.3,1X,A)", "东南向量的ATAN角:", &
atan(ySoutheast / xSoutheast) * radToDegree, "deg"
print "(A,F8.3,1X,A)", "东南向量的ATAN2角:", &
atan2(ySoutheast, xSoutheast) * radToDegree, "deg"
end program inverseTrigDemo
编译运行
(base) hong@hongdeMacBook-Pro 051.inverseTrig % gfortran -Wall -Wextra -std=f2018 exampleInverseTrig.f90 -o inverseTrigDemo
(base) hong@hongdeMacBook-Pro 051.inverseTrig % ./inverseTrigDemo
ASIN求斜坡角: 36.870 deg
ACOS求斜坡角: 36.870 deg
ATAN求斜坡角: 36.870 deg
西北向量的ATAN角: -45.000 deg
西北向量的ATAN2角: 135.000 deg
东南向量的ATAN角: -45.000 deg
东南向量的ATAN2角: -45.000 deg
现象分析
斜坡的三个边长比依次为3/5=0.6、4/5=0.8和3/4=0.75。asin(0.6)、acos(0.8)与atan(0.75)都得到约0.643501109弧度,乘以180/π后均为36.8698976°,按三位小数显示为36.870°。三种方法一致,是因为它们描述同一个3-4-5直角三角形中的锐角。
西北向量(-4,4)的分量比为4/(-4)=-1,东南向量(4,-4)的分量比也为-4/4=-1。因此两次atan(y/x)收到完全相同的参数,只能返回相同的主值-π/4,即-45°。除法把两组分量压缩成一个比值,同时丢掉了x、y各自的符号,程序无法再从-1判断原向量位于第二象限还是第四象限。
atan2直接接收两个分量。对于(-4,4),x<0且y>0,方向位于第二象限,结果为3π/4=135°;对于(4,-4),x>0且y<0,方向位于第四象限,结果为-π/4=-45°。它还避免了先计算y/x,因此在x=0、y不为零时仍可表示正负90°方向。
核心知识点
- asin、acos和atan返回各自约定范围内的主值,并不能恢复三角函数所有可能的原角。
- 实数asin和acos要求参数位于[-1,1];超出定义域会产生无效浮点结果。
- atan(y/x)只保留分量比,既可能除以零,也无法区分相差π的方向。
- atan2(y,x)保留两个分量的符号并正确判断象限,是由笛卡尔坐标计算二维方向角的首选形式,但(0,0)没有确定方向。
- 反三角函数返回弧度,角度制输出需要显式乘以180/π。