如何轻松地将线角转换为导航方位比例尺(即,范围为 [0,360] 且 "North" = 0 度)?

How do I easily convert a line angle to a navigational-bearing scale (i.e., with range of [0,360) and "North" = 0 deg)?

我有两点,(x1,y1)(x2,y2),我想在它们之间画一条线。我知道我可以使用反正切和斜率计算出该线的角度(以度为单位):

atan((y2-y1)/(x2-x1))*180/pi

但是,如何将这个角度转换为 [0,360] 比例?基本上,我希望我的角度在罗盘刻度上,其中 "North" 是 0 度,"East" 是 90 度,"South" 是 180 度,"West" 是 270 度.

谢谢!

(450-atan2(y2-y1,x2-x1)*180/pi)%%360​​​​​​​​​​​​​​​

segmentToAngle <- function(x1,y1,x2,y2) atan2(y2-y1,x2-x1)*180/pi;
segmentToAngle(0,0,1,0); ## east
## [1] 0
segmentToAngle(0,0,0,1); ## north
## [1] 90
segmentToAngle(0,0,-1,0); ## west
## [1] 180
segmentToAngle(0,0,0,-1); ## south
## [1] -90
segmentToCompassAngle <- function(x1,y1,x2,y2) (450-segmentToAngle(x1,y1,x2,y2))%%360;
segmentToCompassAngle(0,0,1,0); ## east
## [1] 90
segmentToCompassAngle(0,0,0,1); ## north
## [1] 0
segmentToCompassAngle(0,0,-1,0); ## west
## [1] 270
segmentToCompassAngle(0,0,0,-1); ## south
## [1] 180

只是为了概括@bgoldst 的回答:

(A1 - atan2(y2-y1,x2-x1) * 180/pi ) %%360

下面是对这个等式各个部分的解释:

  1. 您必须使用 atan2() 而不是 atan()

    atan2() 是有两个参数的反正切函数。使用两个参数的目的是收集有关输入符号的信息,以便 return 计算角度的适当象限。这对于单参数反正切 (atan) 函数是不可能的。

  2. 在这种情况下使用模数运算符 %% 来给出角度除以 360 的余数。这样,​​我们强制角度在 360 处“环绕”。

  3. 将使用 atan2 计算的角度乘以 180/pi,以便将答案从弧度(atan2 的默认输出)转换为度数。

  4. 如果我们到此为止,生成的角度将基于标准三角函数形式,其中“东”= 0 度。所有角度都相对于“东”= 0。

    通过从某个角度 (A1) 中减去我们计算的角度(以度为单位),我们可以将计算的角度偏移 A1 度。在航海方位角(“北”= 0度)的情况下,我们将设置A1 = 90

     (90 - atan2(y2-y1,x2-x1) * 180/pi ) %%360
    

对于"North" 0 度。 "East" 90 度。 "South" 180 度。和 "West" 270 度

您可以使用公式:

f(E,N)=180-90*(1+sign(N))* (1-sign(E)^2)-45*(2+sign(N))*sign(E )

     -180/pi()*sign(E*N)*atan((abs(N)-abs(E))/(abs(N)+abs(E)))

      E=E2-E1 and  N=N2-N1

我不想诋毁这里以数学为中心的讨论。但是,您说的是 导航方位 。据我推测,您的重点是 导航 := 应用数学来完成导航任务(我个人的定义)。

'geosphere package' 将在这方面对您有很大帮助。它提供了一组 geo / nav 函数(用于球形计算)。要从一个点 p1 移动到另一个 p2,函数 'geosphere::bearing()' 或 'geosphere::bearingRhumb()' 将为您提供以度数表示的方位角方向,即 -180 ... +180。 您可以在 answer to this related question.

中找到更多解释

正如@theforestecologist 所指出的那样,以下内容将使用取模方法来确定超出整圆(即 360 度)的任何角度数学的 rest。 模运算符为您提供模数基础之上的其余部分(在我们的例子中为 360)。这解决了方位角的负号问题。例如

  • -90 + 360 = 270 ==> 270 %% 360 := (0 * 360) + 270 = 270
  • 30 + 360 = 30 ==> 30 %% 360 := (0 * 360) + 30 = 30
  • 对于数学纯粹主义者重新取模,可以添加任意数量的完整圆圈,例如2* 360 度 = 720。这将产生:-30 + 720 = 690 ==> 690 %% 360 := (1 * 360) + 330 = 330

在 R/RStudio 中使用以下内容并加载 geoshere 程序包。请注意,geosphere 包使用 x-y 位置概念,即经度在纬度之前,而不是纬度在经度之前的导航实践(例如 43N 3E)!

brg <- geosphere::bearing(c(p1_lon, p1_lat), c(p2_lon, p2_lat))
crs <- (brg + 360) %% 360  # to generate 0...360 courses

注意 2:如果您处理多个点对点关系。使用 cbind():

将它们重新编码为矩阵
brg <- geosphere::bearing(cbind(p1_lon, p1_lat), cbind(p2_lon, p2_lat))