【问题标题】:select points within circles within square perimeter选择正方形周长内的圆圈内的点
【发布时间】:2013-11-21 22:45:16
【问题描述】:

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

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 负值的循环。但是必须为 10s 的数千行执行此操作并担心此速度。是否可以在不诉诸循环的情况下运行这种条件坐标移位?

我的规则集如下:

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

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

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

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

【问题讨论】:

  • 这应该是某种随机游走吗?如果是这样,您应该首先决定在边界会发生什么。如果没有,为什么不直接做X &lt;- sapply(1:10,function(x) runif(5,0,2)) 之类的事情?
  • 谢谢@Roland,是的,它属于随机游走。如果原来的中心,我需要新的中心在半径范围内。
  • 正如@Roland 所说,您应该提供确切的规则集。由于 R 的矢量化特性,您将不需要循环。例如,从博主关于估计 pi ​​的讨论中借用:a &lt;- runif(n,0,1); b &lt;- runif(n,0,1); # use the pythagorean theorem; rads &lt;- sqrt((a^2) + (b^2) ) 那么在您的限制范围内选择所有rads 确实是最快的,例如rads&lt;- rads[rads&lt;0.2]
  • 如果是随机游走,您必须定义如果点移出正方形会发生什么。例如,您可以说它应该遵守反射的物理定律。我认为仅仅在模拟中说它不会发生是没有意义的。
  • 是的,Roland 很抱歉需要保姆。反思的法则是我将如何被对待。

标签: r


【解决方案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,])
}

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

【讨论】:

  • 谢谢 Roland,我的几何不太好,只是想确保我知道 r2 hitxnewx 的计算在做什么
【解决方案2】:

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

如果你的正方形是:

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

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

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

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

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

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

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    相关资源
    最近更新 更多