簡體   English   中英

R:將笛卡爾坐標轉換為極坐標,然后計算距原點的距離

[英]R: Converting cartesian coordinates to polar coordinates, and then calculating distance from origin

我一直在尋找將笛卡爾坐標(緯度,經度)轉換為極坐標的解決方案,以促進我想要運行的模擬,但我在這里沒有找到任何問題或答案R. 有很多選項,包括 Matlab 中的內置函數 car2pol,但我所有的數據都在 R 中,我想繼續在這個框架中工作。

問題:

我有來自標記數據的緯度/經度坐標,我想將它們轉換為極坐標(意思是跳躍大小和角度: http : //en.wikipedia.org/wiki/Polar_coordinate_system ),這樣我就可以洗牌或引導它們(還沒有決定哪個)大約1000次,並計算每個模擬軌跡從起點的直線距離。 我有一個真實的軌跡,我有興趣通過模擬 1,000 條具有相同跳躍大小和轉彎角度但順序和組合完全不同的隨機軌跡來確定這種動物是否表現出場地親和力。 所以我需要與原點相距 1,000 條直線距離來創建距離分布,然后將其與我的真實數據集的直線距離進行比較。

我很樂意進行引導,但我堅持第一步,即將我的笛卡爾緯度/經度坐標轉換為極坐標(跳躍大小和轉彎角度)。 我知道在其他程序(例如 Matlab)中有內置函數可以執行此操作,但是我找不到在 R 中執行此操作的任何方法。我可以在 for 循環中手動執行此操作,但是如果有一個包有或任何更簡單的方法來做到這一點,我更喜歡那個。

理想情況下,我想將數據轉換為極坐標,運行模擬,然后為每個隨機軌跡輸出一個端點作為笛卡爾坐標,緯度/經度,這樣我就可以計算直線距離。

我沒有發布任何示例數據,因為它只是一個經緯度坐標的兩列數據框。

感謝您的任何幫助,您可以提供! 如果本網站或其他網站上的某處有一個簡單的解釋,我錯過了,請指出那個方向! 我找不到任何東西。

干杯

對於單位相同的 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)

在此處輸入圖片說明

由於它相當簡單,您可以編寫自己的函數。 R中類似Matlab的cart2pol函數:

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

  c(r,t)
}

我使用了 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,很少有向后的步驟來降低值。 這不是我的經緯度數據所做的,如果我正確計算了 car->pol 和 pol->cart,這些來自 N 的新值應該與我的緯度/經度數據匹配,只是在不同的坐標系中。 這是繪制的 N 值的樣子:

反向轉換的笛卡爾坐標

完全不一樣... N中的最后一點是離原點最遠的點,而在我的緯度/經度數據中,最后一點實際上離第一點很近,絕對不是最遠的點。 我認為問題一定出在我從極坐標轉換回笛卡爾坐標的過程中,但我不確定如何解決它...

任何幫助解決這個問題將不勝感激!

干杯

我認為我寫的這段代碼轉換為極坐標:

# 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

我認為您可以通過這種方式在 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))
}

僅在學位上的另一種選擇

pol2car = function(angle, dist){
    co = dist*sin(angle)
    ca = dist*cos(angle)
    return(list(x=ca, y=co))
}
pol2car(angle = 45, dist = sqrt(2))

car2sph {pracma} 在二維和三維的笛卡爾坐標系、球坐標系、極坐標系和圓柱坐標系之間進行轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM