Why are my particles drifting? ( aka Is Math.random() broken or is it my algorithm? )

Viewed 732

Using Javascript I'm crudely simulating Brownian motion of particles, but for some reason I don't understand my particles are drifting up and to the left.

The algorithm is pretty straight forward. Each particle is a div and I simply add or subtract a random number from each div's top and left position each round.

I read up on Math.random() a little, and I've tried to use a function that returns a random number from min to max inclussive:

// Returns a random integer between min and max  
// Using Math.round() will give you a non-uniform distribution!  
function ran(min, max)  
{  
    return Math.floor(Math.random() * (max - min + 1)) + min;  
} 

Here is the function for the movement of the particles:

var x, y, $elie, pos, nowX, nowY, i, $that;    

function moveIt()
{
    $("div.spec").each(function(i, v) {
        x = ran(-5, 5);
        y = ran(-5, 5);
        $elie = $(v);
        pos = $elie.position();
        nowX = pos.left;
        nowY = pos.top;

          // The min and abs are to keep the particles within a box
          // The drift occurs even if I remove min and abs
        $elie.css("left", Math.min(Math.abs(nowX + x), 515));
        $elie.css("top",  Math.min(Math.abs(nowY + y), 515)); 
    });
}

And here is how the particles are initially set up an the setInterval started.

$(function() {
    $("body").append("<div/>").attr("id","box");
    $elie = $("<div/>").attr("class","spec");
    // Note that math random is inclussive for 0 and exclussive for Max
    for (i = 0; i < 25; ++i)
    {
        $that = $elie.clone();  
        $that.css("top", ran(0, 495));
        $that.css("left", ran(0, 495));            
        $("#box").append($that);            
    }          
    timer = setInterval(moveIt, 60);
    $("input").toggle(function() {
        clearInterval(timer);
        this.value = " Start ";
    }, function() {
        timer = setInterval(moveIt, 60);        
        this.value = " Stop ";            
    });        
});

My problem is that using the min and max from above ( -5, 5 ), all the particles drift up and to the left very fast.

jsFiddle example of drift (-5, 5)

Example of drift even with the removal of .min() and .abs().

To counteract this, I have to use a min and max of -1, 5.

jsFiddle example of no drift (-1, 5)


Here is the CSS for the div all the particles are contained in:

#box {
    width:500px;
    height:500px;
    border:2px #000 solid;
    position: relative; }

Here is the default CSS for each particle:

div.spec {
    width:5px;
    height:5px;
    background-color:#00DDAA;
    position:absolute; }

What is going on? Why does a min and max of -5 and 5 cause an upward and leftward drift?

A test of the random function ran() doesn't seem to show such a persistent negative drift.

jsFiddle example of testing ran()



The ran() function was taken from the MDC Math.random() page.

2 Answers
Related