---
# System prepended metadata

title: 3. 基礎圖形繪製 - 從點線面到塗鴉(學生版)

---


---
tags: 程式設計,第二章,學生版,互動藝術程式創作入門,Creative Coding
---

# 3. 基礎圖形繪製 - 從點線面到塗鴉(學生版)


---

## 單元介紹
在這個單元中，我們將會介紹繪製各種圖形的方法！ 「圖形」是組成作品最基礎的元素。舉凡常見的方形、圓形或者三角形等，也可以自己繪製更複雜的圖形。熟悉這些操作之後可以讓我們更得心應手的把心裡所想的內容組合出來！


---


# 圖形的組成


## h2幾何抽象主義
* Google Arts 介紹：[幾何抽象主義](https://artsandculture.google.com/entity/%E5%B9%BE%E4%BD%95%E6%8A%BD%E8%B1%A1%E4%B8%BB%E7%BE%A9/m05bw0l) Google Arts& Culture 有許多範例可以參考的 IG：[generative.hut](https://www.instagram.com/generative.hut/)



---


利用width與height變數產生橢圓在視窗中心
另外使用frameCount讓其往上伸展

![](https://i.imgur.com/t7A1uer.gif)


---

![](https://hackmd.io/_uploads/rkpeHuCkp.gif)



```javascript=
function setup() {  //主要設定畫圖的環境，畫布多大，畫布背景顏色
  createCanvas(windowWidth, windowHeight);    //畫布的大小，寬為windowWidth，高為wimdowHeight
  // background(255)  //代表白色(只有一個數字0~255。就黑(0)白(255)
  // background(255,255,0)  //R(紅0~255)G(綠0~255)B(藍0~255)，黃色背景
  background("#8ecae6")
}

function draw() {  //每秒會進入此函數執行60次，
  // background(220);
  // fill("#023047")  //圓內部充滿的顏色
  noFill()  //不充滿顏色
  stroke("#023047")  //框線的顏色
  // frameCount:每次進入draw()執行的次數
  ellipse(windowWidth/2,windowHeight/2,400,frameCount*5)  //畫一個圓，在座標為(windowWidth/2,windowHeight/2)，寬為300，高為50
}




```

---
隨著游標滑鼠移動


![](https://i.imgur.com/FzEhVf3.gif)



---

```javascript=
function setup() {  //主要設定畫圖的環境，畫布多大，畫布背景顏色
  createCanvas(windowWidth, windowHeight);    //畫布的大小，寬為windowWidth，高為wimdowHeight
  // background(255)  //代表白色(只有一個數字0~255。就黑(0)白(255)
  // background(255,255,0)  //R(紅0~255)G(綠0~255)B(藍0~255)，黃色背景
  background("#8ecae6")
}

function draw() {  //每秒會進入此函數執行60次，
  // background(220);
  // fill("#023047")  //圓內部充滿的顏色
  noFill()  //不充滿顏色
  stroke("#023047")  //框線的顏色
  strokeWeight(5)    //框限的粗細設定
  // frameCount:每次進入draw()執行的次數
  //ellipse(windowWidth/2,windowHeight/2,400,frameCount*5)  //畫一個圓，在座標為(windowWidth/2,windowHeight/2)，寬為300，高為50
  ellipse(mouseX,mouseY,400,frameCount*6)  //畫一個圓，在座標隨著滑鼠移動<畫一個寬為400，高隨著滑鼠移動
}


```

---

方形的呈現
![](https://i.imgur.com/bJ6rzD4.png)

```javascript=
function setup() {
  createCanvas(windowWidth, windowHeight);
  background("#8ecae6")
}

function draw() {
  noFill()  //不充滿顏色
  stroke("#023047")  //框線的顏色
  strokeWeight(5)    //框限的粗細設定
  ellipse(windowWidth/2,windowHeight/2,100)  //產生一個圓，座標在中心點，直徑為100的圓
  rect(windowWidth/2,windowHeight/2,100)  //產生一個方形，座標在中心點，寬與高都為100的方形
}




```





---


方形主要以左上角為座標中心點，圓則以中心點為主
可以利用rectMode(CENTER);設定為中心點為座標點

![](https://i.imgur.com/ZyBYqUr.png)



---


```javascript=
function setup() {
  createCanvas(windowWidth, windowHeight);
  background("#8ecae6")
}

function draw() {
  noFill()  //不充滿顏色
  stroke("#023047")  //框線的顏色
  strokeWeight(5)    //框限的粗細設定
  ellipse(windowWidth/2,windowHeight/2,100)  //產生一個圓，座標在中心點，直徑為100的圓
  rectMode(CENTER)  //設定方形的座標點在方形的中心
  rect(windowWidth/2,windowHeight/2,100)  //產生一個方形，座標在中心點，寬與高都為100的方形
}




```
---
![](https://hackmd.io/_uploads/rksmbK0ka.gif)

![](https://i.imgur.com/okkHo0i.gif)

```javascript=
function setup() {
  createCanvas(windowWidth, windowHeight);
  background("#8ecae6")
}

function draw() {
  noFill()  //不充滿顏色
  stroke("#023047")  //框線的顏色
  strokeWeight(5)    //框限的粗細設定
  ellipse(windowWidth/2,windowHeight/2,100)  //產生一個圓，座標在中心點，直徑為100的圓
  rectMode(CENTER)  //設定方形的座標點在方形的中心
  rect(windowWidth/2,windowHeight/2,100+(frameCount-1)*50)  //產生一個方形，座標在中心點，寬與高都為100的方形
}
```


---

粗細間隔顯示

![](https://i.imgur.com/6JppfKb.gif)


![](https://hackmd.io/_uploads/rJFprtAyp.gif)

---

```javascript=
function setup() {
  createCanvas(windowWidth, windowHeight);
  background("#8ecae6")
}

function draw() {
  noFill()  //不充滿顏色
  stroke("#023047")  //框線的顏色
  //frameCount進入draw()的次數，%2代表除以2的餘數，如果餘數為0，則線條粗細為5，餘數為1(==0這個條件不成立)
  strokeWeight(frameCount%2==0?5:1)    //框限的粗細設定，frameCount進入draw()的次數，%2代表除以2的餘數
  ellipse(windowWidth/2,windowHeight/2,100)  //產生一個圓，座標在中心點，直徑為100的圓
  stroke(frameCount%2==0?"#48cae4":"#ade8f4")
  rectMode(CENTER)  //設定方形的座標點在方形的中心
  rect(windowWidth/2,windowHeight/2,100+(frameCount-1)*20)  //產生一個方形，座標在中心點，寬與高都為100的方形
}


```

---

設定文字在視窗上

![](https://i.imgur.com/7VVAzxF.gif)

![](https://hackmd.io/_uploads/BJjK7svl6.gif)


---


```javascript=
function setup() {
  createCanvas(windowWidth, windowHeight);  //建立一個畫布，畫布大小為視窗的寬高
  background("#cdb4db")
}

function draw() {
  background("#cdb4db")  //加入此行，不要產生軌跡影像
  fill("#0077b6")   //文字顏色
  textSize(25)      //文字的大小
  fill("#ffafcc")
  text("教育科技學系",mouseX,mouseY) //文字顯示的內容與位置
  text("滑鼠的 X:"+mouseX+",y:" +mouseY,100,100)

}
```

---

畫三角形

triangle(440, 140, 160, 600, 800, 600);

![](https://i.imgur.com/r9WsHEB.png)


---

利用滑鼠x座標與frameCount作三角形的運作變化

![](https://i.imgur.com/A8iV7ZS.gif)


---

```javascript=




```
---



![](https://i.imgur.com/NPwxzqc.gif)

---

把三角形指令改為(有一點為滑鼠x,y座標)
```javascript=
triangle(440+mouseX/2, 140, 160+frameCount/3, 600, mouseX, mouseY);
```


---

利用fill加上三角形顏色

![](https://i.imgur.com/JQuPWam.gif)


---

```javascript=



```


---

![](https://i.imgur.com/EAVfBx9.gif)


---



## 範例練習 - 

變動的圖形：練習繪製屬於你的角色（[範例 ](https://openprocessing.org/sketch/874368))
```javascript=
function setup() {
  createCanvas(windowWidth, windowHeight);  //建立一個畫布，畫布大小為視窗的寬高
  background("#cdb4db")
}

function draw() {
  //background("#cdb4db")  //加入此行，不要產生軌跡影像
  fill("#0096c7")   //文字顏色
  textSize(25)      //文字的大小
  fill("#0096c7")
  //text("教育科技學系",mouseX,mouseY) //文字顯示的內容與位置
  text("滑鼠的 X:"+mouseX+",y:" +mouseY,100,100)
  //mouseX%256代表把mouseX除以256求榆樹(餘數一定在0~255)
  fill(mouseX%256,mouseY,0)  //充滿的顏色，顏色值為三個數字(RGB)，每個數字的值為0~255
  noStroke()  //不要有框線
  //frameCount主要是進入draw()函數的次數，值會隨著數字累積
  triangle(440+mouseX/3,140+mouseY/3,160+frameCount/10,600,800,600)  //三角形的三個角的座標點

}

```


![](https://i.imgur.com/GrUlRLC.gif)
![](https://hackmd.io/_uploads/HkpPk6wea.gif)



---
```javascript=
function setup() {
  createCanvas(windowWidth,windowHeight);
  background("#cdb4db")
}

function draw() {
  background("#cdb4db");
  textSize(25)      //文字的大小
  fill("#0096c7")
  text("滑鼠的 X:"+mouseX+",y:" +mouseY,100,100)
  fill("#a2d2ff")
  strokeWeight(10)
  beginShape()             // 圖形的起點 

  curveVertex(440+mouseX/5,160+mouseY/5)
  curveVertex(360,360)
  curveVertex(160,400+random(-10,10))
  curveVertex(350,500)
  curveVertex(320+random(-3,3),700)
  curveVertex(430,500)
  curveVertex(570,700)
  curveVertex(500,460)
  curveVertex(670,400+random(-5,5))
  curveVertex(480,360)
  endShape(CLOSE)        //圖形的結束點，加入CLOSE為把最後一個點與第一個點連線
  ellipse(385,390,50+mouseX/60)   //左眼
  ellipse(385,390,5)    //左眼球
  ellipse(450,390,30)   //右眼
  ellipse(450,390,5)    //右眼球
  stroke("#264653")
  beginShape()      //嘴巴線條
    vertex(360,450)
    vertex(400,470)
    vertex(400,440)
    vertex(420,440)
    vertex(450,460)
    vertex(460,440)

  endShape()
}

```

在本次的範例中，我們將練習使用圓形、點以及特製形狀來繪製屬於你的角色！ 例如會學習到如何畫出這樣的海星，並再加上一些小技巧，例如最後讓海星的觸手、眼睛與背景產生動態的變化。就完成這個有點ㄎ一ㄤ的微醺海星囉～



---

## 重點回顧＆一些操作的小技巧


### 繪製形狀的方法整理


---


透過一些函式並放入「位置」、「大小」等資訊（aka. 引數）就能夠繪製出如矩形、圓形 、三角形等形狀；除此之外，也能自己繪製自製形狀 



---


* 橢 / 圓形：使用函式 [ellipse()](https://p5js.org/zh-Hans/reference/#/p5/ellipse)() 來繪製。
* 矩形：使用函式 [rect()](https://p5js.org/zh-Hans/reference/#/p5/rect) 來繪製。要注意的是圖形位置的基準點預設是左上角。因此可以函式 [rectMode()](https://p5js.org/zh-Hans/reference/#/p5/rectMode) 來改變圖形的定位方式。
* 三角形：利用函式 [triangle()](https://p5js.org/zh-Hans/reference/#/p5/triangle) 放入三個點的資訊即可畫出。
* 自製形狀：是使用 [beginShape()](https://p5js.org/zh-Hans/reference/#/p5/beginShape)、[vertex()](https://p5js.org/zh-Hans/reference/#/p5/vertex)、[endShape()](https://p5js.org/zh-Hans/reference/#/p5/endShape) 這三個函式的組合，來將多點連在一起所構成的任意圖形，就像是小時候玩的「連連看」一樣。 



---

其繪製語法是：


```javascript=

beginShape()             // 圖形的起點 //
  vertex()/curveVertex() // 決定頂點在哪裡，可以包很多 //
  vertex()/curveVertex()  
  vertex()/curveVertex()                     
  .....                  
endShape()        // 圖形的終點。引入 CLOSE 才會將圖形封閉起來 // 

```


---

*  圖形的終點。引入 CLOSE 才會將圖形封閉起來  
*  vertex() 直接把點連起來，所以圖形中點的轉折會很明顯；但 curveVertex() 使用了「樣條函數」在點的位置計算出弧形，因此繪製出來的圖形更圓滑了。



---


### 形狀的調整方法

* 調整框線顏色：stroke()
* 調整外框粗細：strokeWeight()
* 改變圖形填充：fill()



---

### 豐富畫面的小技巧們

善用 mouseX、mouseY 及 frameCount 等 p5 原生變數，來動態地改變圖形的模樣吧！



---


#### 可以嘗試以下技巧：

* 讓圖形 / 框線跟著滑鼠移動
* 用滑鼠位置改變線條粗度
* 改變圖形填色
* 調整 frameCount 的倍數來改變繪圖的速度
* 不設定填色，以產生外框線條的堆積效果
* 隨著時間改變圖形位置或大小



---

## 程式小技巧
我們可以運用一些程式的語法幫助更方便創作！
###  三元條件運算子
*  可以更快速地做一些簡單的條件判斷來控制輸出 
要判斷的某個條件 ? 若符合條件的輸出結果 : 若不符合條件的輸出結果

* mouseX>width/2?fill('green'):fill('red') 
 滑鼠在畫布的右半側時圖形填充為綠；反之為紅  
 

---

###  利用 text() 在畫面上印出滑鼠位置以方便我們尋找座標點
* 記得要用引號 ’ ’ 來包住「靜態字」（aka.字串）的範圍，並用加號 ‘+’ 連接靜態字與變數 
* text('這個是：'+mouseX,250,250) 
會在 250,250 的位置渲染出「這個是：滑鼠Ｘ座標」


---

##  課後問題(1)
* ellipse() 跟 circle() 有什麼不一樣，有辦法用 ellipse() 繪製出 circle() 的圖形嗎？
* 我們如何繪製不規則的圖形？需要使用到哪些指令呢？


---

##  課後問題(2)
* 透過可以畫面的元素（如圖形、邊框顏色、粗細、大小、填色等）與各種參數（如 frameCount, mouseX, mouseY, mouseIsPressed 等）互相搭配，可以顯示出讓人驚艷的效果，也試試看隨意的搭配，看看會有什麼變化吧，像是 “隨著滑鼠位置變化邊框粗細，或是判斷是否透過點擊滑鼠改變圖形的填色”
* 如何用三元運算子表達這個判斷式的結果


---

```javascript=
if(imHungry){
return 'eatDinner'
}
else
{
return 'goToSleep'
}
```


---

* 如何讓繪製的圖形隨時間變形/變色呢？ 需要使用到什麼變數？
* 曲線是不是不能應用在非封閉線段？
* 很想知道重複偏移要如何使用？
 


---


常見的表現手法與組成元素：

* 韻律感
* 材質，如光影、深度
* 軌跡
* 位置
* 畫畫 -> 幾何圖形 / 隨機圖型 / 文字 -> 填色 / 線條
* 變化 -> 時間 滑鼠 鍵盤



---

### 參考作品：
Google Arts: 幾何抽象主義 https://artsandculture.google.com/entity/%E5%B9%BE%E4%BD%95%E6%8A%BD%E8%B1%A1%E4%B8%BB%E7%BE%A9/m05bw0l
https://www.instagram.com/generative.hut/


---

- 畫布與坐標系
    - width / height
    - background
    - clear
    - 檢視位置工具： https://www.openprocessing.org/sketch/788769



---

- 繪製幾何圖形
    - line
    - rect
    - ellipse
    - triangle
    - rectMode / ellipseMode -> 定位點的差別
https://www.openprocessing.org/sketch/874264
 


---

- 控制顏色與線條
    - fill / stroke / strokeWidth
    - RGB / 灰階 / 顏色名稱
- 顏色
    - https://coolors.co/
- 繪製任意形狀 < 重點
    - beginShape / endShape / vertex
    - curveVertex
    - arc
- 繪製文字
    - text(文字,x,y)
    - textSize() -> 取得文字寬度
    - textStyle


---

- 隨著時間變化
    - frameCount
- 隨著滑鼠變化
    - mouseX / mouseY / pmouseX / pmouseY
- 控制更新頻率
    - frameRate
    - noLoop / Loop
- 課堂範例 - 規則v.s. 混亂
    - random? 


---

### 課後作業 - 繪製風景/東西 or 模仿藝術品


![](https://i.imgur.com/o35rHtS.png)
https://www.openprocessing.org/sketch/874264


---

![](https://i.imgur.com/Vx1unBw.png)
https://www.openprocessing.org/sketch/874271


---

![](https://i.imgur.com/qcLfXQw.png)
https://www.openprocessing.org/sketch/864045




---

![](https://i.imgur.com/TnQnQYQ.png)
https://www.openprocessing.org/sketch/874368



---

```javascript=
function setup() {
	createCanvas(windowWidth, windowHeight);
	background(255);
}

function draw() {
	// ellipse(mouseX, mouseY, 20, 20);
	// background(255,1)
	background(mouseX, 207, 149+frameCount/5)
	
	noFill()
	ellipse(width/2,height/2,50,50)
	rectMode(CENTER)
	// circle(width/2,height/2,50)
	// fill(frameCount*3)
	// rect(50+frameCount*5,50+frameCount*5,100,100)
	// fill('red')
	noFill()
	
	// strokeWeight( frameCount%2==0?5:1 )
	// stroke(mouseX)
	// rect(width/2,height/2,100+frameCount*20,50+mouseX)
	// print(frameCount)
	fill('black')
	textSize(50)
	text( int(mouseX)+" , "+int(mouseY),50,50 )
	
	fill(255, 213-mouseX, 45)
	
	strokeWeight(10)
	beginShape()
	curveVertex(440+mouseX/5,160+mouseY/5)
	curveVertex(360,360)
	curveVertex(160,400 + random(-10,10))
	curveVertex(350,500)
	curveVertex(320,700)
	curveVertex(430,500)
	curveVertex(570,700)
	curveVertex(500,460)
	curveVertex(670,400+ random(-10,10))
	curveVertex(480,360)
	curveVertex(440+mouseX/5,160+mouseY/5)
	curveVertex(360,360)
	curveVertex(160,400)
	
	endShape()
	fill('white')
	ellipse(390,400,40+mouseX/20,40+mouseX/20)
	ellipse(450,405,30,30)
	ellipse(390,400,5,5)
	ellipse(450,405,5,5)
	
	noFill()
	beginShape()
	vertex(360,450)
	vertex(400,470)
	vertex(400,440)
	vertex(420,440)
	vertex(450,460)
	vertex(460,440)
	
	endShape()
	// fill(mouseX,mouseY,50)
	// triangle(440+mouseX/2,140,160+frameCount/10,600,mouseX,mouseY)
	
}
```
3. 基礎圖形繪製 - 從點線面到塗鴉(學生版).md
目前顯示的是「3. 基礎圖形繪製 - 從點線面到塗鴉(學生版).md」。