Why does this random() distribution look asymmetric?

不想你离开。 提交于 2019-12-07 02:28:59

问题


Edit: This is using Google Chrome 36

I was messing around with html5 canvas, generating points randomly distributed inside a cube and projecting that onto a 2D canvas. Surprisingly, the results don't look very symmetric at all, and I suspect that Javascript's Math.random() is letting me down.

Can anyone tell me why this is happening? Is it possible to make it actually look random, without making it slower?

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/ (Takes a while to load)


回答1:


Chrome has a documented issue that subsequent calls to Math.random() are correlated. In your algorithm, correlated values will tend to fall on a line on the canvas. An extra call to Math.random() breaks that correlation. I haven't seen reports that other browsers are affected.

Just call Math.random() an extra time on each call, and you'll get what you want.

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);
}

Updated on: http://jsfiddle.net/y10tvj26/5/




回答2:


This is a case of pseudorandom number generation vs. random generation. Basically, there are numbers that will occur more often than others when you generate pseudorandom numbers (such as with the Math.random() function). See here for more information about the difference.

As far as actually making it look more "random", I would note that for a smaller range of i the image does look random, it's only when you choose a very large value that the flaws become apparent. Additionally, I don't believe seting your own seed for Math.random will be an adequate solution either, because you will still see degradation in the "randomness" when you iterate a very large number of times.

A potential solution would be to use a different library to generate pseudorandom numbers and see if it produces a better looking output. Other than that, you're pretty much constrained to the deterministic properties of computers (at least until powerful quantum computers show up on the market!).

Edit - This problem is unique to Google Chrome's implementation of Math.random() and documented in the following locations: 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



来源:https://stackoverflow.com/questions/25272799/why-does-this-random-distribution-look-asymmetric

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!