8

我一直在寻找一种解决方案,将我必须的笛卡尔坐标(纬度,经度)转换为极坐标,以促进我想要运行的模拟,但我在这里没有找到任何问题或答案R. 有很多选项,包括 Matlab 中的内置函数 cart2pol,但我所有的数据都在 R 中,我想继续在这个框架中工作。

问题:

我有来自标记数据的纬度/经度坐标,我想将它们转换为极坐标(意思是跳跃大小和角度:http ://en.wikipedia.org/wiki/Polar_coordinate_system ),以便我可以随机播放或引导它们(还没有决定)大约1000次,并计算每个模拟轨道到起点的直线距离。我有一条真实的轨迹,我有兴趣通过模拟 1,000 个具有相同跳跃大小和转弯角度但顺序和组合完全不同的随机轨迹来确定这种动物是否表现出站点亲和力。所以我需要距离原点 1,000 个直线距离来创建距离分布,然后将其与我的真实数据集的直线距离进行比较。

我很乐意做引导,但我被困在第一步,将我的笛卡尔纬度/经度坐标转换为极坐标(跳跃大小和转动角度)。我知道在其他程序(例如 Matlab)中有内置函数可以执行此操作,但我在 R 中找不到任何方法来执行此操作。我可以在 for 循环中手动执行此操作,但如果有包输出那里或任何更简单的方法来做到这一点,我更喜欢那个。

理想情况下,我想将数据转换为极坐标,运行模拟,然后为每个随机轨道输出一个终点作为笛卡尔坐标,纬度/经度,这样我就可以计算直线距离。

我没有发布任何示例数据,因为它只是一个经纬度坐标的两列数据框。

感谢您的任何帮助,您可以提供!如果本网站某处或我错过的其他地方有简单的解释,请指出我的方向!我什么也找不到。

干杯

4

7 回答 7

7

对于相同单位的 xy 坐标(例如米而不是纬度和经度),您可以使用此函数来获取跳跃大小和转动角度(以度为单位)的 data.frame。

getSteps <- function(x,y) {
    d <- diff(complex(real = x, imaginary = y))
    data.frame(size = Mod(d), 
               angle = c(NA, diff(Arg(d)) %% (2*pi)) * 360/(2*pi))
}

## Try it out   
set.seed(1)
x <- rnorm(10)
y <- rnorm(10)
getSteps(x, y)
#        size     angle
# 1 1.3838360        NA
# 2 1.4356900 278.93771
# 3 2.9066189 101.98625
# 4 3.5714584 144.00231
# 5 1.6404354 114.73369
# 6 1.3082132 135.76778
# 7 0.9922699  74.09479
# 8 0.2036045 141.67541
# 9 0.9100189 337.43632

## A plot helps check that this works
plot(x, y, type = "n", asp = 1)
text(x, y, labels = 1:10)

在此处输入图像描述

于 2013-05-03T04:52:44.873 回答
2

由于它相当简单,您可以编写自己的函数。R中的类似Matlab的cart2pol函数:

cart2pol <- function(x, y)
{
  r <- sqrt(x^2 + y^2)
  t <- atan(y/x)

  c(r,t)
}
于 2013-05-03T04:31:29.027 回答
1

我使用了 Josh O'Brien 的代码,得到了看似合理的跳跃和角度——它们非常适合目测粗略的距离和点之间的航向。然后,我使用他建议中的公式创建一个将极坐标转换回笛卡尔坐标的函数,并使用一个 for 循环将该函数应用于所有极坐标的数据框。循环似乎工作,输出的单位正确,但我不相信它输出的值与我的数据相对应。所以要么我的公式计算错误,要么发生了其他事情。更多详情如下:

这是我的经纬度数据的头部:

> head(Tag1SSM[,3:4])
       lon       lat
1 130.7940 -2.647957
2 130.7873 -2.602994
3 130.7697 -2.565903
4 130.7579 -2.520757
5 130.6911 -2.704841
6 130.7301 -2.752182

当我将整个数据集绘制为值时,我得到了这个图: 经纬图

这看起来与我使用 R 中的任何空间或映射包绘制它完全相同。

然后我使用 Josh 的函数将我的数据转换为极坐标:

x<-Tag1SSM$lon
y<-Tag1SSM$lat

getSteps <- function(x,y) {
  d <- diff(complex(real = x, imaginary = y))
  data.frame(size = Mod(d), 
             angle = c(NA, diff(Arg(d)) %% (2*pi)) * 360/(2*pi))
}

它适当地产生了以下极坐标:

> polcoords<-getSteps(x,y)
> head(polcoords)
        size     angle
1 0.04545627        NA
2 0.04103718  16.88852
3 0.04667590 349.38153
4 0.19581350 145.35439
5 0.06130271  59.37629
6 0.01619242  31.86359

同样,这些在我看来是正确的,并且很好地对应于点之间的实际角度和相对距离。到目前为止,一切都很好。

现在我想将这些转换回笛卡尔坐标并计算到原点的欧几里得距离。这些不必是真正的纬度/经度,因为我只是在它们之间进行比较。因此,我很高兴将原点设置为 (0,0) 并以参考 x,y 值而不是公里或类似的值计算距离。

因此,我在 Josh 的帮助和一些网络搜索下使用了这个功能:

polar2cart<-function(x,y,size,angle){

  #convert degrees to radians (dividing by 360/2*pi, or multiplying by pi/180)
  angle=angle*pi/180
  if(is.na(x)) {x=0} #this is for the purpose of the for loop below
  if(is.na(y)) {y=0}
  newx<-x+size*sin(angle)  ##X #this is how you convert back to cartesian coordinates
  newy<-y+size*cos(angle)  ##Y
  return(c("x"=newx,"y"=newy)) #output the new x and y coordinates
}

然后将其插入此 for 循环:

u<-polcoords$size
v<-polcoords$angle
n<-162 #I want 162 new coordinates, starting from 0
N<-cbind(rep(NA,163),rep(NA,163)) #need to make 163 rows, though, for i+1 command below— first row will be NA
for(i in 1:n){
  jump<-polar2cart(N[i,1],N[i,2],u[i+1],v[i+1]) #use polar2cart function above, jump from previous coordinate in N vector 
  N[i+1,1]<-jump[1] #N[1,] will be NA's which sets the starting point to 0,0—new coords are then calculated from each previous N entry
  N[i+1,2]<-jump[2]
  Dist<-sqrt((N[163,1]^2)+(N[163,2]^2)) 
}

然后我可以看看 N,我的新坐标基于这些跳跃:

> N
               [,1]        [,2]
  [1,]           NA          NA
  [2,]  0.011921732  0.03926732
  [3,]  0.003320851  0.08514394
  [4,]  0.114640605 -0.07594871
  [5,]  0.167393509 -0.04472125
  [6,]  0.175941466 -0.03096891

这就是问题所在......来自 N 的 x,y 坐标逐渐变大——那里有一点变化,但如果你向下滚动列表,y 从 0.39 变为 11.133,几乎没有向后降低的步骤价值观。这不是我的 lat/long 数据所做的,如果我正确计算了 cart->pol 和 pol->cart,那么来自 N 的这些新值应该与我的 lat/long 数据匹配,只是在不同的坐标系中。这是 N 值绘制的样子:

反向转换的笛卡尔坐标

完全不一样... N 中的最后一个点是离原点最远的点,而在我的经纬度数据中,最后一个点实际上非常接近第一个点,而且绝对不是最远的点。我认为问题一定是我从极坐标转换回笛卡尔坐标,但我不知道如何解决它......

任何解决此问题的帮助将不胜感激!

干杯

于 2013-05-03T19:20:33.967 回答
1

我认为我编写的这段代码转换为极坐标:

# example data
x<-runif(30)
y<-runif(30)
# center example around 0
x<-x-mean(x)
y<-y-mean(y)

# function to convert to polar coordinates
topolar<-function(x,y){

    # calculate angles 
    alphas<-atan(y/x)

    # correct angles per quadrant
    quad2<-which(x<0&y>0)
    quad3<-which(x<0&y<0)
    quad4<-which(x>0&y<0)
    alphas[quad2]<-alphas[quad2]+pi
    alphas[quad3]<-alphas[quad3]+pi
    alphas[quad4]<-alphas[quad4]+2*pi

    # calculate distances to 0,0
    r<-sqrt(x^2+y^2)

    # create output
    polar<-data.frame(alphas=alphas,r=r)

}

# call function
polar_out<-topolar(x,y)
# get out angles
the_angles<-polar_out$alphas
于 2019-05-29T09:32:26.027 回答
1

我认为您可以通过这种方式在 catesian 和 polar 之间进行转换:

polar2cart <- function(r, theta) {
  data.frame(x = r * cos(theta), y = r * sin(theta))
}

cart2polar <- function(x, y) {
  data.frame(r = sqrt(x^2 + y^2), theta = atan2(y, x))
}
于 2020-12-24T12:49:20.417 回答
0

仅在学位上的另一种选择

pol2car = function(angle, dist){
    co = dist*sin(angle)
    ca = dist*cos(angle)
    return(list(x=ca, y=co))
}
pol2car(angle = 45, dist = sqrt(2))
于 2016-08-18T22:29:06.383 回答
0

cart2sph {pracma} 在二维和三维的笛卡尔坐标系、球坐标系、极坐标系和柱坐标系之间转换。

于 2021-03-26T15:00:35.767 回答