iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Modern Web

p5.js 的環形藝術系列 第 4

[Day 04] p5.js 基礎教學(一) -- 座標與旋轉圖案

  • 分享至 

  • xImage
  •  

第二篇文章我們完成了第一個作品,我們做出了分散在上下左右,能夠隨著滑鼠移動的四個圓圈。

現在我們希望在第二個作品做優化,讓這四個圓圈,還能繞著滑鼠做圓周運動,就像是行星繞著太陽一樣,那我們該怎麼做呢?

首先我們要先解釋一下 p5.js 中,畫布的 xy 座標系統,這個座標系統的原點 (0,0) 位於畫布的左上角,且 x 軸正向為由左到右,而 y 軸正向為由上到下:

Imgur

當我們要做出圖案隨時間進行運動(圓周運動)的效果,就必須引入 frameCount 這個變數,該變數紀錄了目前 p5.js 執行了幾次 draw() 函數,也就是他繪製了多少幀動畫。

下面是第一個作品的程式,我們試著在裡面加入 frameCount 變數。

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);
}

現在我們開啟第二個作品的編輯界面,嘗試加入 frameCount 變數:

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

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

我在每個圓圈的 y 座標都加上 frameCount,因此除了會跟著滑鼠移動,他們還會因為 y 值的遞增,而逐漸往下移動,離滑鼠越來越遠:

Imgur

那如果我們要使用這個 frameCount 來執行每個圓圈的圓周運動,那要怎麼做呢?

這裡就要稍微引入一下數學的向量概念:

Imgur

上圖中的兩個箭頭分別代表向量 A (x1, y1) 跟向量 B (x2, y2),像這樣的二維向量,我們可以用一組 xy 座標來代表他。

然後這兩個向量他們的長度是一樣的,因此向量 A 和向量 B 這樣看起來就只有一個角度的轉向,然後這個角度就是 θ

重點來了,我們希望找到一個函數,他的輸入為 x1, y1, θ,得到輸出為 x2, y2,這個函數的用意在幹嘛呢?就是我希望輸入某個向量 (x1, y1) 跟某個角度 θ,然後他要將這個向量 (x1, y1) 以逆時針轉 θ 度之後得到的新向量 (x2, y2) 給我們,所以這個函數是用來做向量旋轉的。

假設我們已經有了這個函數叫做 vector_rotate,輸入向量就是圓圈相對於滑鼠的初始位置,角度為 frameCount/30,輸出就是圓圈相對於滑鼠的新位置,現在初始位置固定,那隨著 frameCount 遞增,新位置所轉的位置也遞增,我們的圓圈不就可以繞著滑鼠做圓周運動了嗎?

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

function vector_rotate(x, y, angle) {
        ...
}

function draw() {
        background(100, 100);
        
        // 這是初始位置
        let [init_pos_x, init_pos_y] = [100, 0];
        
        // 這是新位置
        let [new_pos_x, new_pos_y] = vector_rotate(init_pos_x, init_pos_y, frameCount/30);
        
        
        circle(mouseX+new_pos_x, mouseY + new_pos_y, 20);
}

若能夠完成 vector_rotate 的內容,那這段程式呈現出來的動畫會像這樣:

Imgur

如果要實作 vector_rotate,就必須要知道一些高中數學知識,在高中數學會學到一個矩陣叫做旋轉矩陣,就是用來做二維向量的旋轉:

Imgur

我們不需要知道旋轉矩陣的實際細節,我們只需要借用他們的結果就行了,這個 vector_rotate 的內容就是:

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

現在我們能夠實現圓周運動了,那我們的第二個作品就是將第一個作品的四個圓圈加上圓周運動:

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

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

function draw() {
	background(100, 100);
	let v = PI / 80 * frameCount;
	let [x1, y1] = vector_rotation(100, 0, v);
	let [x2, y2] = vector_rotation(-100, 0, v);
	let [x3, y3] = vector_rotation(0, 100, v);
	let [x4, y4] = vector_rotation(0, -100, v);

	let y = mouseY;
	let x = mouseX;
	circle(x+x1, y+y1, 20);
	circle(x+x2, y+y2, 20);
	circle(x+x3, y+y3, 20);
	circle(x+x4, y+y4, 20);
}

這是呈現出來的動畫:

Imgur


上一篇
[Day03] 展示你的 Open processing 作品
下一篇
[Day 05] p5.js 基礎教學(二) –– rotate 和 translate
系列文
p5.js 的環形藝術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言