连接距离最小的矩阵的两个坐标

时间:2020-09-15 08:07:01

标签: r matrix interpolation igraph

我正在基于一个考虑最小距离的两个坐标来完成一个矩阵的完成过程(我不确定正确的术语)。

我有一个nxm的矩阵(行和列),NA值为1,见图1:

enter image description here

目标是:

  1. 找到相连元素的端点,这些端点之间的距离等于1(水平和垂直方向上相邻)或1.4142(对角线上相邻)。示例中的极端坐标由图中的矩形表示。
  2. 找到极端坐标后,需要完成描述“最好”两点之间最小距离的坐标。 (由图1中的线表示)

假设我找到了极坐标( a b 见图2),我试图使用直线的矢量方程:

enter image description here

因此,我试图创建一个使用极值(a和b)和常数k(见图2)的函数

completa <- function(a, b, k){
  x <- y <- NULL
  resta <- b - a
  u_ba <- resta / sqrt(sum(resta^2))
  for (i in seq(0, 1, k)) {
    posi <- a + i * u_ba
    x <- c(x, posi[1])
    y <- c(y, posi[2])
  }
  coordenadas  <- round(cbind(x, y))
  return(coordenadas)
}

示例矩阵位于:

data_mat <- read.csv("https://www.dropbox.com/s/hz42scjuf9uib9y/data_test.csv?dl=1")
a <- c(25, 6)
b <- c(20, 10)

使用坐标为a,b和k = 0.5(k的值可以在0和1之间变化)的函数时,将获得以下结果:

completa(a,b,0.5)
#      x y
#[1,] 25 6
#[2,] 25 6
#[3,] 24 7

但预期的输出是:

#      x y
#[1,] 25 6
#[2,] 24 7
#[3,] 23 8
#[4,] 22 9
#[5,] 21 10 # or 21 9,  
#[6,] 20 10

很明显,这条线有多个解决方案,因此,建议最好考虑最小距离。

最后,在拥有这些坐标之后,仅给它们分配一个等于1的值就足够了。主要思想是使此过程递归。最后,矩阵的所有坐标都可以连接。

欢迎任何建议,谢谢。

3 个答案:

答案 0 :(得分:1)

据我所知,您已经在数学上出现了问题。当我理解正确时,您想“击中”极端坐标之间的正方形,以在2个簇之间建立桥梁。您所犯的错误是在您的for循环中。您在循环的末尾仅添加了ab的单位矢量的1倍,因此在网格中仅行进了1的距离。 我已经以这种方式更正了您的代码,它可以传播整个距离。我希望它能解决您的问题:

completa <- function(a, b, k){
  if(k!=0){
    x <- y <- NULL
    resta <- b - a
    vector_length = sqrt(sum(resta^2))        
    for (i in seq(0, 1, length.out=(vector_length/k))) {
      posi <- a + i * resta
      x <- c(x, posi[1])
      y <- c(y, posi[2])
    }
    coordenadas  <- round(cbind(x, y))
    coordenadas <- unique(coordenadas[,1:2])
  }
if(k==0) coordenadas = a
return(coordenadas)
}

结果是

 > completa(a,b,0.5)
         x  y
   [1,] 25  6
   [2,] 24  7
   [3,] 23  7
   [4,] 23  8
   [5,] 22  8
   [6,] 22  9
   [7,] 21  9
   [8,] 20 10

答案 1 :(得分:1)

为什么不只是在识别出的极点之间使用线性逼近并取整数值...

> x_12 <- c(25, 20)
> y_12 <- c(6, 10)
> do.call(cbind, lapply(approx(x_12, y_12, xout = seq(x_12[1], x_12[2], ifelse(x_12[1]>x_12[2], -1, 1))), round))
     x  y
[1,] 25 6
[2,] 24 7
[3,] 23 8
[4,] 22 8
[5,] 21 9
[6,] 20 10

答案 2 :(得分:1)

也许您可以尝试以下类似的方法

x <- seq(a[1],b[1])
y <- seq(a[2],b[2])
if (length(x) >= length(y)) {
  y <- c(y,rep(tail(y,1),length(x)-length(y)))
} else {
  x <- c(x,rep(tail(x,1),length(y)-length(x)))
}

这样

> cbind(x,y)
      x  y
[1,] 25  6
[2,] 24  7
[3,] 23  8
[4,] 22  9
[5,] 21 10
[6,] 20 10