Вы также можете сделать это в сферических координатах, в этом случае нет отклонения. Сначала вы случайным образом генерируете радиус и два угла, а затем используете формулу перехода для восстановления , и ( , , ).xyzx=rsinθcosϕy=rsinθsinϕz=rcosθ
Вы генерируете равномерно между и . Радиус и угол наклона не одинаковы. Вероятность того, что точка находится внутри шара радиуса равна поэтому функция плотности вероятности равна . Вы можете легко проверить, что кубический корень равномерной переменной имеет точно такое же распределение, поэтому вы можете сгенерировать . Вероятность того, что точка находится в сферическом конусе, определенном наклоном равна или еслиϕ02πrθrr3r3r2rθ(1−cosθ)/21−(1−cos(−θ))/2θ>π/2 . Таким образом, плотность есть . Вы можете проверить, что минус арккосин равномерной переменной имеет правильную плотность.θsin(θ)/2
Или, проще говоря, мы можем смоделировать косинус равномерно beteen и .θ−11
В R это будет выглядеть так, как показано ниже.
n <- 10000 # For example n = 10,000.
phi <- runif(n, max=2*pi)
r <- runif(n)^(1/3)
cos_theta <- runif(n, min=-1, max=1)
x <- r * sqrt(1-cos_theta^2) * cos(phi)
y <- r * sqrt(1-cos_theta^2) * sin(phi)
z <- r * cos_theta
В процессе написания и редактирования этого ответа я понял, что решение менее тривиально, чем я думал.
Я думаю, что самый простой и эффективный в вычислительном отношении метод - это следовать методу @ whuber для генерации на единичной сфере, как показано в этом посте, и масштабировать их с помощью .(x,y,z)r
xyz <- matrix(rnorm(3*n), ncol=3)
lambda <- runif(n)^(1/3) / sqrt(rowSums(xyz^2))
xyz <- xyz*lambda