代码之家  ›  专栏  ›  技术社区  ›  Peter Ajtai

为什么我的粒子会漂移?(又称math.random()坏了还是我的算法?)

  •  22
  • Peter Ajtai  · 技术社区  · 14 年前

    使用javascript,我可以粗略地模拟粒子的布朗运动,但出于某种原因,我不明白我的粒子正在向上和向左漂移。

    算法是非常直接的。每个粒子都是 div 我只是简单地从每一个数字中加上或减去一个随机数 div top left 每轮定位。

    我读了起来 Math.random() 有一点,我尝试使用一个函数返回 min max 含糊不清的:

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

    以下是粒子运动的函数:

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

    这是粒子最初是如何建立的 setInterval 起动。

    $(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 ";            
        });        
    });
    

    我的问题是使用 最大值 自上而下( -5, 5 所有的粒子都很快地向上和向左漂移。

    jsFiddle example of drift (-5, 5)

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

    为了抵消这一点,我必须使用 最大值 属于 -1, 5 .

    jsFiddle example of no drift (-1, 5)


    这是用于 div 所有颗粒都包含在:

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

    以下是每个粒子的默认CSS:

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

    怎么回事?为什么最小值和最大值为 -5 5 导致向上和向左漂移?

    随机函数的检验 ran() 似乎没有显示出如此持久的负漂移。

    jsFiddle example of testing ran()



    这个 RAND() 函数取自 the MDC Math.random() page .

    2 回复  |  直到 11 年前
        1
  •  8
  •   Community CDub    7 年前

    你的错误是使用

    pos = $elie.position();
    

    而不是

    pos = $elie.offset();
    

    如果它们被添加到父DIV中,这不会有什么不同,但是您的元素没有被正确地添加到父DIV中,它们被直接附加到文档正文中。所以你的另一个错误是:

    $("body").append("<div/>").attr("id","box");
    

    如果希望DIV的ID为“box”,则该行应为:

    $box = $("<div/>").attr("id","box");
    $("body").append($box)
    

    否则,你实际上是在给“body”提供“box”的ID

    编辑:

    附加DIV的最有效方法如下(如 this post ):

    $(document.createElement('div')).appendTo('body').attr('id', 'box')
    
        2
  •  2
  •   atiquratik jaywon    11 年前

    而不是使用 .position() 尝试 .offset() 相反。看起来像 it works .

    Position .

    Offset .

    它是这样工作的,因为你设定了绝对值' left “和” top 价值观 CSS . 相反,你可以用这个 Example :

    $elie.css("margin-left", nowX + x);
    $elie.css("margin-top",  nowY + y);