2017-08-02 123 views
0

我在Java中,下面的方法:隨機點不是均勻分佈

public static Vector2d random(Circle circle) { 
    // this returns a random number between 0 and Math.PI * 2 
    double angle = MathUtils.random(0, Math.PI * 2); 
    // give the point inside the unit circle 
    // this returns a normalized vector from a given angle 
    Vector2d point = new Vector2d(angle); 
    // however, this is only along the edge 
    // now add a random magnitude (because this is a normalized vector, we can just multiply it by the desired magnitude) 
    double magnitude = Math.random(); 
    point = point.multiply(magnitude); 
    // now expand this to fit the radius 
    point = point.multiply(circle.getRadius()); 
    // now translate by circleCenter 
    return point.add(circle.getCenter()); 
} 

這並在確定的圓返回一個點,然而,當你這樣做了很多次,積點,你可以清楚地看到大多數點將朝向中心。

這是爲什麼?我不明白我的數學能做到這一點。

評論如果您希望我添加圖上的點的圖像,如果您認爲這可能會有所幫助。

+0

是的,這種情況發生的原因大致相同,即經線靠近極點靠近赤道附近。在圓圈中均勻分佈隨機點的一個很好的方法是在外接正方形中得到隨機點,然後拒絕掉落在圓外的那些點。 –

+2

試試這個:畫一個圓圈(或者想象你正在繪製一個圓圈)。按照切片比薩的方式分成16個等份。現在,對於從中心到外邊緣的每個半徑,將線段分成10個相等部分,並沿半徑放置10個均勻間隔的點。我想你會注意到這些點似乎更接近中心。這就是你的隨機化方法正在做的事情。 – ajb

+0

@ajb哦,謝謝,這幫助我想象它。現在我明白爲什麼發生這種情況 – MCMastery

回答

1

你的數學是有缺陷的。下面是爲什麼解釋和正確的解決方案:

任務是半徑爲R的在(x,y)平面的圓 內生成均勻分佈的數字。起初極座標看起來好像是一個好主意,而天真的解決方法是選擇[0,R]中分佈均勻的半徑r,然後在[0,2π]中均勻分佈 。但是,你最終會在原點 (0,0)附近出現一些點!這是錯誤的,因爲如果我們看一個特定的角度間隔,則說明[θ,θ+dθ],需要更多的點產生更多的點(大r),而不是接近零。半徑必須不 從均勻分佈拾取,而是一個都按

pdf_r =(2/R^2)* R

這足以容易做到通過計算累積 分佈的逆的,我們得到當r:

R = R * SQRT(RAND())

其中RAND()是在一個均勻隨機數[0,1]

http://www.anderswallin.net/2009/05/uniform-random-points-in-a-circle-using-polar-coordinates/

2

當然,當r小時,生成的點彼此更接近。

正如@DBrowne所說,您可以通過逆CDF技巧調整密度。

或者,您可以通過在[-R,R]x[-R,R]中繪製統一點並拒絕X²+Y²>R²(約佔其中的21%)的功能評估。該方法推廣到由其隱式方程已知的任何形狀。