---
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讓其往上伸展

---
```javascript=
```
---
隨著游標滑鼠移動

---
```javascript=
```
---
方形的呈現
```javascript=
```

```javascript=
function setup() {
createCanvas(windowWidth, windowHeight);
background("#faedcd")
}
function draw() {
//background(220);
noFill()
ellipse(width/2,height/2,100)//畫園,座標以園新為座標點
rect(width/2,height/2,100)//畫方框,座標以左上角為座標點
}
```
---
方形主要以左上角為座標中心點,圓則以中心點為主
可以利用rectMode(CENTER);設定為中心點為座標點

---
```javascript=
function setup() {
createCanvas(windowWidth, windowHeight);
background("#faedcd")
}
function draw() {
//background(220);
noFill()
rectMode(CENTER);//設定中心點為座標點
ellipse(width/2,height/2,100)//畫園,座標以園新為座標點
rect(width/2,height/2,100)//畫方框,座標以左上角為座標點
}
```
---

---
粗細間隔顯示

---
```javascript=
function setup() {
createCanvas(windowWidth, windowHeight);
background("#faedcd")
}
function draw() {
//background(220);
noFill()
rectMode(CENTER);//設定中心點為座標點
strokeWeight(frameCount%2==0?4:1)//框限粗細,frameCount除以2求餘數=0(偶數),線條粗細為4,否則為1(基數)
ellipse(width/2,height/2,100)//畫園,座標以園新為座標點
rect(width/2,height/2,20*frameCount)//畫方框,座標以左上角為座標點
}
```
---
設定文字在視窗上

---
```javascript=
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(220);
textSize(50)
text("滑鼠X軸:"+mouseX+",Y軸:"+mouseY, 50, 50)
}
```
---
畫三角形
triangle(440, 140, 160, 600, 800, 600);

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

---
```javascript=
```
---

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

---
```javascript=
function draw() {
//background("#8ecae6");
//textSize(50)
//fill(0)
//text("X軸:"+mouseX+",Y軸:"+mouseY, 50, 50)
//fill("#ffb703")
fill(mouseY%256,(184+frameCount)%256,3+mouseX/3)
// triangle(552,182.300,340,766,411)
//triangle(200+mouseX/3,200+mouseY/3,300,340,766,414);
triangle(200+mouseX/3,200+mouseY/3,300+frameCount/10,340-mouseX/10,766,414+frameCount/10);
}
```
---

---
## 範例練習 -
變動的圖形:練習繪製屬於你的角色([範例 ](https://openprocessing.org/sketch/874368))

---
在本次的範例中,我們將練習使用圓形、點以及特製形狀來繪製屬於你的角色! 例如會學習到如何畫出這樣的海星,並再加上一些小技巧,例如最後讓海星的觸手、眼睛與背景產生動態的變化。就完成這個有點ㄎ一ㄤ的微醺海星囉~
---
## 重點回顧&一些操作的小技巧
### 繪製形狀的方法整理
---
透過一些函式並放入「位置」、「大小」等資訊(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 的位置渲染出「這個是:滑鼠X座標」
---
## 課後問題(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://www.openprocessing.org/sketch/874264
---

https://www.openprocessing.org/sketch/874271
---

https://www.openprocessing.org/sketch/864045
---

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