使用方螺旋算法

时间:2015-05-22 17:27:24

标签: r

我有一个像这样的data.frame:

        X1       X2 n
1 -80.3845 43.19402 4
2 -80.3845 43.19402 4
3 -80.3845 43.19402 4
4 -80.3845 43.19402 4

您会注意到每个变量中的值都是相同的。我尝试做的是创建一个新的数据帧,调整后使变量X1和X2不重叠。我需要它们有0.1的差异。最终的数据框应如下所示:

        X1       X2 n
1 -80.3845 43.19402 4
2 -80.3845 43.29402 4
3 -80.2845 43.29402 4
4 -80.2845 43.19402 4

此图表可能有助于表示发生了什么:

enter image description here

值代表经度和纬度,我保留了第一个点,然后向上移动了一个位置,然后向右移动了一个位置,然后向下移动了一个位置到第4个位置。

手动操作几行非常容易,但是当我们添加更多点时,它会变得更复杂。对于任何' n'第一行将保持相同的值,行将以顺时针方式绕过。因此,对于8行,它看起来像这样:

        X1       X2 n
1 -80.3845 43.19402 8
2 -80.3845 43.29402 8
3 -80.2845 43.29402 8
4 -80.2845 43.19402 8
5 -80.2845 43.09402 8
6 -80.3845 43.09402 8
7 -80.4845 43.09402 8
8 -80.4845 43.19402 8

最高数量的' n'我将有大约400.我的思考过程是我应该尝试预先计算1-400中每个数字的位置,如上图所示。即它们是...... -3,-2,-1,0,1,2,3,...行/列远离中心点。然后使用它来计算X1中的调整值(可以认为是列的坐标)和X2(可以认为是行的坐标)。

有人能想到更好的方法吗?

1 个答案:

答案 0 :(得分:1)

这是一个简单的循环:

get_spiral <- function(orig,incr,n){

  ng   <- ceiling(sqrt(n))
  myg  <- -floor((ng-1)/2):ceiling((ng-1)/2)
  x0   <- which(myg==0)
  y0   <- which(myg==0)

  vecs <- lapply(orig,`+`,myg*incr)
  res  <- matrix(,n,2)

  x    <- 0
  y    <- 0
  goin <- "up"
  ring <- 0
  for (i in 1:n){
    res[i,] <- c(vecs[[1]][x0+x],vecs[[2]][y0+y])

    if(goin=="up"   ){y=y+1; if(y==  ring+1){ring=ring+1; goin="right"}; next}
    if(goin=="right"){x=x+1; if(x==  ring  ){             goin="down" }; next}
    if(goin=="down" ){y=y-1; if(y== -ring  ){             goin="left" }; next}
    if(goin=="left" ){x=x-1; if(x== -ring  ){             goin="up"   }; next}
  }
  res
}

示例:

require(ggplot2)
mat<-get_spiral(c(10,10),1,22); df<-data.frame(mat); ggplot(df,aes(X1,X2))+geom_path()

Result from the example