如何轻松地将线角转换为导航方位比例尺(即,范围为 [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
下面是对这个等式各个部分的解释:
您必须使用 atan2()
而不是 atan()
。
atan2()
是有两个参数的反正切函数。使用两个参数的目的是收集有关输入符号的信息,以便 return 计算角度的适当象限。这对于单参数反正切 (atan
) 函数是不可能的。
在这种情况下使用模数运算符 %%
来给出角度除以 360 的余数。这样,我们强制角度在 360 处“环绕”。
将使用 atan2
计算的角度乘以 180/pi
,以便将答案从弧度(atan2 的默认输出)转换为度数。
如果我们到此为止,生成的角度将基于标准三角函数形式,其中“东”= 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))
我有两点,(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
下面是对这个等式各个部分的解释:
您必须使用
atan2()
而不是atan()
。atan2()
是有两个参数的反正切函数。使用两个参数的目的是收集有关输入符号的信息,以便 return 计算角度的适当象限。这对于单参数反正切 (atan
) 函数是不可能的。在这种情况下使用模数运算符
%%
来给出角度除以 360 的余数。这样,我们强制角度在 360 处“环绕”。将使用
atan2
计算的角度乘以180/pi
,以便将答案从弧度(atan2 的默认输出)转换为度数。如果我们到此为止,生成的角度将基于标准三角函数形式,其中“东”= 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))