修改:这是使用Google Chrome 36
我正在弄乱html5画布,生成随机分布在立方体内的点并将其投影到2D画布上。令人惊讶的是,结果看起来并不完全对称,我怀疑Javascript的Math.random()让我失望。
谁能告诉我为什么会这样?是否有可能使它看起来实际上是随机的,而不是让它变慢?
var ctx = canvas.getContext('2d');
for (var i = 0; i < 10000000; i++) {
var x = Math.random()*2-1, y = Math.random()*2-1, z = 2+Math.random()*2-1;
x = (.5 + .5*x/z) * canvas.width;
y = (.5 + .5*y/z) * canvas.height;
ctx.fillRect(Math.floor(x), Math.floor(y), 1, 1);
}
http://jsfiddle.net/y10tvj26/(加载需要一段时间)
答案 0 :(得分:4)
Chrome有documented issue,后续对Math.random()的调用是相关的。在您的算法中,相关值将倾向于落在画布上的一条线上。对Math.random()的额外调用打破了这种相关性。我还没有看到其他浏览器受到影响的报道。
每次通话只需拨打Math.random()
一次额外的时间,您就可以获得所需的内容。
var ctx = canvas.getContext('2d');
function r() {
Math.random();
return Math.random();
}
for (var i=0; i<10000000; i++) {
var x = r()*2-1, y = r()*2-1, z = 2+r()*2-1;
x = (.5 + .5*(x/z)) * canvas.width;
y = (.5 + .5*(y/z)) * canvas.height;
ctx.fillRect(x, y, 1, 1);
}
答案 1 :(得分:-3)
这是伪随机数生成与随机生成的情况。基本上,当您生成伪随机数时(例如使用Math.random()函数),有些数字会比其他数字更频繁地出现。有关差异的详细信息,请参阅here。
实际上让它看起来更像&#34;随机&#34;,我会注意到,对于较小范围的i,图像确实看起来是随机的,只有当你选择一个非常大的值时缺陷变得明显。另外,我不相信为Math.random设置自己的种子也是一个合适的解决方案,因为你仍会看到随机性的降低&#34;当你迭代很多次时。
一个潜在的解决方案是使用不同的库来生成伪随机数并查看它是否产生更好看的输出。除此之外,你几乎受限于计算机的确定性属性(至少在强大的量子计算机出现在市场上之前!)。
修改 - 此问题是Google Chrome在Math.random()的实施中所独有的,并记录在以下位置: Why is Google Chrome's Math.random number generator not *that* random? https://code.google.com/p/chromium/issues/detail?id=276886 https://code.google.com/p/v8/issues/detail?id=558