标题打这么多是因为去年的某篇文章导致的...
除了骗还是骗
这个世界充满了欺骗...
目前还在研究乱数这东西
http://rosettacode.org/wiki/Linear_congruential_generator
有兴趣可以先阅读上面的文章
目前基本的乱数产生都是用线性同余法来达成
觉得不够乱的话就是要自己写了
方法似乎百百种
接着再阅读这篇
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
应该许多人研究过这东西
许多沙盒游戏也都是使用perlin noise来达到理论上无限大的地图
使用种子码来减少资料储存量
产生看似随机生成的世界
不过理论跟实际要使用差距蛮大的
网络上能找的资料都是很基本的东西
要实际使用还需要琢磨一番
如果照着网络上的文献来实作会发现一个范围的perlin noise的产生
跟即时产生差异还颇大的
因为还牵扯到图块接合等等问题(map tile)
需要做内插法平顺等等处理
说到这里
可以参考minecraft spigot-api里头的perlin noise
github.com/SpigotMC/Spigot-API/tree/master/src/main/java/org/bukkit/util/noise
(太长了把http截掉)
=======吃完饭之后突然忘了自己要说什么========
说点比较不容易看懂的地方
如果照着第二篇的公式来看
很快就会发现过了一定数值后结果会一直是1.0
我想这应该是同余法的极限吧
如果SEED一直不变
完全无法产生够大范围的乱数
(1.0-((x*(x*x*15731+789221)+1376312589)&7fffffff)/1073741824.0);
来分析一下上面的算式
基本上的目的就是要让1.0后面那串结果在0.0与2.0之间
这样相减才能产生正负
注意绿色的符号
那是位元运算子后面的7fffffff应该是0x7fffffff
也就是整数最大值2,147,483,647
位元运算子的用处就是确保计算后的直为正数且在该范围内
位元运算子算相当好用
接下来可以参考C或者C++的RAND与SRAND之header
在stdlib.h里
利用第一个种子码计算出下一个数值后(可能为长整数时期)
将其当成下次的种子码如此反复执行到我们指定的次数
不过这种作法我们发现每次乱数的顺序都是一样的
所以现在改善的做法都是用系统时间来当种子码(准度到秒)
不过还是有不够随机的情况产生
所以第一个种子码很重要
接下来就是我们想控制的部分了
由于PERLIN NOISE是有规律的
因此需要使用不同的频率与放大的倍率将数个阶(octave)合成起来
这边可以另外参考SIVI的作品
https://github.com/philfrei/SiVi
我目前的想法是
如果之后要带入计算的座标极大时
是否会降低运算的效能
目前还在测试
所以猜测把座标加入seed的产生
或许是个效率较高的作法