必ず元の場所に戻るランダムウォークのサンプル
概要
一定量の移動幅を持つランダムウォークをし終わったときに、必ず元の場所に戻ってくるコードのサンプルです。
原理
プラス方向に移動した分だけマイナス方向にも動く(どのタイミングで逆の動きをするかはランダム)ことにより、移動量の合計が0に戻る仕組みです。
デモ
こんな風に横移動した後に最初の位置に戻ります。
デモページ:
http://codepen.io/butchi/pen/XMqevj
サンプルコード
シャッフルにはFisher–Yatesアルゴリズムを用いましたが、
Underscoreの_.shuffleとかで代用できるので読み飛ばせばOK。
const LENGTH = 25; // 25×2の50回ランダムウォークする
const MAGNITUDE = 10; // 振動ピクセル幅
// 入力した正の数を正負両方含む配列(倍のサイズ)として返す
function double(arr) {
let ret = [];
arr.forEach((num) => {
ret.push(num);
ret.push(-num);
});
return ret;
}
// Fisher–Yatesアルゴリズムによる配列シャッフル
function shuffle(arr) {
let ret = [].concat(arr);
for(let i = ret.length - 1; i > 0; i--){
let r = Math.floor(Math.random() * (i + 1));
let tmp = ret[i];
ret[i] = ret[r];
ret[r] = tmp;
}
return ret;
}
// ランダムウォークの対象要素
let walkerElm = document.querySelector('.walker')
// ランダムウォークを始めるボタン
let startBtn = document.querySelector('.btn-start');
startBtn.addEventListener('click', () => {
// ランダム数値配列(mapを有効にするため一旦0で初期化)
let deltaXArr = (new Array(LENGTH)).fill(0).map(() => {
return Math.random() * MAGNITUDE;
});
let deltaXArr2 = double(deltaXArr);
let shuffleXArr = shuffle(deltaXArr2);
// 累積変動量
let deltaX = 0;
for(let i = 0; i < LENGTH * 2; i++) {
setTimeout(() => {
deltaX += shuffleXArr[i];
walkerElm.style.transform = `translateX(${deltaX}px)`;
}, i * 50);
}
});
今回は簡単のため横軸のみ移動にしましたが、
X軸とY軸だったり絶対値(abs)と偏角(arg)の2つの配列で処理すれば平面上のランダムウォークも実装できます。
Author And Source
この問題について(必ず元の場所に戻るランダムウォークのサンプル), 我々は、より多くの情報をここで見つけました https://qiita.com/butchi_y/items/b1b2a2cd5d9fc81a746e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .