震える・撒き散らす(乱数)

2019-05-07

本章のあらすじ

  • 乱数とは
  • Processingと乱数
  • 乱数で撒き散らす
  • 乱数で震えさせる
円の外周付近に乱数で繊毛を散布

乱数

この世界には、予測不可能な状態(ランダム)が至るところに隠れています。

  • サイコロの目はいくつが出るか?
  • アナログテレビの砂嵐
  • 雨音
  • 分子運動

プログラミングにおいても、擬似的にランダムな数値を発生させる「乱数」という仕組みがあります。乱数をスケッチに組み込むことで、作者の予想を超える結果を生み出すことができます。

ランダムな数値を生成: random()

random() を使うと、指定した範囲の中でランダムな数値を生成することができます。

random( 最小値 , 最大値 )

このように書くと、最小値以上、最大値未満の数値を生成してくれます。具体的な数値を入れてみましょう。

// 0 〜 99.999… の範囲でランダムな数値を生成
random(0 , 100)

このような感じです。 random() はこれまで出てきた mouseXsecond() などと同様、数値のように扱うことができます。

random() は実行するたびに値が変わる

ちなみに最小値のほうは省略可能で、この場合の範囲は 0 〜最大値 となります。

// 0 〜 199.999… の範囲でランダムな数値を生成
random(200)

撒き散らす

それでは、 random() を使って絵を描いていきましょう。例えば draw() ブロックの中で円を描く位置をランダムにすると、円が撒き散らされたように積み重なっていきます。

void setup() {
  size(600, 600);
  background(255, 255, 255);
}

void draw() {
  // 円の位置をランダムに
  ellipse(
    random(0, 600),
    random(0, 600),
    100,
    100
  );
}

円のサイズや線の幅もランダムにすると、さらにダイナミックな印象を受けます。

void draw() {
  // 線幅をランダムに
  strokeWeight(random(4, 50));

  ellipse(
    random(0, 600),
    random(0, 600),
    random(50, 300),
    random(50, 300)
  );
}

塗りや枠線の色をランダムに変化させてみるのもおもしろいでしょう。

void draw() {
  noStroke();
  // 塗り色をランダムに
  fill(
    random(0, 255),
    random(0, 255),
    random(0, 255)
  );
  
  ellipse(
    random(0, 600),
    random(0, 600),
    random(50, 300),
    random(50, 300)
  );
}

飛沫ブラシ

もうひとつ、ペンツールと組み合わせた例を試してみましょう。 mouseDragged() ブロックの中で複数の円を描きますが、その位置と大きさをランダムにしてみます。

void setup() {
  size(600, 600);
  background(255);
  noStroke();
  fill(0);
}

// マウスをドラッグしたときに実行されるブロック
void mouseDragged() {
  // ランダムにずらした位置に、ランダムなサイズの円を描く
  ellipse(
    mouseX + random(-10, +10),
    mouseY + random(-10, +10),
    random(1, 10),
    random(1, 10)
  );
}

void draw() {
}

(→brush

震える

アニメーション」の回では、1フレームごとに少しずつ変化させると動いて見える…という話をしましたね。それでは、1フレームごとにランダムに位置をずらすと、どのように動いて見えるでしょうか?

void setup() {
  size(600, 600);
  noStroke();
  fill(0, 0, 0);
}

void draw() {
  // 背景を塗りつぶす
  background(255, 255, 255);

  // 円の位置を、キャンバス中央からランダムに少しだけずらす
  ellipse(
    300 + random(-10, +10),
    300 + random(-10, +10),
    100, 100
  );
}

位置が秩序なく小刻みに変化するので、震えているように見えます。

震えているように見える

動かす幅を変えたり、ランダムにする対象を位置ではなくサイズにしてみたり。いろいろ試して、見えかたの違いを自分の目で感じてみてください。

揺らぎペン

もうひとつ、ペンツールと組み合わせた例を試してみましょう。 mouseDragged() ブロックの中で、線の幅と不透明度をランダムにしてみます。

void setup() {
  size(600, 600);
  background(255, 255, 255);
}

// マウスをドラッグしたときに実行されるブロック
void mouseDragged() {
  // 線の幅をランダムに
  strokeWeight(random(1, 20));
  // 線の不透明度もランダムに
  stroke(0, 0, 0, random(100, 255));

  // 線を引く
  line(pmouseX, pmouseY, mouseX, mouseY);
}

void draw() {
}

線に揺らぎが加わり、どこか水墨画らしさを感じる?趣が出ました。 (→fruc_pen

確率を制御する

if文と組み合わせると、確率を制御することができるようになります。

例えば、30%の確率で実行したい処理があったとします。0〜100の範囲で乱数を発生させて、30より小さなときだけ処理を実行すれば…ほぼ30%の確率になりそうですね。

if (random(0, 100) < 30) {
  // 30%の確率で実行したい処理を書く
}

試しに、30%の確率で塗りを黒色にするスケッチを作ってみましょう。

void setup() {
  size(600, 600);
  background(255, 255, 255);
}

void draw() {
  if (random(0, 100) < 30) {
    // 30%の確率で塗りを黒色に
    fill(0, 0, 0);
  }
  else {
    // それ以外は塗りを白色に
    fill(255, 255, 255);
  }
  
  ellipse(
    random(0, 600),
    random(0, 600),
    100, 100
  );
}

演習:これまでのスケッチに乱数を組み込んでみよう

これまで作ってきたスケッチに乱数を組み込んで、味つけしてみましょう。

  • ランダムで色や太さ・座標の変わるペン
  • ランダムに挙動を変える時計

本章のまとめ

  • random() を使うと、指定した範囲のランダムな数値が得られる
  • random() は実行するたびに異なる数値が得られる
  • 乱数は震えさせたり、撒き散らしたり、確率を制御したりするとき役に立つ

関連

  • 連続的に変化する多次元ノイズ:noise()