在光线跟踪算法里,有一个子问题:如何在一个半径为1的单位球里面,产生一个均匀分布的随机的点(相同的体积里有相同数量的点)。下面这篇文章里给出了5种可能的方法 (参考文献[3])。当然,后面我们会看到,这5种方法并不都是对的。

球里面均匀分布的点

方法一:拒绝掉不在球里的点

这个方法是这样,首先我们在x,y,z分别在 [-1, 1] 里均匀采样,这样就能实现在一个立方体里均匀采样。但这样的点可能不在球里,我们把不在球里的点拒绝掉就行。

function getPoint() {    var d, x, y, z;    do {        x = Math.random() * 2.0 - 1.0;        y = Math.random() * 2.0 - 1.0;        z = Math.random() * 2.0 - 1.0;        d = x*x + y*y + z*z;    } while(d > 1.0);    return {x: x, y: y, z: z};}

这里,Math.random() 会产生一个[0,1]之间的均匀分布的随机数。

方法二:选择一个随机的方向和半径

这个方法选择一个随机的向量,然后把它归一化到一个随机的半径。

function getPoint() {    var x = Math.random() - 0.5;    var y = Math.random() - 0.5;    var z = Math.random() - 0.5;    var mag = Math.sqrt(x*x + y*y + z*z);    x /= mag; y /= mag; z /= mag; // 把一个随机的点归一化到单位球面上    var d = Math.random(); // 一个随机的半径    return {x: x*d, y: y*d, z: z*d};}

这个方法会在同样的半径区间里产生同样多的点,比如 半径在 (0.1, 0.2)的区域内产生的点数和半径在 (0.2, 0.3)的区域内的点数,期望是相同的。但是这两个区间的体积却不一样。所以,这个方法并不能产生球内均匀分布的点。

方法三:在球坐标系下选择随机的点

球坐标下,一个点由 r (到原点的距离),theta(和z轴的夹角),phi(向量在x-y平面的投影和x轴的夹角)三个变量控制。这个坐标表示如果表示成笛卡尔坐标系,就是

x = r sin(phi) cos(theta)

y = r sin(phi) sin(theta)

z = r cos(phi)

function getPoint() {    var theta = Math.random() * 2.0*Math.PI;    var phi = Math.random() * Math.PI;    var r = Math.random();    var sinTheta = Math.sin(theta);   var cosTheta = Math.cos(theta);    var sinPhi = Math.sin(phi);   var cosPhi = Math.cos(phi);    var x = r * sinPhi * cosTheta;    var y = r * sinPhi * sinTheta;    var z = r * cosPhi;    return {x: x, y: y, z: z};}

球体里的一小块体积

根据上图,球体里的一下快体积正比于 sin(phi)d(theta)d(phi) = d(theta) d(cos(phi))。因此,可以看到,如果phi是均匀分布,但是sin(phi)不是均匀分布。

另外,这个算法里,半径r是均匀分布的,但是半径为r的球和单位球的体积比例是r的三次方。也就是说,r越小,点会越密集。

因为这两个原因,这个方法也不符合要求。

方法四:用高斯分布的随机数

我们首先看代码

function getPoint() {    var u = Math.random();    var x1 = randn(); // 0为均值,1为方差的高斯分布随机数    var x2 = randn();    var x3 = randn();    var mag = Math.sqrt(x1*x1 + x2*x2 + x3*x3);    x1 /= mag; x2 /= mag; x3 /= mag;    var c = Math.cbrt(u); // 立方根    return {x: x1*c, y:x2*c, z:x3*c};}

这个地方要对 u 取立方根,是因为半径为u的球的体积是半径为1的球的体积的 u 三次方倍。

这个地方比较奇怪的是,x,y,z为什么要是高斯分布(正态分布)。这个可以参考参考文献[5][6]。

简单解释一下如下:

正态分布的形式是 f(x) = exp{-(x*x)/2} / sqrt(2PI)

因此,f(x, y, z) = exp{ - (x*x + y*y + z*z)/2 } / Const = exp{ - (r*r)/2 } / Const

因此这样产生的点只和它的模长相关,和各种角度都无关。

方法五:改良的球坐标法

在上面的球坐标法中,有2个问题,1. 角度phi均匀分布不代表cos值均匀分布 2. 球的体积和半径的三次方成正比。因此,我们可以直接让cos(phi)值均匀分布,而不是角度均匀分布,同时,对半径开立方根,来保证体积的均匀分布。

function getPoint() {    var u = Math.random();    var v = Math.random();    var theta = u * 2.0 * Math.PI;    var phi = Math.acos(2.0 * v - 1.0);    var r = Math.cbrt(Math.random());    var sinTheta = Math.sin(theta);    var cosTheta = Math.cos(theta);    var sinPhi = Math.sin(phi);    var cosPhi = Math.cos(phi);    var x = r * sinPhi * cosTheta;    var y = r * sinPhi * sinTheta;    var z = r * cosPhi;    return {x: x, y: y, z: z};}

参考文献

  1. 各种分布的证明 http://mathworld.wolfram.com/SpherePointPicking.html
  2. 球坐标系的介绍 http://mathworld.wolfram.com/SphericalCoordinates.html
  3. https://karthikkaranth.me/blog/generating-random-points-in-a-sphere/
  4. Marsaglia, G. (1972). Choosing a point from the surface of a sphere,Ann. Math. Statist.,43, 645–646 https://projecteuclid.org/download/pdf_1/euclid.aoms/1177692644
  5. Muller, M. E. (1959). A note on a method for generating points uniformly onN-dimensional spheres,Commun. Ass. Comput. Math. 2, 19–20.
  6. http://extremelearning.com.au/how-to-generate-uniformly-random-points-on-n-spheres-and-n-balls/

地图点随机分布均匀_如何在单位球内产生一个均匀分布的随机的点?相关推荐

  1. 地图点随机分布均匀_英国标准协会(BSI)推荐的三坐标测点分布策略

    在使用三坐标测量机进行测量并且评价形位公差时,首先要做的就是根据图纸要求,测量对应特征,使用对应基准特征,建立坐标系. 为了达到测量的目的,每种特征在数学上均定义了最少测点数(如下图所示),例如两点定 ...

  2. wpf指定的元素已经是另一个元素的逻辑子元素。请先将其断开连接。_在60分钟内建立一个无代码应用程序...

    让我们使用Airtable和Appgyver制作一个基本的Web应用程序. 无需编码技能. 我们将使用以下内容建立具有类别的产品目录: · Airtable:用于构建数据的混合数据库服务(第1部分) ...

  3. 语音库构建_在10分钟内构建一个多功能语音助手

    语音库构建 Nowadays people don't have time to manually search the internet for information or the answers ...

  4. vr设备应用程序_在15分钟内构建一个VR Web应用程序

    vr设备应用程序 在15分钟内,您可以开发一个虚拟现实应用程序,并在Web浏览器,VR头盔或Google Daydream上运行它. 关键是A-Frame ,这是Mozilla VR Team构建的开 ...

  5. 一、三大基础随机分布与数学特征

    一.三大基础随机分布 均匀.指数.正态 1.均匀分布 表示在相同长度间隔的分布概率是等可能的 其概率密度.均值.方差 2.指数分布 事件以恒定平均速度连续且独立地发生的过程(泊松过程中的事件之间的时间 ...

  6. python实现随机抽取答题_如何在python中实现随机选择

    这篇文章主要介绍了如何在python中实现随机选择,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 想从一个序列中随机抽取若干元素,或者想生成几个随机 ...

  7. 用百度地图实现添加电子围栏并判断是否在范围内

    用百度地图实现添加电子围栏并判断是否在范围内 做一个社区矫正系统时,误以为是给每个人设置一个活动范围,做了一个Demo, 以用户位置为中心,设置电子围栏半径并判断是否在范围内 预览: HTML代码如下 ...

  8. 画时域随机信号波形_【鼎阳硬件智库原创︱测试测量】任意波形发生器的基本输出波形及其相关参数...

    方浩 鼎阳硬件设计与测试智库专家组成员 传统的函数发生器可以输出正弦波.方波.三角波等标准波形,但是在实际的测试场景中,为了模拟产品在实际使用过程中的复杂情况,往往需要人为地去制造一些"不规 ...

  9. 狄利克雷分布公式_深入机器学习系列11-隐式狄利克雷分布

    转载请注明出处,该文章的官方来源: LDA | Teaching ML 前言 LDA是一种概率主题模型:隐式狄利克雷分布(Latent Dirichlet Allocation,简称LDA).LDA是 ...

最新文章

  1. windows简易使用composer 安装国内镜像
  2. .net得到ip(引)
  3. typescript的类型描述_一文学懂TypeScript的类型
  4. efl是什么意思_efl
  5. [转载] 4.Pandas处理丢失数据
  6. 一次频繁Full GC问题排查过程分享
  7. 04-树4. Root of AVL Tree (25)
  8. Guice依赖注入(Scope)
  9. 《老路用得上的商学课1—5》成本
  10. EditPlus怎么首行和末尾统一添加文本内容
  11. “CSIG 计算机视觉前沿 · 研讨会”于6月28日在百度举行
  12. JSD-2204-(业务逻辑开发)-发酷鲨商城front模块-开发购物车功能-Day09
  13. java之httpclient
  14. 删除flash助手推荐广告
  15. elasticsearch-starter
  16. 阿里云OSS配置及使用
  17. 人间简史从动物到上帝读后感_从我的博客到上帝的耳朵...
  18. 电脑市场装机版Ghost XP SP2 v2.0 [修正版]
  19. shell读书笔记8
  20. phpbreak跳出几层循环_PHP break:跳出循环

热门文章

  1. 微信终于要上线客服了?相关商标已完成注册
  2. 哎!2019年最后1天,我从外包公司辞职了...
  3. vue拿到数据渲染页面上
  4. ELP界的苹果:太奇pad开创教育电子产品新时代
  5. 无法选择工作 但可选择态度
  6. Android Studio 注释模板
  7. asp.net学员请销假管理系统
  8. 只字没有,网络小说就一标题能卖810万
  9. flutter 死亡红屏 隐藏
  10. 炫云图像分层工具使用方法