生成乙個均勻的 隨機的圓形

2021-08-20 12:35:53 字數 2252 閱讀 1411

posted on 2023年5月24日

by jinchao

最近在工作中遇到這麼乙個問題:

在遊戲場景中有乙個怪物生成點,這個生長點產生的怪物均勻分布在半徑為r的圓形內,這個隨機演算法應該如何生成?看起來很簡單,隨手寫了乙個:

#define

rand

((float

)rand()/

rand_max

)void

get_random_pos

(float

center_x

, float

center_y

, float

radius

, float&x

, float& y

) 但寫的過程中,直覺告訴我,這麼寫肯定是有問題的,試想,如果以北京為例,如果所有居住在北京的人都報出自己家和天安門的距離,那麼這些資料肯定不是均勻分布的,因為居住在五環附近的人數肯定要大於居住在二環附近的人數,於是用mathamatica實驗一下:

果然,這麼寫是不對的,網上查了一下,這個問題還真是有人研究過,說應該把所獲得的隨機數開平方一下,實驗一下:

但是,這個開平方背後的數學原理究竟是什麼呢?抽空翻了下概率書,原來,其中的道理並不複雜,這裡涉及到概率裡的乙個基本概念,累計分布函式(cumulative distribution function),簡稱cfd,它的定義如下:

設有乙個隨機變數x

,它的取值範圍是從負無窮到正無窮,如果把它的值小於x

的概率表達為乙個函式f(x

),那麼這個函式就稱為x

的累計分布函式f(

x)=p

(x≤x

) 以最為常見的均勻分布概率為例,設均勻分布的隨機變數x

的取值範圍是[a,

b],那麼它的累計分布函式以及函式影象是f(

對於乙個累計分布函式,符合以下規律

回到我們的問題中,假設怪物產生的範圍的半徑為r

,隨機產生乙隻怪物時,它和中心的距離是乙個隨機變數x

,顯然,對於怪物均勻分布的情況,x

落在半徑為x

的圓內的概率,等於半徑為x

小圓和半徑為x

的大圓的面積之比

也就是說f(

x)=p

(x≤x

)=x2

/r2

現在我們手頭上只有均勻概率的隨機數產生器,要想產生這麼個隨機數需要用到乙個很巧妙的運算,就是反函式。設隨機變數

u是乙個均勻分布在[0,1]之間的隨機數,另乙個隨機變數 x=

f−1(

u),現在我們需要證明

x的累計分布函式是 f(

x)證明如下 p

(x≤x

)=p(

f−1(

u)≤x

)=p(

u≤f(

x))=

f(x)

初看起來有點複雜,其實在下面的圖上可以很直觀的理解這個過程:

這是利用了 f(

x)是單調遞增函式的特性,在我們的問題中, f(

x)的反函式可以表達為 f

−1(u

)=ru

−−√

所以最終的演算法可以寫成

#define

rand

((float

)rand()/

rand_max

)void

get_random_pos

(float

center_x

, float

center_y

, float

radius

, float&x

, float& y

) tagged 數學, 程式, 演算法

演算法 均勻的生成圓內的隨機點

演算法 1 設半徑為 r x r ast cos theta y r ast sin theta 其中 0 leqslant r leqslant r t 為0 1均勻分布產生的隨機數,r sqrt t ast r theta 2 pi ast t,t sim u 0,1 證明 url 下面的演算法...

乙個均勻繫結 cpu 的 shell

有時,由於架構設計或其他業務本身特點原因,導致有些應用是由cpu很不均衡 處理集中在乙個cpu是上 白白浪費其他cpu在睡覺。乙個簡單辦法就是繫結到多個cpu 繫結 cpu 是乙個不錯技巧,但是不是殺手鐗,一般能提高10 效能 更好地辦法是優化架構,對於網路處理性程式,繫結網絡卡中斷。這裡分享乙個小...

隨機生成乙個根據引數指定的隨機數

在開發過程中隨時都可以遇到隨機數,但是有時候往往達不到自己意願,在這裡我將自己寫的乙個方法整理出來,大家一起交流!desciption 隨機生成乙個根據引數指定的隨機數 str 生成隨機碼位數 arg 1 生成全數字,2 生成數字字母混合 private static string makepass...