fortran fortran中文资料网
手气不错
Article

051.inverseTrig_反三角函数与象限角

asinacosatanatan2是Fortran标准定义的泛型、元素内在函数,用于由三角函数值或坐标分量反求角度。本文讨论实数参数:结果以弧度表示,且kind跟随参数。它们常用于几何测量、姿态计算和二维向量定向;已知直角三角形边长比时适合使用asinacosatan,已知向量的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°方向。

核心知识点

  • asinacosatan返回各自约定范围内的主值,并不能恢复三角函数所有可能的原角。
  • 实数asinacos要求参数位于[-1,1];超出定义域会产生无效浮点结果。
  • atan(y/x)只保留分量比,既可能除以零,也无法区分相差π的方向。
  • atan2(y,x)保留两个分量的符号并正确判断象限,是由笛卡尔坐标计算二维方向角的首选形式,但(0,0)没有确定方向。
  • 反三角函数返回弧度,角度制输出需要显式乘以180/π。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注