14:変換(Transform)

移動

translate()関数を使用すると、キャンバス内のどこにでもオブジェクトを移動させることができます。1つめのパラメータはX軸のオフセットを設定し、2つめのパラメータはY軸のオフセットを設定します。このサンプルは、変換が蓄積されることを示すものです。

let x = 0;
let y = 0;
const dim = 80.0;

function setup() {
    createCanvas(720, 400);
    noStroke();
}

function draw() {
    background(102);
    // 変数xの値を大きくすることでアニメーションする
    x = x + 0.8;
    // シェイプがキャンバスから出たら、位置をリセットする
    if (x > width + dim) {
        x = -dim;
    }

    // rect()関数はキャンバスの原点を基準にシェイプを描画するが、
    // translate()はそれを新しいxとy位置に移動させる
    translate(x, height / 2 - dim / 2);
    fill(255);
    rect(-dim / 2, -dim / 2, dim, dim);

    // 変換は蓄積される。translate()のX軸値のパラメータは上と同じなのに、
    // この矩形が上の矩形の倍の速さで移動する点に注意。
    translate(x, dim);
    fill(0);
    rect(-dim / 2, -dim / 2, dim, dim);
}
解説

変換(transform)は数学の行列が関係する計算で、その理解は簡単ではありません。しかし座標システムに手を加えることだと考えると、理解のハードルが下がるかもしれません。移動(平行移動)変換の場合には、原点が平行移動します。たとえばtranslate(100,100)を実行すると、その後のキャンバスの原点は(100,100)に移動します。

変換の移動とtranslate()関数については、「5_1:移動(translate) p5.js JavaScript」で詳しく述べています。

拡大縮小

scale()関数のパラメータは小数点のついたパーセントで指定した値です。たとえばscale(2.0)は、シェイプのサイズを200パーセント大きくします。オブジェクトはつねに原点から拡大縮小されます。このサンプルは、変換が蓄積し、拡大縮小と移動がその順番によってどう作用し合うかを示すものです。

let a = 0.0;
let s = 0.0;

function setup() {
    createCanvas(720, 400);
    noStroke();
    // すべての矩形を、デフォルトの左上隅ではなく、それぞれのセンターから描画する
    // => 矩形センターから伸縮させるため
    rectMode(CENTER);
}

function draw() {
    background(102);

    // aは少しずつ大きくなる。
    // このaのコサインを使って滑らかな周期運動を作成する
    a = a + 0.04;
    s = cos(a) * 2;

    // 原点からキャンバスのセンターに移動
    translate(width / 2, height / 2);
    // sでスケール => sは滑らかな周期運動なので、滑らかな拡大縮小を繰り返す
    scale(s);
    fill(51);
    rect(0, 0, 50, 50);

    // 移動と拡大縮小の変換は累積するので、この移動は2つめの白い矩形を1つめより遠くに移動し、
    // 拡大縮小の効果も2倍になる。
    // sはコサインによって正負両方の値になるので、左右を往復する動きになる。
    translate(75, 0);
    fill(255);
    scale(s);
    rect(0, 0, 50, 50);
}
解説

このサンプルと拡大縮小については、「5_5:拡大縮小(scale) p5.js JavaScript」とその中の「p5.jsのScaleサンプル解説」で述べています。

rectMode()関数については、「5_3:移動(translate)と回転(rotate) p5.js JavaScript」で述べています。

回転

Z軸周りに正方形を回転させます。期待する結果を得るには、rotate()関数のangleパラメータに、0からPI*2(TWO_PI、約6.28)の間の値を送ります。角度を度で扱いたい場合には、値を度単位に変換するradians()関数を使用します。たとえば、rotate(radians(90)) は、ステートメントrotate(PI/2)と同じです。このサンプルでは、偶数秒ごとに変数jitterに回転が追加されます。奇数秒の間には、最終的なjitter値によって決まる速度で、矩形が時計回り方向と反時計回り方向に回転します。

let angle = 0.0;
let jitter = 0.0;

function setup() {
    createCanvas(720, 400);
    noStroke();
    fill(255);
    // 矩形をセンターから描画する。これはまたセンターを中心に回転させることにもなる
    rectMode(CENTER);
}

function draw() {
    background(51);

    // 偶数秒(0, 2, 4, 6...)の間は、回転にjitterを加える
    if (second() % 2 === 0) {
        jitter = random(-0.1, 0.1);
    }
    // 直近のjitter値を使って、angle値を大きくする
    angle = angle + jitter;
    // jitter(もぞもそ)していないとき(=>奇数秒の間)は、コサインを使って、時計回りと反時計回りの滑らかな運動を得る
    let c = cos(angle);
    // シェイプをキャンバスセンターに移動させる
    translate(width / 2, height / 2);
    // 最終の回転を適用する
    rotate(c);
    rect(0, 0, 180, 180);
}
解説

回転については、「5_2:回転(rotate) p5.js JavaScript」や「5_3:移動(translate)と回転(rotate) p5.js JavaScript」で述べています。

リファレンスメモ

second()

説明

p5.jsはコンピュータの時計とやりとりする。second()関数は、現在の秒数を0-59の値として返す。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA