球面上のランダムな点

(3次元)単位球面上から、偏りなくランダムに点を得たいとします。


単位円上であれば、区間[0,2\pi)上の一様乱数\thetaを生成すれば点(\cos\theta,\sin\theta)が目的のものとなりますが、
球座標(r,\theta,\phi)で同様に「\theta[0,\pi)\phi[0,2\pi)上の一様乱数」としてしまうと極付近に点が偏ってしまいます。

方法1

区間[-1,1]上の一様乱数を3つ生成し、a,b,cとする。
(a,b,c)が単位球に含まれていれば、
\begin{pmatrix} x\\y\\z \end{pmatrix} = \frac{1}{\sqrt{{a^2+b^2+c^2}}}\begin{pmatrix} a\\b\\c \end{pmatrix}
が目的のもの。含まれていなければやり直し。

分かりやすくて良いですね。
ただ、1回で点が得られるとは限らないのが残念です。


(a,b,c)は単位球内から偏りなく選ばれるので、もちろん(x,y,z)も単位球面上から偏りなく選ばれます。

方法2

\phi[0,2\pi)上の、z[-1,1]上の一様乱数とすれば、
\begin{pmatrix} x\\y\\z \end{pmatrix} = \begin{pmatrix} \sqrt{1-z^2}\cos \phi \\ \sqrt{1-z^2}\sin \phi  \\z \end{pmatrix}
が目的のもの。

これだとまた極方向に偏ってしまいそうですが、そうはなりません。


球座標(r,\theta,\phi)\theta,\phiを一様乱数にすると、微小面積\sin\theta d\theta d\phiに対して(?)一様に点が
分布することになるため、\sin\thetaが小さい極付近に点が集まってしまいます。
ここで
 \cos\theta = z
とすれば
 \sin\theta d\theta d\phi = -dzd\phi
となり、\phizを一様乱数とすれば偏りは無くなります。

方法3

正規乱数を3つ生成し、a,b,cとすれば、
\begin{pmatrix} x\\y\\z \end{pmatrix} = \frac{1}{\sqrt{{a^2+b^2+c^2}}}\begin{pmatrix} a\\b\\c \end{pmatrix}
が目的のもの。

某所で最近見かけたのですが、どうやら正規乱数を用いると簡単に書けるようです。


正規分布
 f(x)=\frac{1}{\sqrt{2 \pi}}e^{-\frac{x}{2}}
のような形をしているので、ある点(a,b,c)が選ばれる確率密度(?)は
 (\frac{1}{\sqrt{2 \pi}})^3 e^{-\frac{a^2+b^2+c^2}{2}}
となり、原点からの距離sqrt{a^2+b^2+c^2}にのみ依存する(等方的である)、といった感じでしょうか。
これだと任意の次元に使えそうですね。