上一篇文章 解釋了如何用數學的方法(旋轉矩陣)來操作圖案的座標達成圓周運動,但其實 p5.js 也有一些現成的函數 rotate
、translate
來組合成類似的功能。
rotate
、translate
可以用來操作現有的座標系統,rotate
用來旋轉座標系統,translate
則是用來移動座標系統。
rotate
:
translate
:
回到我們的第一個作品:
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);
}
裡面的 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);
}
rotate(frameCount/30);
這一行指令,讓座標系統以 frameCount/30
(2*pi 就是一整圈的角度) 的速度進行轉向。
前面介紹的旋轉矩陣、rotate
和 translate
函數,這些方法都能讓畫布上的物體協調的作動,並做出有趣的視覺效果。
我們還能任意的改變這些方法的呼叫順序與組合,來呈現更多元的連動效果:
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);
}
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);
}