1

So I have elements that are position: absolute and then I use Math.random() to set their left:#random and top:#random position.

However a very weird thing is happening. It should be completely random, thus they should be placed completely randomly. However time and time again, they are placed very closely together. Instead of being spread apart.

enter image description here

however you can clearly see, their positions are indeed random: enter image description here

Here is the code I use to generate them:

const Clouds = function(props) {
    const clouds = []
    for (let i = 0; i < props.cloudNum; i++) {
        const style = {
            position: 'absolute',
            height: 50 * props.cloudSize + 'px',
            top: Math.random() * 100 + '%',
            left: Math.random() * 100 + '%',
        }
        clouds.push(<Cloud key={i} style={style} />)
    }
    return <div className={props.side}>{clouds}</div>
}

is there a temporal component to Math.random, and because they are generated in sequence their random numbers are similar?

zver
  • 33
  • 3
  • 5
    Is this always happening, or just sometimes? Because truly random numbers (not that those generated by `Math.random()` are *truly* random, but they should be good enough for most purposes) will "clump together" more often than people naively expect "random" numbers to do. But if you're saying that the values are always in a narrow range, say always 51.xxxx, rather than anywhere from 0-100, then that does seem very strange and I can't explain it from the code snippet given. – Robin Zigmond Apr 29 '19 at 08:50
  • 2
    Random doesn't mean equally spread. Truly random data should have some clusters of points close together as every point should have an equal chance of being chosen. Is this happening around a specific range of points every time or does it change? – James Coyle Apr 29 '19 at 08:51
  • cryptoObj.getRandomValues() is the alternate for Math.random try this – Atchutha rama reddy Karri Apr 29 '19 at 08:54
  • https://dilbert.com/strip/2001-10-25 – Erki Aring Apr 29 '19 at 09:04
  • I see. To answer @RobinZigmond, no they are not always around 51. just a suspiciously large amount of times. but you guys raise a good point. I might just be misunderstanding what random means – zver Apr 29 '19 at 14:17

3 Answers3

2

In fact, although they look like similar numbers they are not (remember that you are multiplying by 100), this means that your space of random numbers goes from 0 to 100 (since the decimals in the drawing barely have value, as is the case that you ask).

Keep in mind that if your space is 100 clouds only generating 13 clouds there is more than a 50% probability that two clouds occupy the same position by the birthday problem.

https://en.wikipedia.org/wiki/Birthday_problem

kb05
  • 69
  • 4
0

There's no temporal component - it's just generated by the system. Here's a good thread explaining it. The random algorithm depends on the JavaScript engine (there's a V8 answer in that thread) but the function always produces a floating-point number between 0 and 1 inclusive. It's an incredibly large coincidence that your code yielded two numbers that close.

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
  • I should have said, that keeps happening all the time. here another example: http://prntscr.com/niaw1v – zver Apr 29 '19 at 14:15
0

It's a coincidence that you get similar value. Try as many times as you want with my snippet to test it your own.

Note that my objects are much smaller than yours, not having elements overlapping give a better sense of randomness. IMHO, if you are generating clouds (depends on purposes) it could be better to use perlin noise

const container = document.getElementById('container');

const Clouds = function() {
   
    for (let i = 0; i <10; i++) {        
         let myCloud = document.createElement("div");
        myCloud.style.height = '15px';
                myCloud.style.width = '15px';
        myCloud.style.position = 'absolute';
        myCloud.style.background =  '#fff';
        myCloud.style.border = '1px solid #ccc';
        myCloud.style.left = Math.random()*100+'%';
        myCloud.style.top = Math.random()*100+'%';
        container.appendChild(myCloud);
    }
   
}

function generate() {
 container.innerHTML = '';
 Clouds();
}
#container {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  background: red;
}

button {
position: absolute;
z-index: 999;
}
<div id="container"></div>
<button onClick="generate()">Generate</button>
Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
  • I'm sorry I should have explained it better. this keeps happening again and again. I will try using the perlin noise. thanks! :) – zver Apr 29 '19 at 14:11
  • However even with your snippet it's very common to get most objects on a "single" axis. It's strangle Like this:http://prntscr.com/niavcw – zver Apr 29 '19 at 14:13
  • This is not so common as you perceive, and it is less common as you increase your container size. This is related to birthday problem above. If you do not want _similar coords_ it is better to look to a distribution algorithm than a random generator. – Mosè Raguzzini Apr 29 '19 at 14:20