【问题标题】:How to procedurally calculate angles between a great number of vectors?如何在程序上计算大量向量之间的角度?
【发布时间】:2020-02-03 13:57:44
【问题描述】:

我有 4 个向量,它们的坐标在不同的时间步长。

lon <- list(505997.627175236, 505997.627175236, 505997.627175236, 505997.627175236, 505997.064187932, 505997.814896096,
          505997.843587834, 505997.880929633, 505996.906012923, 505998.486599226, 505998.075906002, 505998.079921271)   
lon <- do.call(rbind.data.frame, lon)

lat <- list(7941821.025438220, 7941821.025438220, 7941821.025438220, 7941821.025438220, 7941819.791667340, 7941821.329316000,
            7941821.741379530, 7941821.171989530, 7941819.103811300, 7941821.831421200, 7941822.024924560, 7941822.110412460)
lat <- do.call(rbind.data.frame, lat)

step <- list(1,1,1,1,2,2,2,2,3,3,3,3)
step <- do.call(rbind.data.frame, step)

allbuff <- cbind(lon, lat, step)
colnames(allbuff) <- c("lon", "lat", "STEP")

我使用以下脚本计算了 step、step+1、...、step+n 处的四个向量之间的角度:

M_PI <- 3.14159265359

output_angle = NULL

for (i in unique(allbuff$STEP)) {

  select = allbuff[allbuff$STEP == i, 1:2]

  result1 = atan2((select[1,2] - select[2,2]), (select[1,1] - select[2,1]))*(180/M_PI) # between 1 & 2
  result2 = atan2((select[1,2] - select[3,2]), (select[1,1] - select[3,1]))*(180/M_PI) # between 1 & 3
  result3 = atan2((select[1,2] - select[4,2]), (select[1,1] - select[4,1]))*(180/M_PI) # between 1 & 4
  result4 = atan2((select[2,2] - select[3,2]), (select[2,1] - select[3,1]))*(180/M_PI) # between 2 & 3
  result5 = atan2((select[2,2] - select[4,2]), (select[2,1] - select[4,1]))*(180/M_PI) # between 2 & 4
  result6 = atan2((select[3,2] - select[4,2]), (select[3,1] - select[4,1]))*(180/M_PI) # between 3 & 4

  result <- rbind(result1,result2,result3,result4,result5,result6)
  STEP <- c(i,i)
  result <- cbind(result, as.data.frame(STEP))

  output_angle = rbind(output_angle,result)

}

output_angle <- as.data.frame(output_angle)

用少量向量编码但用 1000 个向量编码是有效的,而且不会太长,这种编码方式可能非常耗时。

因此,无论输入中的向量数量是多少,是否有一种更有效的方法(从程序上讲)来计算 步骤 n 中所有向量之间的角度?

【问题讨论】:

    标签: r vector angle procedural


    【解决方案1】:

    也许下面的基本 R 代码会有所帮助

    dfout <- do.call(rbind,
                     c(make.row.names = F,
                       lapply(split(allbuff,allbuff$STEP), function(v) 
                         data.frame(result = combn(nrow(v),2,function(k) atan2(diff(v[rev(k),2]),diff(v[rev(k),1])) )*(180/M_PI),
                                    STEP = unique(v[3]),
                                    row.names = NULL))))
    

    你会得到

    > dfout
           result STEP
    1     0.00000    1
    2     0.00000    1
    3     0.00000    1
    4     0.00000    1
    5     0.00000    1
    6     0.00000    1
    7  -116.02248    2
    8  -111.78912    2
    9  -120.61296    2
    10  -93.98304    2
    11  112.76891    2
    12   93.75220    2
    13 -120.09129    3
    14 -111.82589    3
    15 -111.32784    3
    16  -25.22807    3
    17  -34.45110    3
    18  -92.68914    3
    

    【讨论】:

    • 谢谢托马斯。您的代码完美运行。 “combn”功能确实很方便。不过,在高效编码之前,我还有很长的路要走。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    相关资源
    最近更新 更多