当前课程知识点:游戏程序设计 > 第五章 《随机数在游戏中的应用》 > 5.3 随机数分布与应用 > 5.3 随机数分布与应用
我们看那个我们真正在用的时候
像vc里面
我们取的随机数是
0到32767的一个随机数
那如果我有如何取到一个
0到9999的随机数呢
我们平常写的时候
有可能也会写一个rand()整除1万这样的
左边这块的几率会大一些
然后右边几率就会小一些
它原因呢
就是因为32767不能被一万整除
但这个例子中
如果是要一到五的话
是因为它没法整除
所以所以其实很难取到这个数
这时候呢
我们可以采用一个拒绝采样方法
就是如果取到一个比如说
这个取到超过三万的话
我就把它扔掉重新取一次
它是如何取得一个更大的随机数
就是如果我只有一个这样的函数
我想取的一个非常大的随机数的话
取两次把它两个两个装的宽带加起来
但直接相加是不行的
就是用那个rand() * (RAND_MAX + 1)
然后可以达到一个更大的数
还有当然更好的方法就是一个
就别用这个vc++的rand函数了
我们现在一般用的话
就拿没梅森旋转去取就可以了
这个已经很成熟
速度也很快
我们如何取了一个零到一的随机数呢
0到1的浮点随机数呢
我们一般一般用的方法就是
先取一次rand()
然后
再除以RAND_MAX
就得到0到1的随机数
能不能使用
然后整出一万
然后再出一万
这样呢
虽然这以前我也这样写过
但是后来才知道这样是不行的
这样说
这样写了就会跟刚才
跟刚才这个犯一样的错误
我就是会左边这个呢
会会增大
分布在左边的时候可能性会更大
然后放在右边的时候可能性会更小
针对那个浮点数的存储格式了
我可以直接往它那填充二进制进行填充
因为浮点数存储格式
我们是可以知道
它是由一个符号位
还有一个指数域还有一个尾数域
三部分组成的
那么指数域我们给它指定一个写死的这样的值
然后在尾数域在23位
拿随机拿0和1进行填充
这样生成的一个随机数呢
它就是在1和2的一个范围内
然后再把它减去一就可以的到0到1之间
分布的一个随机数
在后面讲一下正态分布
比如说有时候我们想生成一些
比如说形成一个草地或者树林
或者生成一些不同身高的人群
我们如果用正态分布的话
会得到一个更自然一点的效果
既然上面是正态分布的
下面是平均分布的
平均分布呢
就看起来就没那么自然
因为比如而正态分布呢
就是大家都是差不多的身高
然后突然来有几个人特别高的
而平均分布就会看起来不那么自然
如何获得正态分布呢
然后
获得正在分步的方法
有很多种像拒绝采样法
这个Ziggurat
然后反函数法还有Boxmuiier
还有中心极限定理
拒绝采样法呢
就是一种很简单的方法
就是我采两次样
把两次样分别当作X值和Y值用
然后
根据这个先求一个这个正太分布的曲线
然后如果这个xy
处在除了蓝色线以下的地方我就保留
处在除了蓝色线以外我就丢弃
这样很简单办法就能保证
到时候我输出的时候只输出S值
这样就能保证知道是一个正态分布
它的缺点是浪费了很多采样点
就是有很多次很多次计算是白费掉了
Ziggurat法是一个优化版的
跟拒绝采样是一样的
它就为了解决
为了解决
刚才上一个方法中有很多计算被浪费掉
这个现象
他的方法
它的算法是先生成一些面积相等的矩形
这个面积相等的矩形是符合正态分布的
然后再随机
随机是在哪个矩形中
如果是在矩形中的这种绿色部分的话
就是保留就是要保留它
然后如果是在红色部分的话
就再用上一次拒绝采样法来判断一次
最后只保留还是跟上次一样
只保留蓝色线以下的部分
蓝色线以上的部分就丢掉
这是一个优化版的拒绝采样
它主要的目的就是为了减少无效的预算
还有一个方法就是逆变换采样
这个就是比那个效率更高些
它的思想就是
因为现在我知道
我能知道这是正态分布的曲线的话
我可以先产生Y轴上
零到一之间均匀分布的随机数
然后找到它对应的通过S轴的位置
然后把X值对应的值输出来就可以了
所以这种方法就是要先拿到一个
拿一个正态分布的一个反函数
然后拿这个反函数来算
还有一个boxMuIIer法
然后就是一个
它这种方法是好处是算起来很快
而且我一次可以得到两个两个那个
这下正态分布的值
还有个方法就是中心极限定理
就是跟刚才扔硬币那个
不是扔硬币扔骰子
那个是一样的
如果我仍有很多很多次话
叠加起来就是一个正态分布的一个曲线
这种方法看起来是
看起来是一种浪费
因为我采用一个值
我要把生成N个
独立分布的随机变量加起来
但这个方法有好处
第一单个计算非常快
就是虽然我计算每一个的时候非常快
而且因为这种算法特别适合于硬件加速
因为我们现在CPU处理器
也是很多都是向量运算
它一次可以运送很多值
所以这样这种方法
在CPU上运行的切面起来也很快
如果
像N等于4的话
就能得到一个看起来
有点这个正态分布的这种效果
如果质量不高的话
可以采用这种方式
这里面列了就是很多很多种
那个正态分布的方案
然后这里有它耗时的比较
大家可以看到这个耗时最快的
还是一个boxMuIIer法
这个
这个具体的这些每一个算法是怎么实现的
大家可以去参考这个网站
这个PPT到时候我会发给大家
可以参考这个网站上有那个各种方式
各种方法的那个实践
还有各种方案的比较
在接下来讲究形状采样
像形象采样比如说
策划给我们这样一个要求
要求我在一个矩形区域内
随机产生多少个怪物
然后这种方式的是
这种方式怎么做呢
其实这个也很简单
就是在横轴上
然后零到一之间随机取一个值
纵轴上随机取一个值
然后直接取消坐标就可以
平行四边形的话就是也是一样的
但是想想三角形该怎么做
我要在三角形上随机取一个点
因为这种需求
比如说我们那个在渲染时候
用的所有的面都是三角形的
所以这个还是有一定有一些需求的
就是比如说我要再取三角面上
随机一个点用来做光照图
或者做离线渲染之类经常会用到
我们有时候有一些
有时候也会有需求
比如说我要娶一个圆上的随机分布
那个最简单方法还是拒绝采样
然后比如说我采一下
在一个矩形里面采一下
如果不在这个圆里面
我就把它扔掉
但是一个没有办法采用这种方法
再好一点办法
就是极坐标
但用极坐标的时候
大家要稍微注意点
就是不要犯左图错误
如果左图这是最简单方法
如果r*sin(theta) ,r*cos(theta)就会出现这种情况
就是
都挤在里面这了挤在中心这了
右边这种就是先取二的开方
然后再乘以sin(theta)
它的证明呢大家可以看看这里面这个
刚才上一次提到一个洗牌算法
刚才上一次提到一个洗牌算法
洗牌算法呢
应该也算是跟着这个也有点关系的
就是比如现在音乐播放
有时候会用到的
这是
它的方法就是先取第一个元素
然后与后面的N个元素之中
任意一个交换包括自己
以此类推
然后直到把所有N个元素跑一遍为止
这个洗牌算法呢
就是还是挺不好设计
这种算法设计不好的话
就很容易出各种坑
所以说
如果大家用到洗牌算法的话
就可以用这个简单的方法来实现
-1. 1什么是游戏(上)
--选择题
-1.2 什么是游戏(下)
--选择题
-1.3 游戏是如何开发出来的
-1.4 游戏引擎(上)
-1.5 游戏引擎(下)
--单选题
-1.6 如何成为一个游戏开发者
--多选题
-2.1 什么是游戏服务器
--单选题
-2.2 游戏服务器的和分类发展
--单选题
-2.3 核心技术和实现难点
--单选题
-2.4 设计原理与方法论
--单选题
-3.1 三维坐标系统
--多选题
-3.2 向量与运算
--单选题
-3.3 矩阵与线性变换
--双选题
-3.4 四元数
--3.4 四元数
--多选题
-4.1 游戏循环概述(上)
--多选题
-4.2 游戏循环概述(下)
--单选题
-4.3 《无尽之路》的实现
--单选题
-4.4 支撑游戏的功能
--选择题
-4.5 支撑游戏的机制与系统
--多选题
-5.1 基本介绍
--5.1 基本介绍
--单选题
-5.2 随机数生成器
--单选题
-5.3 随机数分布与应用
--单选题
-6.1 什么是游戏玩法开发
--单选题
-6.2 建立愿景 Vision
--单选题
-6.3 划定边界 Scope
-6.4 迭代 Iteration
--单选题
-6.5 迭代 Iteration+抛光Polish
--单选题
-7.1实时图形渲染管道 宏观渲染系统
--单选题
-7.2实时图形渲染管道 应用阶段
--单选题
-7.3实时图形渲染管道 几何阶段
--单选题
-7.4实时图形渲染管道 光栅化阶段
--单选题
-7.5实时图形渲染管道 总结 参考
-8.1 物理回顾1
--单选题
-8.2 物理回顾2
--单选题
-8.3 材质 1
--8.3 材质 1
-8.4 材质 2
--8.4 材质 2
-8.5 材质3
--8.5 材质3
-8.6局部光照
--8.6局部光照
--单选题
-8.7 全局光照
--8.7 全局光照
--单选题
-9.1 动画介绍
--9.1 动画介绍
--多选题
-9.2 游戏动画介绍
-9.3 动画技术类型
--多选题
-9.4 骨骼蒙皮动画
--多选题
-9.5 动画流水线
--多选题
-9.6 动画前沿趋势
--多选题
-10.1 .基本概念
--多选题
-10.2 设计目标
--多选题
-10.3 传输数据分析
--多选题
-10.4 常用同步方案 1
-10.4 常用同步方案 2
-10.4 常用同步方案 3
-10.4 常用同步方案 4
--多选题
-10.5 方案对比
--多选题
-11.1 基本图元
--单选题
-11.2 图元距离(上)
--单选题
-11.2 图元距离(下)
--单选题
-11.3 图元相交测试+ 其他几何方法
--单选题
-12.1 著名物理引擎介绍
--单选题
-12.2 物理引擎原理(上)
--单选题
-12.3 物理引擎原理(下)
--单选题
-12.4 游戏中的物理体
--单选题
-12.5 物理引擎使用入门
--单选题
-13.1开发语言
--13.1开发语言
--单选题
-13.2 开发环境
--单选题
-13.3 腾讯开发组件介绍
--单选题
-13.4 网络通信+业务框架介绍
--多选题
-14.1 进程间通信(上)
-14.2 进程间通信(下)
-14.3 通信格式
-14.4 并发模型
-14.5 超时处理
-14.6 大系统小做(上)
--多选题
-14.7 大系统小做(下)
-14.8 架构层面的技术支持(上)
--单选题
-14.9 架构层面的技术支持(下)
-14.10 分布系统的关键能力
--多选题
-15.1 游戏人工智能综述
-15.2 人工智能在游戏中主要方法 上
--多选题
-15.3人工智能在游戏中主要方法 (下)
-15.4 人工智能在游戏制作中的应用领域1
--多选题
-15.5 人工智能在游戏制作中的应用领域2
-15.6 人工智能在游戏制作中的应用领域3
--多选题
-15.7 人工智能在游戏运营中的应用实践(上)
-15.8 人工智能在游戏运营中的应用实践(下)
--多选题
-16.1 游戏支撑系统(1)
--单选题
-16.2 游戏支撑系统(2)
--单选题
-16.3 游戏支撑系统(3)
--单选题
-16.4 游戏支撑系统(4)
--单选题
-16.5 游戏支撑系统(5)
-17.1 游戏逻辑服务器(上)
--单选题
-17.1 游戏逻辑服务器(下)
-17.2 外挂与反外挂(上)
-17.2 外挂与反外挂(下)
--多选题
-18.1运行环境
--18.1运行环境
--多选题
-18.2物理部署
--18.2物理部署
--多选题
-18.3系统的可运维性
--多选题
-18.4运维案列分析
--多选题