1

我有一个坐标向量,其中每一行指定一个圆的中心:

x <- runif(5,0,2)
y <- runif(5,0,2)

如您所见,圆心都在正方形 (0,2) 内。

每个圆的半径为 0.2。我想在原始圆的范围内随机移动圆的中心。我想我可以这样做:

radii  <- (sample(20,5,replace=TRUE))/100
angles <- sample(360,5,replace=TRUE)
newx <- x + radii*(cos(angles))
newy <- y + radii*(sin(angles))

但是,我意识到这样做我可以从技术上获得落在正方形 (0,2) 之外的圆心。我可以尝试编写一个拒绝newx和否定newy值的循环。但是必须为成千上万行执行此操作并担心此速度。是否可以在不诉诸循环的情况下运行这种有条件的坐标偏移?

我的规则集如下:

  1. 为每个中心选择一个新的圆心。

  2. 新的中心必须落在每个圆的区域内(距离原始中心的半径 0.2 距离)

  3. 新中心必须位于原来的方格内。

  4. 如果一个中心与圆的边界相交,则应按照反射定律反映(反映所选随机半径距离的剩余长度)

在此处输入图像描述

4

2 回答 2

1

像这样的东西:

#lets do only one point first
x <- runif(1,0,2)
y <- runif(1,0,2)


randomwalk <- function (pos) {
  x <- pos[1]
  y <- pos[2]
  radius  <- (sample(20,1,replace=TRUE))/100
  angle <- sample(360,1,replace=TRUE)
  newx <- x + radius*(cos(angle))
  newy <- y + radius*(sin(angle))

  if (newy > 2) { #check the geometric calculations
    r2 <- (2-y)/sin(angle)

    hitx <- x + r2*(cos(angle))
    hity <- 2

    newx <- hitx + (radius-r2)*sin(angle)
    newy <- hity - (radius-r2)*cos(angle)
  } 

  #implement other borders yourself
  #and include a check, which border is hit first
  #and include the possibility for multiple hits 
  #(e.g., left border and then top border)

  cbind(newx,newy)
}

resx <- vector(50,mode="numeric")
resy <- vector(50,mode="numeric")

res <- cbind(resx,resy)

res[1,] <- cbind(x,y)


for (i in 2:50) {
  res[i,] <- randomwalk(res[i-1,])
}

我怀疑这仍然包含一些几何错误,但没有时间检查。

于 2012-09-24T13:21:15.957 回答
1

函数inpipinoutfrom package splancs 非常有用;它们可用于检查点是否落在多边形内。您只需要一个包含 2 列的矩阵,它代表任何多边形(例如正方形)。使用 C 和 Fortran 程序使这些函数变得快速。

如果您的正方形是:

square <- cbind(c(0, 10, 10, 0), c(0, 0, 10, 10)) # In case side = 10

然后创建所有新中心(我建议使用runif而不是samplefor the radiiand angle,但这取决于你)。然后用一条线检查这些中心是否落在正方形内:

inside <- inout(newCenters, square)
newCenters <- newCenters[inside]

之后,您应该执行所有必要的步骤来重新创建newCenters选择的对象,根据需要多次创建,直到它们落在正方形内。请注意,这需要一个while循环(或等效项)。

另请注意,在同一个包(splancs)中有这个函数csr可以在多边形内创建随机点。因此,原则上,您可以在正方形之外的每个圆周上切割一块,然后使用生成的多边形(切割圆)作为该函数的输入。这可能会变得很慢,因为您必须对所有切割圆使用循环(或lapply可能)。

最后一个想法,也许您可​​以将这两种策略结合起来。首先将您最初的想法用于完全落在正方形内的所有圆周(或等效地,与圆周距离为 2 或更多的所有中心)。然后csr对所有其余的圆圈使用该功能。

希望这可以帮助!

于 2012-09-24T15:05:14.977 回答