コンテンツにスキップ

繰り返しと色の表現

この章では処理の繰り返しについて学びます。 繰り返しを使うと規則的に図形を並べることができるようになります。 また、色を数値で表現する方法について学び、図形を好きな色で塗ることができるようになります。

繰り返し

プログラムでは似たような処理を何度も行いたいことが多くあります。 前回学んだプログラム 例2-2-1 の中でも、"円の位置をずらしで描く"ということを3回行っています。 for文を使うとこのような繰り返しを簡潔に書くことができます。 次の例では、前回より短い記述でたくさんの円を並べています。

[例3-1 for文で円を20個並べる]

function setup() {
    createCanvas(800, 500);
    background(200);
}

function draw() {
    let y = 250;
    let width = 20;

    for(let i=0; i<20; i++){
        let x = i*40 + 20;
        circle(x, y, width);
    }
}

文法の解説

もっとも典型的なfor文は以下のように書きます。 これでブロックの中に書いた処理1, 処理2, 処理3... の全てが5回繰り返されるようになります。

いきなり登場した新しい変数 i に関する3つの命令 1. 変数の初期化, 2. 継続条件, 3. 変数の進行 がこのループを制御する役割を持っています。

この構文は順を追うと次のような動作をしています。 まず変数 i=0 として変数が初期化されます。 継続条件 i<5 をみたすなら、ブロックの中の処理を実行し、最後に変数の進行i++を実行します。 ここで、 i++i = i+1 と同じ意味で、 i を1大きくするという意味です。 このループは i=0 からスタートし、 i は1ずつ増加します。 ループが進みながら、継続条件を満たす i=1, i=2, i=3, i=4 までは処理が実行されますが、次の i=5 のときは条件を満たさないので終了となりブロックを抜けます。

ここで宣言した変数 i はforブロックの中で利用することができます。 例3-1 では、x座標を i*40 + 20 (等差数列)として円を等間隔に並べています。

繰り返しの繰り返し

for文の中にもfor文を書くことができて、プログラムがさらに簡潔に書けることがあります。 例3-2aは円を横一列に並べるための似たようなfor文が5つも書いてありますが、これらのfor文をさらにまとめて例3-2bのように書くことができます。 なるべくfor文を使って処理をまとめて書くようにすれば、プログラムが短くなるのに加え、円の色を変更したい、円を長方形に変更したいという場合の書き換えも少なくすみます。

[例3-2a. 100個の円を並べる]

function setup() {
    createCanvas(800, 500);
    background(200);
}

function draw() {
    let width = 20;

    for(let i=0; i<20; i++){
        circle(i*40 + 20, 90, width);
    }

    for(let i=0; i<20; i++){
        circle(i*40 + 20, 170, width);
    }

    for(let i=0; i<20; i++){
        circle(i*40 + 20, 250, width);
    }

    for(let i=0; i<20; i++){
        circle(i*40 + 20, 330, width);
    }

    for(let i=0; i<20; i++){
        circle(i*40 + 20, 410, width);
    }
}

[例3-2b. 二重の繰り返しで100個の円を並べる]

function setup() {
    createCanvas(800, 500);
    background(200);
}

function draw() {
    let width = 20;

    for(let j=0; j<5; j++){
        for(let i=0; i<20; i++){
            circle(i*40 + 20, j*80 + 90, width);
        }
    }
}

色を扱う

コンピュータ上で色を表現する

コンピュータで色を数値で表す方法がいくつかあります。

グレイスケール は黒と白のあいだの単色での色指定です。 グレイスケールは0〜255の数値で指定し、数字が小さいほど黒く大きいほど白を表します。

RGB は光の3原色である赤(Red)緑(Green)青(Blue)に色を分解し、それぞれの濃さを数値で指定する方法です。 R, G, B それぞれの成分は0〜255の数値で指定します。

HSB は色相 (Hue), 彩度 (Saturation), 明度 (Brightness) の3つの属性で指定する方法です。 同じような明るさで、色相だけ変化させるといった色の指定がしやすくなります。 色相 H は0°〜360°、彩度S と明度B は0%〜100% の数値で指定します。

余談
文脈によって HSV も同じ意味で使われます。 色を表すそれぞれの数値を調べるには google color picker などが便利です。

p5.js で色を指定する

上記の色の指定方法は、p5.js ではcolorMode を使って切り替えることができます。

colorMode(RGB); // 以降RGB で色を指定するという宣言
colorMode(HSB); // 以降HSB で色を指定するという宣言

背景や図形の色を決めるために以下のような関数があります。

関数 意味 引数
background 背景の色を決める
fill 図形内部の色を決める
stroke 輪郭線の色を決める
noFill 図形内部を塗らない なし
noStroke 図形の輪郭線を引かない なし
// 背景を真っ黒で塗りつぶす(グレースケールで色指定)
background(0);


// 次に描く図形の色を水色にする(RGBで色指定)
colorMode(RGB);
fill(80, 240, 240);

// これ以降に rect や circle を使う

もちろんアニメーションで色を変化させることもできます。 次の例ではHSB色指定を用い、時間とともに色相を回転させています。

let hue = 0;

function setup() {
    createCanvas(200, 200);
    background(200);
    colorMode(HSB);
}

function draw() {
    hue = (hue + 1)%360; // take remainder to loop over [0, 359]

    fill(hue, 50, 100);
    noStroke(); // draw without stroke(contours)
    rect(10, 10, 180, 180);
}

練習問題

練習問題1

次のプログラムを利用して、背景と9つの四角形を自分が美しいと思う色を塗りましょう。 RGB, HSB それぞれの方法で色を指定してみましょう。

function setup() {
    createCanvas(500, 500);
    colorMode(HSB);

    background(200 ,10, 40);
}

function draw() {
    // 1段目
    fill(0, 50, 100);
    rect(50, 50, 100, 100);

    fill(120, 50, 100);
    rect(200, 50, 100, 100);

    fill(240, 50, 100);
    rect(350, 50, 100, 100);

    // 2段目
    fill(40, 50, 100);
    rect(50, 200, 100, 100);

    fill(160, 50, 100);
    rect(200, 200, 100, 100);

    fill(280, 50, 100);
    rect(350, 200, 100, 100);

    // 3段目
    fill(80, 50, 100);
    rect(50, 350, 100, 100);

    fill(200, 50, 100);
    rect(200, 350, 100, 100);

    fill(320, 50, 100);
    rect(350, 350, 100, 100);

}

練習問題2

for文を使うと少しずつ色を変化させることもできます。

function setup() {
    createCanvas(500, 500);
    colorMode(HSB);

    background(50);
}

function draw() {
    for(let i=0; i<10; i++){
        fill(i*36, 50, 100);
        rect(i*40 + 30, i*20 + 100, 80, 80);
    }
}

次のような徐々に色相(H)と彩度(S)が変化する図形(例えば四角形)をforを使って描いてみましょう。

練習問題3

図形の色をアニメーションで変化させてください。 色相(左)または彩度(右)を変数とし、drawの中で更新すると以下のようなものができます。