选择方形周长内圆圈内的点

时间:2012-09-24 11:16:30

标签: r

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

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)。我可以尝试编写一个拒绝newxnewy值为负的循环。但是必须为成千上万行执行此操作并担心速度。是否可以在不诉诸循环的情况下运行此条件坐标移位?

我的规则集如下:

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

  2. 新中心必须位于每个圆圈的范围内(与原始中心的半径距离为0.2)

  3. 新中心必须位于原广场内。

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

  5. enter image description here

2 个答案:

答案 0 :(得分: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,])
}

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

答案 1 :(得分:1)

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

如果你的方格是:

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

然后创建所有新中心(我建议runifsample使用radii代替angle,但这取决于您)。然后检查这些中心是否落在广场内,只有一行:

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

然后你应该做所有必要的步骤来重新创建所选择的newCenters,根据需要多次,直到它们落入广场。请注意,这需要while循环(或等效)。

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

作为最后一个想法,也许你可以结合这两种策略。首先将您的初始想法应用于完全位于正方形内的所有圆周(或等效地,距离周长2或更远的所有中心)。然后对所有其他圈子使用csr功能。

希望这有帮助!