Подтвердить что ты не робот

Почему мои частицы дрейфуют? (aka Is Math.random() сломан или это мой алгоритм?)

Использование 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 ";            
    });        
});

Моя проблема заключается в том, что с помощью min и max сверху (-5, 5) все частицы очень быстро перемещаются вверх и влево.

jsFiddle пример дрейфа (-5, 5)

Пример дрифта даже при удалении .min() и .abs().

Чтобы противодействовать этому, я должен использовать min и max of -1, 5.

jsFiddle пример дрейфа (-1, 5)


Вот CSS для div все частицы содержатся в:

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

Вот CSS по умолчанию для каждой частицы:

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

Что происходит? Почему min и max -5 и 5 приводят к смещению вверх и влево?

Тест случайной функции ran(), похоже, не показывает такого постоянного отрицательного дрейфа.

jsFiddle пример тестирования ran()



Функция ran() была взята из страницы MDC Math.random().

4b9b3361

Ответ 1

Ваша ошибка заключается в использовании

pos = $elie.position();

а не

pos = $elie.offset();

Это не имело бы никакого значения, если бы они были добавлены в родительский div, но ваши элементы неправильно добавлены в родительский div, они добавляются непосредственно в тело документа. Итак, ваша другая ошибка:

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

Если вы хотите, чтобы div имел идентификатор "box", строка должна читать:

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

В противном случае вы фактически даете "тело" идентификатор "окна"

EDIT:

Наиболее эффективным способом добавления div будет следующее (как отмечено этим сообщением):

$(document.createElement('div')).appendTo('body').attr('id', 'box')

Ответ 2

Вместо использования .position() попробуйте .offset(). Похож на он работает.

Position.

Offset.

Это работает так, потому что вы устанавливаете абсолютные значения "left" и "top" в CSS. Вместо этого вы можете использовать этот Пример:

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