上一篇文章 解釋了如何用數學的方法(旋轉矩陣)來操作圖案的座標達成圓周運動,但其實 p5.js 也有一些現成的函數 rotatetranslate 來組合成類似的功能。

rotatetranslate 可以用來操作現有的座標系統,rotate 用來旋轉座標系統,translate 則是用來移動座標系統。

rotate

Imgur

translate

Imgur

回到我們的第一個作品:

function setup() {
    createCanvas(windowWidth, windowHeight);
    background(100);
}

function draw() { background(100, 100); circle(mouseX+100, mouseY, 20); circle(mouseX-100, mouseY, 20); circle(mouseX, mouseY+100, 20); circle(mouseX, mouseY-100, 20); }

四個圓圈會跟著滑鼠的座標進行移動,但如果我們使用 translate,我們就不需要讓圓圈的座標跟著 (mouseX, mouseY) 移動,而是讓整個座標系統移動就可以了。

現在我們開啟第三個作品的編輯界面,使用 translate 函數進行類似的功能:

function setup() {
    createCanvas(windowWidth, windowHeight);
    background(100);
}

function draw() { background(100, 100); translate(mouseX, mouseY); circle(100, 0, 20); circle(-100, 0, 20); circle(0, 100, 20); circle(0, -100, 20); }

Imgur

裡面的 translate(mouseX, mouseY),可以將座標系統的原點定位在在 (mouseX, mouseY),這樣我四個圓圈的座標都不需要動,但座標系統本身會隨著滑鼠移動,所以也會呈現出四個圓圈跟著滑鼠移動的效果。

然後我們再加入 rotate 函數,讓座標進行旋轉:

function setup() {
    createCanvas(windowWidth, windowHeight);
    background(100);
}

function draw() { background(100, 100); translate(mouseX, mouseY); rotate(frameCount/30); circle(100, 0, 20); circle(-100, 0, 20); circle(0, 100, 20); circle(0, -100, 20); }

Imgur

rotate(frameCount/30); 這一行指令,讓座標系統以 frameCount/30 (2*pi 就是一整圈的角度) 的速度進行轉向。

不同的順序與組合

前面介紹的旋轉矩陣、rotatetranslate 函數,這些方法都能讓畫布上的物體協調的作動,並做出有趣的視覺效果。

我們還能任意的改變這些方法的呼叫順序與組合,來呈現更多元的連動效果:

function setup() {
    createCanvas(windowWidth, windowHeight);
    background(100);
}

function draw() { background(100, 100); translate(mouseX, mouseY); rotate(frameCount/30); translate(150, 0); circle(100, 0, 20); circle(-100, 0, 20); circle(0, 100, 20); circle(0, -100, 20); }

Imgur

function setup() {
    createCanvas(windowWidth, windowHeight);
    background(100);
}

function vector_rotate(x, y, angle) { return [cos(angle)x-sin(angle)y,sin(angle)x+cos(angle)y]; }

function draw() { background(100, 100); translate(mouseX, mouseY); rotate(frameCount/30); let [final_x, final_y] = vector_rotate(200, 0, -frameCount/20); translate(final_x, final_y); circle(100, 0, 20); circle(-100, 0, 20); circle(0, 100, 20); circle(0, -100, 20); }

Imgur