地图点随机分布均匀_如何在单位球内产生一个均匀分布的随机的点?
在光线跟踪算法里,有一个子问题:如何在一个半径为1的单位球里面,产生一个均匀分布的随机的点(相同的体积里有相同数量的点)。下面这篇文章里给出了5种可能的方法 (参考文献[3])。当然,后面我们会看到,这5种方法并不都是对的。
![](/assets/blank.gif)
球里面均匀分布的点
方法一:拒绝掉不在球里的点
这个方法是这样,首先我们在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)的区域内的点数,期望是相同的。但是这两个区间的体积却不一样。所以,这个方法并不能产生球内均匀分布的点。
方法三:在球坐标系下选择随机的点
![](/assets/blank.gif)
球坐标下,一个点由 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};}
![](/assets/blank.gif)
球体里的一小块体积
根据上图,球体里的一下快体积正比于 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};}
参考文献
- 各种分布的证明 http://mathworld.wolfram.com/SpherePointPicking.html
- 球坐标系的介绍 http://mathworld.wolfram.com/SphericalCoordinates.html
- https://karthikkaranth.me/blog/generating-random-points-in-a-sphere/
- 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
- Muller, M. E. (1959). A note on a method for generating points uniformly onN-dimensional spheres,Commun. Ass. Comput. Math. 2, 19–20.
- http://extremelearning.com.au/how-to-generate-uniformly-random-points-on-n-spheres-and-n-balls/
地图点随机分布均匀_如何在单位球内产生一个均匀分布的随机的点?相关推荐
- 地图点随机分布均匀_英国标准协会(BSI)推荐的三坐标测点分布策略
在使用三坐标测量机进行测量并且评价形位公差时,首先要做的就是根据图纸要求,测量对应特征,使用对应基准特征,建立坐标系. 为了达到测量的目的,每种特征在数学上均定义了最少测点数(如下图所示),例如两点定 ...
- wpf指定的元素已经是另一个元素的逻辑子元素。请先将其断开连接。_在60分钟内建立一个无代码应用程序...
让我们使用Airtable和Appgyver制作一个基本的Web应用程序. 无需编码技能. 我们将使用以下内容建立具有类别的产品目录: · Airtable:用于构建数据的混合数据库服务(第1部分) ...
- 语音库构建_在10分钟内构建一个多功能语音助手
语音库构建 Nowadays people don't have time to manually search the internet for information or the answers ...
- vr设备应用程序_在15分钟内构建一个VR Web应用程序
vr设备应用程序 在15分钟内,您可以开发一个虚拟现实应用程序,并在Web浏览器,VR头盔或Google Daydream上运行它. 关键是A-Frame ,这是Mozilla VR Team构建的开 ...
- 一、三大基础随机分布与数学特征
一.三大基础随机分布 均匀.指数.正态 1.均匀分布 表示在相同长度间隔的分布概率是等可能的 其概率密度.均值.方差 2.指数分布 事件以恒定平均速度连续且独立地发生的过程(泊松过程中的事件之间的时间 ...
- python实现随机抽取答题_如何在python中实现随机选择
这篇文章主要介绍了如何在python中实现随机选择,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 想从一个序列中随机抽取若干元素,或者想生成几个随机 ...
- 用百度地图实现添加电子围栏并判断是否在范围内
用百度地图实现添加电子围栏并判断是否在范围内 做一个社区矫正系统时,误以为是给每个人设置一个活动范围,做了一个Demo, 以用户位置为中心,设置电子围栏半径并判断是否在范围内 预览: HTML代码如下 ...
- 画时域随机信号波形_【鼎阳硬件智库原创︱测试测量】任意波形发生器的基本输出波形及其相关参数...
方浩 鼎阳硬件设计与测试智库专家组成员 传统的函数发生器可以输出正弦波.方波.三角波等标准波形,但是在实际的测试场景中,为了模拟产品在实际使用过程中的复杂情况,往往需要人为地去制造一些"不规 ...
- 狄利克雷分布公式_深入机器学习系列11-隐式狄利克雷分布
转载请注明出处,该文章的官方来源: LDA | Teaching ML 前言 LDA是一种概率主题模型:隐式狄利克雷分布(Latent Dirichlet Allocation,简称LDA).LDA是 ...
最新文章
- windows简易使用composer 安装国内镜像
- .net得到ip(引)
- typescript的类型描述_一文学懂TypeScript的类型
- efl是什么意思_efl
- [转载] 4.Pandas处理丢失数据
- 一次频繁Full GC问题排查过程分享
- 04-树4. Root of AVL Tree (25)
- Guice依赖注入(Scope)
- 《老路用得上的商学课1—5》成本
- EditPlus怎么首行和末尾统一添加文本内容
- “CSIG 计算机视觉前沿 · 研讨会”于6月28日在百度举行
- JSD-2204-(业务逻辑开发)-发酷鲨商城front模块-开发购物车功能-Day09
- java之httpclient
- 删除flash助手推荐广告
- elasticsearch-starter
- 阿里云OSS配置及使用
- 人间简史从动物到上帝读后感_从我的博客到上帝的耳朵...
- 电脑市场装机版Ghost XP SP2 v2.0 [修正版]
- shell读书笔记8
- phpbreak跳出几层循环_PHP break:跳出循环