这是我遇到的一个问题,但在那里找不到好的答案。我最终在R中解决了这个问题,但我想如果其他人需要它我会发布它。如果有人有更优雅的解决方案,我很乐意看到它。这是一种蛮力的努力。
我有一系列成对的XY(笛卡尔坐标)坐标。我可以使用简单的atan()命令轻松获取它们之间的角度。但是,我想要指南针(极地?基数?)方向的角度(北= 0°,东= 90°,等等)。这是制作数据和笛卡尔角度的最小例子,我已经将我的蛮力转换发布到下面的罗盘角度。度转换(从弧度)使用'圆形'包中的deg()。
require(circular)
test <- data.frame(x=c(0,1,1,1,0,-1,-1,-1),y=c(1,1,0,-1,-1,-1,0,1))
test$angle <- deg(atan(test$y/test$x))
test
...产生
x y angle
1 0 1 90
2 1 1 45
3 1 0 0
4 1 -1 -45
5 0 -1 -90
6 -1 -1 45
7 -1 0 0
8 -1 1 -45
请注意,左下和左上象限的角度与右下象限的角度相同,失去了矢量的方向性。
答案 0 :(得分:2)
ang <- function(x,y) {
z <- x + 1i * y
res <- 90 - Arg(z) / pi * 180
res %% 360
}
ang(test$x, test$y)
#[1] 0 45 90 135 180 225 270 315
答案 1 :(得分:1)
首先,通过减去90度(感谢JK)改变代码的角度线,可以轻松地将角度移动到y轴的测量角度(或North = 0):
test$angle <- 90-deg(atan(test$y/test$x))
然而,需要保持左边向量的转换,因此根据X和Y值的符号调整这些角度是我的解决方案:
# Make new column for the polar/compass angles
test$polar <- test$angle
# Then make the necessary adjustments
# Adjustment for quadrant C (bottom left, 180 to 270°)
test[sign(test$x)==-1 & sign(test$y)==-1,"polar"] <- ((1-(test[sign(test$x)==-1 & sign(test$y)==-1,"angle"]/90))*90)+180
# Adjustment for quadrant D (top left, 270 to 360°)
test[sign(test$x)==-1 & sign(test$y)>=0, "polar"] <- abs(test[sign(test$x)==-1 & sign(test$y)>=0,"angle"])+180
...产生:
x y angle polar
1 0 1 0 0
2 1 1 45 45
3 1 0 90 90
4 1 -1 135 135
5 0 -1 180 180
6 -1 -1 45 225
7 -1 0 90 270
8 -1 1 135 315
同样,我将此作为一个有效的解决方案发布,但更优雅或更简单的建议也将受到赞赏!
答案 2 :(得分:0)
它全是线性的。有两个困难:增加角度的方向是笛卡尔系统中的CCW,导航系统中的CW,以及0°笛卡尔在图表上是90°。我们可以通过改变符号来解决第一个问题:N&lt; = -C。
现在0映射到0.我们希望0映射到90,所以只需添加90:N&lt; = -C + 90。
但是,哎呀,这给了我们一些超出正常范围0-360的角度。但是,角度重复mod 360,所以我们可以很容易地解决这个问题:N&lt; = -c + 90 modulo 360.
模数运算符不同意如何处理负数,所以为了安全起见,先添加360以消除问题:N&lt; =(-C + 90 + 360)modulo 360。
在Excel,MOD(450 - C,360)或javascript中,((450 - C))%360。恐怕我不知道R. [但在Fortran IV中,它将是FN = mod(450.0 - C,360.0)]