将笛卡尔角度转换为R中的极坐标/指南针/基本角度?

时间:2014-04-11 16:34:59

标签: r angle polar-coordinates cartesian-coordinates

这是我遇到的一个问题,但在那里找不到好的答案。我最终在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

请注意,左下和左上象限的角度与右下象限的角度相同,失去了矢量的方向性。

3 个答案:

答案 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)]