サイン波を計算して虹色を描く方法

サイン波を計算して虹色を描く方法
ok-scratch

スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。

マウスクリックで虹色のドットを打つペンアートを作ろう。sin関数でRGB値を計算し、R×65536+G×256+Bでペンカラーを直接設定する方法を学べる。Scratchで数学が実用的に活きるテクニック。

さぁ、スクラッチでナニ作る!?

動画で見てみよう

ok-scratch ok-scratch
チャンネル登録して応援よろしく!チャンネル登録する

チュートリアルの元になった作品

小技:サイン波を計算して虹色を描く

小技:サイン波を計算して虹色を描く

by ok-scratch
プレイしておこう プレイしておこう
今回のスクラッチを作る参考作品です。sin関数で三波が120度ずつズレてRGBをぐるぐる計算してるのがマジでエグい。「色相」変数1個を増やし続けるだけで虹色が自動的に循環するし、そのRGBをR×65536+G×256+Bって掛け算一発でペンカラーに直接叩き込む発想がキレッキレ。数学の波が実際の色のグラデーションとして現れる感覚、体験してみる価値あり。この計算の仕組みを一緒に見ていこう。

今回の目標

マウスをクリックした場所に、sin関数で計算した虹色のドットを打つペンアートを作るよ。RGB値を数式で求めてペンカラーを直接設定する仕組みを組み上げる。

スターター作品をリミックスしよう

このチュートリアルにはスターター作品があります。使わなくても大丈夫だけど、最低限の素材などが用意されてるので便利です。
スターター作品をダウンロード

#1ペンの初期設定

ok-scratch ok-scratch
まずはペン拡張機能の下準備から。描き始める前に画面をまっさらにして、ペンの太さと透明度を決めておくよ。

準備

スプライト名を「ペンプロッター」に変更

スプライト名を「ペンプロッター」に変更

実装

step-0

イベントgreenflag が押されたときでスタートしたら、スプライト本体は見た目隠すで隠す。このスプライトはあくまで「ペンを持つ手」だから、画面に見える必要はないんだ。ペン全部消すで前の描画を全消しして、ペンサイズを8にセット。

そしてペンペンの[COLOR_PARAM]を[VALUE]にするでペンの透明度を100に。ループが回り始めてから色が確定するまでの一瞬に、ゴーストドットが描画されるのを防ぐための保険だよ。

確認プレビューしておこう 確認プレビューしておこう
旗を押すとペンプロッターが消えて、画面がクリアされたね。

#2サイン波で赤を計算

準備

変数「★色相」を追加

現在の色相角度。毎ループ5ずつ増加し、RGBの計算基準になる

変数「★色相」を追加

変数「★赤の値」を追加

ペンの赤チャンネル値(0〜255)。HUEのサイン波から計算される

変数「★赤の値」を追加

実装

step-1

制御ずっとループの中で、虹色を生み出す計算が始まるよ。まずは「★色相」変数を毎ループ5ずつ増やして、そこから赤チャンネルの値を算出するんだ。

普通に色を変えるならScratchのペン「色」パラメータをいじるだけでいいけど、この作品ではサイン関数(sin)を使ってRGB値を直接計算しているのがミソ。「★赤の値」の計算式は 128 + 127 × sin(★色相) で、sinの結果(-1〜1)を0〜255の範囲にマッピングしてるんだ。

ok-scratch ok-scratch
sin(サイン)は波の形を数式で表す関数で、音波や光の波長、振り子の動きにも使われてるよ。-1から1の間をなめらかに行ったり来たりするから、色の変化も「パキッ」と切り替わるんじゃなくて、じわ〜っとグラデーションになる。数学の授業で出てくるやつが、こんなところで大活躍するっていう。

#3緑を120度ずらして計算

ok-scratch ok-scratch
赤と同じ要領で「★緑の値」も計算するよ。ただし、ここがレインボーの核心――sinに渡す角度を120度ずらすんだ。

準備

変数「★緑の値」を追加

ペンの緑チャンネル値(0〜255)。HUEに120度オフセットしたサイン波から計算される

変数「★緑の値」を追加

実装

step-2

式は 128 + 127 × sin(★色相 + 120) になる。赤と全く同じ波だけど、120度先にスタートしてるから、赤がピークのときに緑はまだ途中、っていう具合にタイミングがずれる。360度を3色で均等に分けてる(120 × 3 = 360)から、常にどれか1色がピークにいて鮮やかな色が途切れないんだ。

#4青を240度ずらして完成

ok-scratch ok-scratch
最後に「★青の値」を `128 + 127 × sin(★色相 + 240)` で計算。赤が0度、緑が120度、青が240度――これで3色が等間隔に並んで、完璧な虹色サイクルの完成だよ。

準備

変数「★青の値」を追加

ペンの青チャンネル値(0〜255)。HUEに240度オフセットしたサイン波から計算される

変数「★青の値」を追加

実装

step-3

ここまでのR/G/B計算を俯瞰すると、やってることは3つの波が120度ずつずれて重なってるだけ。たった1つの「★色相」変数を増やし続けるだけで、全ての色が自動的に循環するのがこの手法の美しいところ。

#5RGB合成とマウス検出

ok-scratch ok-scratch
計算したR/G/Bの3つの値を1つの数値に合成して、ペンの色として設定するよ。さらにマウスが押されたかどうかの判定も加えるんだ。
step-4

ペンペンの色を[COLOR]にするに渡す値は ★赤の値 × 65536 + ★緑の値 × 256 + ★青の値 という計算式。65536は256の2乗で、これはコンピュータが色を「赤8ビット+緑8ビット+青8ビット=24ビット」で表現する仕組みそのものなんだよ。この1行で任意のRGB色をペンに設定できる。

その直後に制御もし ( ) なら調べるマウスが押されたを組み合わせて、マウスが押されているときだけ描画処理に入るようにするよ。

ok-scratch ok-scratch
R×65536 + G×256 + B の式は「24ビットカラー」と呼ばれていて、組み合わせは約1677万色。WebのCSSで書く #FF8800 みたいな16進カラーコードも、実はこれと同じ仕組みなんだよ。普段ネットで見てる色が、全部この掛け算で表現されてるって考えるとちょっとエモくない?

確認プレビューしておこう 確認プレビューしておこう
ずっとの中で★色相がどんどん変わって、★赤の値・★緑の値・★青の値が動いてるのが見えるね。

#6マウス位置にドットを描画

ok-scratch ok-scratch
マウスが押されている間、クリックした場所に実際にドットを描くよ。ここでペンの透明度を0に戻して「見える状態」にするのが重要なポイント。
step-5

動きx座標を ( ) 、y座標を ( ) にするでマウスのx座標・y座標にスプライトを瞬間移動させてから、ペンペンの[COLOR_PARAM]を[VALUE]にするで透明度を0にする。これで初めてペンが「描ける」状態になるんだ。直後にペンペンを下ろすでペンを下ろすと、スプライトの位置にペンサイズ分のドットが1点だけ描画されるよ。

#7ドット完成と透明度復帰

step-6

ペンペンを上げるでペンを上げて、すぐに透明度を100に戻す。これでドット1点の描画が完了だよ。

普通にペンで絵を描くときは「ペンを下ろす → 移動 → ペンを上げる」で線を引くよね。でもこの作品では「移動 → ペンを下ろす → ペンを上げる」を一瞬でやることで、線じゃなくて点を打っている。しかも描画のたびに透明度を0→100と切り替えることで、ずっとループの色計算中にゴーストドットが描かれるのを確実に防いでるんだ。クリックしまくって虹色の軌跡を楽しもう!

確認プレビューしておこう 確認プレビューしておこう
マウスをクリックした場所に虹色のドットが描けるようになったね。

まとめ

sin関数でRGBを計算するテクニック、バッチリ理解できた?色相変数1個を増やし続けるだけで虹色が延々とループするって、かなりエレガントな発想だよね。クリックしまくっていろんな軌跡を描いてみてね!ペンのサイズや透明度をいじったり、sin関数の係数を変えて色の変化スピードを調整したりして、自分流のペインターに育てていこう。

ブクマよろしくお願いします! ブクマよろしくお願いします!
どんどん追記・更新していくので、ブックマークやシェアよろしくお願いします!