2012-09-24 26 views
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)以外的圆心。我可以尝试写一个循环,拒绝newxnewy值为负值。但是要做到这一点,需要成千上万的行,并担心这个速度。是否可以运行此条件坐标转换而不诉诸循环?

我的规则设置如下:

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

  2. 的新的中心必须落在每个圆圈(半径从原来的中心0.2距离)

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

  4. 如果中心符合应当反映为反射定律的圆的边界(反映选择的随机半径距离的剩余长度)

enter image description here

+0

这应该是一种随机游走?如果是这样,你应该首先决定边界发生了什么。如果没有,为什么不只是做一些像'X < - sapply(1:10,function(x)runif(5,0,2))'? – Roland

+0

谢谢@罗兰德是在随机散步下。如果原来的中心,我需要新的中心在半径范围内徘徊。 – user1320502

+0

正如@Roland所说,你应该提供确切的规则集。由于R的向量化本质,你不需要循环。例如,从博客的关于估计pi的讨论中借用:'a < - runif(n,0,1); b < - runif(n,0,1); #使用毕达哥拉斯定理;rads < - sqrt((a^2)+(b^2))',那么选择所有限制内的所有'rads'确实是最快的。 'rads < - rads [rads <0.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,]) 
} 

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

+0

谢谢罗兰我的几何不是很好,只是试图确定我知道'r2'' hitx'和'newx'计算正在做什么 – user1320502

1

来自软件包splancs的函数inpipinout非常有用;它们可以用来检查点是否落在多边形内。你只需要一个有2列的矩阵来表示任何多边形(比如方形)。使用C和Fortran程序可以使这些功能变得更快。

如果你方是:

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

然后创建所有的新的中心(我建议使用runif,而不是sampleradiiangle,但是这取决于你)。然后检查这些中心属于正方形内有一个行:

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

事后你应该做的一切必要的措施来重新创建newCenters但如选择出来,根据需要,直到它们落在正方形内多次。请注意,这需要一个while循环(或等效)。

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

作为最后的想法,也许你可以结合这两种策略。首先使用你的初始想法,完全落在正方形内的所有圆周(或者等同于周边距离2或更远的所有中心)。然后对所有其余的圈子使用csr函数。

希望这会有所帮助!