第7章 周期と偶然のあいだ
機械的に同じ速さで動く円は、動きの仕組みを知るには分かりやすい例です。しかし呼吸、波、風のような動きは、行って戻る変化や、完全には予測できない揺れを含みます。周期と乱数は、その 2 種類の変化を作ります。
7.1 sin が往復運動を返す
sin(サイン)は、三角関数と呼ばれる計算の一つです。この本では、公式も計算方法も覚えません。数字を少しずつ増やして sin へ渡すと、答えが -1 から 1 の間をなめらかに行き来することだけを、画面の動きに使います。-1 は「マイナス 1」と読み、0 より小さい数です。
def setup
createCanvas(500, 240)
end
def draw
background(245)
wave = sin(frameCount * 0.04)
x = width / 2 + wave * 180
fill(235, 90, 120)
ellipse(x, height / 2, 60, 60)
end
frameCount(フレーム・カウント)は、draw が何回呼ばれたかを表す値です。1、2、3 と増えていく番号へ 0.04 を掛け、sin へ渡します。戻ってくる wave は -1 から 1 の間なので、180 を掛けると -180 から 180 の範囲になります。
この計算を自分で解く必要はありません。まず 0.04 を 0.02 へ変えて実行してください。動きが遅くなれば、数字と速さの関係を確認できています。次に元へ戻し、180 を 80 へ変えると、左右へ動く幅が小さくなります。
0.04 を小さくするとゆっくり、大きくすると速く往復します。180 は移動幅です。速度と振れ幅を別の数字で調整できる点が重要です。
7.2 同じ周期を大きさへ使う
同じ wave を位置ではなく大きさへ使います。次の変更部分を、7.1の長いコードにある draw の中身と置き換えます。
wave = sin(frameCount * 0.04)
size = 100 + wave * 40
ellipse(width / 2, height / 2, size, size)
大きさは 60 から 140 の間を往復します。wave をそのまま大きさにすると負の値になる時間があります。中心となる 100 を足すことで、扱いやすい範囲へ移しています。
周期の式は、横移動、透明度、色、回転にも使えます。同じ波を複数の性質へ使うと、画面全体が同じ呼吸を持ちます。別の速さを使うと、少しずつずれる関係が生まれます。
7.3 random は毎回別の値を選ぶ
random(400) は、0 以上 400 未満の範囲から値を返します。draw のたびに位置を選ぶと、円が激しく飛びます。
def setup
createCanvas(500, 300)
background(20)
noStroke
end
def draw
x = random(width)
y = random(height)
size = random(4, 28)
fill(255, 220, 120, 120)
ellipse(x, y, size, size)
end
背景を setup に置いたため、点が消えずに積もります。実行するたび別の星空になります。
乱数は「自然らしさ」を自動で作る命令ではありません。位置も色も大きさもすべて乱数にすると、どこを見る画面なのか分かりにくくなることがあります。何を規則で揃え、どこだけ偶然に任せるかが制作上の選択です。
7.4 noise は隣り合う値がつながる
random は呼ぶたび大きく飛べます。noise は、近い入力へ近い値を返すため、連続した揺れを作りやすい機能です。
def setup
createCanvas(500, 240)
end
def draw
background(245)
value = noise(frameCount * 0.01)
x = value * width
fill(60, 130, 220)
ellipse(x, height / 2, 60, 60)
end
noise(ノイズ)の戻り値は通常 0 から 1 の範囲です。width(ウィズ、キャンバスの幅)を掛けると、キャンバスの左端から右端の範囲へ変換できます。
二つの変化を横へ並べる代わりに、上段と下段へ点として記録すると形を比べられます。次はそれだけで実行できる完成コードです。
def setup
createCanvas(600, 300)
background(245)
noStroke
120.times do |i|
x = 30 + i * 4.5
wave_y = 80 + sin(i * 0.18) * 35
fill(235, 90, 120)
ellipse(x, wave_y, 6, 6)
noise_y = 220 + (noise(i * 0.08) - 0.5) * 90
fill(50, 130, 230)
ellipse(x, noise_y, 6, 6)
end
end
上段の赤い点は、同じ波の形を繰り返します。下段の青い点は滑らかにつながっていますが、次の山や谷の大きさは一定ではありません。
7.5 偶然を保存する
乱数を使った作品で気に入った結果が出たら、その画面を保存する方法があります。再現できることも重要なら、randomSeed で乱数の並びを固定できます。
def setup
createCanvas(500, 300)
randomSeed(42)
background(20)
100.times do
fill(255, 220, 120, 140)
ellipse(random(width), random(height), random(4, 24), random(4, 24))
end
end
同じシード値 42 なら、同じ乱数列を得られます。偶然に見える構図を選び、あとから同じ版を作れるようになります。
第2部では、値が時間で変わる仕組みを見ました。第3部では、変化のきっかけをマウスとキーボードから受け取ります。
7.6 波と偶然を同じ海へ置く
sinで規則的に上下する線を作り、noiseで少しだけ位置を揺らすと、完全な規則でも完全な乱数でもない水面を作れます。さらにrandomで小さな光を散らすと、波、風、反射という別々の役割を同じ画面へ置けます。
ここでは完成コードを一つに決めません。星空のコードを青い背景へ変えて水面にする、往復する円を船に見立てて三角形を足す、noiseの動きを雲へ使う、のどれかから始めます。同じ数の変化が、何に見立てるかで別作品になることを試す節です。
7.7 模様をもっと探すなら
第6章の行数と列数、第7章のsin、noise、randomを組み合わせると、同じコードから規則的な模様と崩れた模様を作り分けられます。まず一つだけ選びます。
- 行と列の数を増やし、遠くから見た印象を比べる
sinを位置や大きさへ使い、並びを波打たせるnoiseを色へ使い、少しずつ変わる帯を作る- 第6章のフラクタルで、円を四角や枝へ変える
さらに探したくなったら、「セル・オートマトン」「フラクタル」「ジェネラティブアート」「Genuary」という言葉を、画像や作品例から調べられます。見つけた作品を全部まねるのではなく、気になった規則を一つだけ今のスケッチへ持ち帰ります。
この章の小さな区切り
random、sin、noiseのどれか一つを画面で確認した- 数字を一つ変え、変化の速さか散らばり方を比べた
- 余裕があれば、星空、水面、雲のどれかに見立てた
三つを全部使わなくても、一つの変化を観察できれば保存して次章へ進めます。