:::warning **CHANGE LOG**(有任何修改請在此通知) > [name=andrew] 2023/11/14, 11:14am 目前已經上傳至 [gitlab repo](https://gitlab.com/aesthetic-programming/book/-/tree/master/source.zh_TW/2-VariableGeometry) ::: ![flowchart](https://hackmd.io/_uploads/B1LY3C753.png) <!-- 使用 Graphviz Oneline 繪製流程圖的程式碼 https://dreampuf.github.io/GraphvizOnline digraph G { node[fontname="Taipei Sans TC"] //labels GS [ label="第二章:變數幾何", style=bold, shape=rectangle, penwidth="1pt" ] SU [label="setup()"] ST [label="start()"] SC [label="原始碼"] CO [label="座標"] EiC [label="課堂練習"] VB [label="變數"] YVB [label="為何使用變數?"] OF [label="其他函式"] BAO [label="基本算數運算子"] CS [label="條件結構"] RO [label="關係運算子"] DiC [label="課堂討論"] MW [label="While()"] MX [label="迷你習作: \n幾何表情符號"] RR [label="指定讀物"] FR [label="延伸讀物"] Notes [label="註釋"] //rank {rank = same; MW, EiC} {rank = same; SC, MX} {rank = same; OF, DiC} //graph GS -> MX; GS -> RR[dir=both, minlen=2]; SU -> MW [dir=both]; MW -> VB[dir=both]; RO -> BAO[dir=none]; GS -> SU -> ST -> SC; SC -> CO -> EiC; SC -> VB; VB -> YVB[minlen=2]; SC -> OF -> BAO; SC -> CS[minlen=2]; CS -> RO ; EiC, VB, CS -> DiC; ST -> MW -> Notes; MW -> MX; RR -> MX, SU; RR -> FR; } --> ## setup() 學習複雜的新事物有其困難之處,但撇開這點,我們希望學習程式設計可以讓您感到愉快和有所回報。許多相關書籍的書名,都明白地告訴讀者,寫程式可以很有趣,像由林納斯・托瓦茲(Linus Torvalds)與大衛・戴蒙德(David Diamond)合寫,半為自傳性質,半為 Linus 發展故事的《只是為了好玩:一個偶然成為革命者的故事》(Just for Fun: The Story of an Accidental Revolutionary)便是一例。[^Fun]在這種情況下,樂趣和開放原始碼,以供人們進一步修改的努力結合在一起。就如同分享或一則笑話或一份食譜,程式設計是一種社會活動,要「懂得」程式設計,必須仰賴集體的理解。 強調「樂趣」概念的例子還有很多,而這似乎是想要表達,只要這樣便足以說服使用者持續學習程式設計,而不被潛在的困難所擊倒。接續上一章的橢圓繪製,我們鼓勵您在接下來的內容裡繼續享受幾何的樂趣。這裡的想法,是希望讀者進一步探索各種形狀、大小、位置、空間和長度,上述在數學的定義中被視為「幾何」要素,並且在日常生活中有著多種應用方式,包括但不限於排版、標示、平面設計和建築,以及其他組織形式。更具體來說,物件是由點、線、面構成,因此這三者被視為設計的基本元素,而世界又是由具有特定屬性的各種物件組成的。幾何學的樂趣便是來自於這些屬性的操弄與重新建構,從而創造不同的認識和理解模式。[^Fun2]正如奧爾加・葛路諾瓦(Olga Goriunova)在其主編的《樂趣和軟體》(Fun and Software)中所言,電腦的樂趣被視為一種思考模式[^Olga],此外,在這個過程中出現的悖論也可以帶來樂趣。經由創造新的運算物件,你可以操縱學習的程序邏輯,並探索如何調整和重新繪製這些邏輯。在這層意義上,變數幾何關乎形狀的轉換,亦即重新想像各種新的形狀、組合形式和空間關係,從而挑戰幾何慣例。[^Femke] 以表情符號(一種表意符號,通常是笑臉形式)為例,這是一種可用以呈現面部表情的文字排列,比如開心便可用「:D」表示。這些符號在溝通上愈來愈普及,不再是簡單的文字排列,而是變成了實際的圖像,有時候,這些圖像作為表情符號看起來可能相當有趣,但與之相關,潛在的再現政治問題也隨之而來。下文將更深入討論這一點,但就目前而言,表情符號是一個很好的例子,因為它們是由幾何形狀組成,包含點、線、面和顏色。本章將從這些表情符號中獲得樂趣(即使一些潛在的問題根本不好玩),進而探索表情符號的情感維度,以及我們在日常溝通上會遇到的不同呈現形式。 已有許多評論家針對表情符號標準化與再現政治之間的關連進行探索。由羅耶・羅斯卡姆·亞彬(Roel Roscam Abbing)、佩姬・皮耶洛(Peggy Pierrot)和芬穆珂・史奈爾汀(Femke Snelting)所撰寫,研究表情符號「通用性」政治的文章〈修改通用性〉(Modifying the Universal)便是一個很好的例子。[^Emojis]自一九八七年以來,Unicode 計畫設定了運算產業的標準,讓所有主要操作系統和書寫應用程式有了一致的編碼、文字再現和處理方法,從而推動軟體國際化,表情符號也隨之出現。有趣的是,在技術層面上,Unicode 提供了一個獨特的編碼點(數字),以抽象方式表示字符,視覺呈現的任務(大小、字體、形狀、幾何)則留給其他軟體,例如網頁瀏覽器或文字處理器等。在這裡,我們感興趣的是關於再現的問題。 正如開發一種世界上大多數人都可以言說和理解的通用語言(例如世界語)這種烏托邦式理想,Unicode 對於國際/多語言系統的溝通運作顯然很重要。截至本書撰寫時的最新版本 Unicode 12.1 於二〇一九年五月發佈時,一共有 137,994 個字符,涵蓋 150 部腳本(scripts),以及多個符號集和表情符號。[^Unicode]然而,隨著這項標準從基本字符,一路擴大適用到符號集和表情符號,標準的通用性愈來愈成問題。相關批評毫無意外地圍繞在再現政治上,例如公然展現的性別刻板印象和種族歧視,舉例而言,女性的表情符號在某些行業中明顯欠缺[^Telegraph],表情符號的膚色也有所侷限,另外,「通用修飾符號」也無法於所有裝置和作業系統上「通用」顯示。 我們的觀點是,表情符號的使用或許既有趣又能表現情緒,但表情符號也容易過度簡化並抹消差異,從而延續了已經很「暴力的權力結構」中的規範意識形態[^ideology],例如只選擇呈現具有特定膚色的人,而忽略其他人。關於人如何被再現這點,存在著明顯的不平等,因此我們必須質疑是誰為這些再現設定了標準。此處的問題,有一部分在於為何這種操作能被塑造為「好玩」的形象,以及這如何掩蓋了監控我們情緒狀態的其他過程,尤其是在工作場所之中(我們將在第四章〈資料擷取〉中回頭討論這個問題)。Process Studio 的 *AIMoji* 計畫運用深度學習的技術,並訓練現有的表情符號資料[^almoji],進而擾亂化約的再現邏輯、提供介於各式形狀、表情和情緒之間的多種突變,從而拒絕通用主義,並突顯了前述這些問題。以上是一些本章想要探討的議題,我們將透過介紹幾何變量,來學習如何產生有別於此(也許更為政治正確)的替代方案。我們將從平面設計師大衛・萊因福特(David Reinfurt)的作品《*Multi*》開始,來示範幾何的基礎,並協助讀者了解如何從簡單的排版元素產生不同的面部表情和構圖。 * * * ## start() ![multi](https://gitlab.com/aesthetic-programming/book/-/raw/master/source/2-VariableGeometry/ch2_1.gif) *圖 2.1:大衛・萊因福特(David Reinfurt)的作品《Multi》,感謝原設計者提供圖片。* 《Multi》(<http://www.o-r-g.com/apps/multi>)[^multi]靈感來自另一位設計師恩佐·馬里(Enzo Mari),他於 1957 年花費整整一年的時間,探索物體(蘋果)的基本形式。萊因福特解釋道:「他不是想畫一顆蘋果,而是想畫『那顆』[通用] 蘋果,亦即一個完美的象徵,專為工業再生產的序列邏輯而設計。」《Multi》便是這種想法的變化形,以手機應用程式的形式來進行資訊複製,以最簡易的標點符號構成 1728 種可能的排列組合或表情符號。使用預設的字型符號無疑是《Multi》概念的魅力所在,但出於我們的目的,我們在此將練習用基本的幾何元素,從頭開始繪製這些字型符號。 ## 原始碼 ![](https://gitlab.com/aesthetic-programming/book/-/raw/master/source/2-VariableGeometry/ch2_2.gif) *圖 2.2:混合《Multi》概念的繪圖的螢幕截圖* RunMe, <https://aesthetic-programming.gitlab.io/book/p5_SampleCode/ch2_VariableGeometry/>. ```javascript= /*靈感來自大衛・萊因福特(David Reinfurt)的作品《Multi》*/ let moving_size = 50; let static_size = 20; function setup() { createCanvas(windowWidth, windowHeight); frameRate(15); } function draw() { //背景 background(random(230, 240)); //左 noStroke() fill(0); rect(97, 169, 79, 12); //右 rect(365, 184, 20, 15); fill(20, 20, 120); beginShape(); vertex(365, 199); vertex(385, 199); vertex(372, 216); vertex(358, 216); endShape(CLOSE); //下 noFill(); stroke(130); strokeWeight(2); ellipse(255, 350, static_size, static_size); //滑鼠互動 stroke(180); ellipse(mouseX, mouseY, moving_size, moving_size); if (mouseIsPressed) { static_size = floor(random(5, 20)); } } ``` * * * 上面的程式碼繪製了數個形狀並能呈現簡單的互動效果: * 背景以閃爍的灰階色彩所填滿 * 左側為一條黑色的矩形水平直線 * 右側為一個黑色矩形和一個藍色多邊形 * 下方為一沒有填充任何色彩的圓形,筆觸顏色為灰色 * 移動滑鼠時,一個灰色的圓形輪廓也會跟著移動 * 您可以點擊滑鼠,灰色圓形的大小會隨之改變 ## 座標 在前一章中,我們簡單討論了 x 和 y 座標軸,這是在畫布上以不同測量方式定位及繪製各種物件的基本概念。`createCanvas(windowWidth,windowHeight)` 這一行程式碼,意指創造一個寬度、高度與視窗大小一致的畫布。與此不同,上一章範例 `createCanvas(640,480);` 則是為畫布設定精確的像素尺寸,而不固定的畫布大小可帶來靈活性。在這段範例程式碼中,背景顏色填滿了整個視窗,畫布做為一處空間的概念,則根據幾何特性而有所變異。我們應該自我提醒的是,在數學中原點 [0,0] 通常位於網格紙/螢幕的中心,但在 p5.js 等程式語言中,原點是位於左上角(見上一章節的圖 1.11)。這會影響物件的放置方式,並因參考框架的存在而改變我們對空間或畫布的感知/理解。 ## 課堂練習 ```javascript= function setup() { createCanvas(windowWidth, windowHeight); frameRate(15); } function draw() { background(random(230,240)); } ``` 提醒您,一個網頁/應用程式的結構應包括 HTML、一個能夠運作的 JavaScript 檔案(例如 sketch.js)以及相關的 p5.js 函式庫。 - 在一個有效的 JavaScript 檔案中鍵入或複製上述原始碼,然後儲存。在 Atom 上運行該程式(使用 live-atom-server),其後螢幕上背景應會開始閃爍。 - 這裡有幾個新的語法範例,另一種說法是以稍微不同的方式使用之前學過的語法: - `frameRate()`:設定電腦運行程式時每秒將有多少個影格。預設值為 60,這裡將其設置為 15(參見第 3 行),因此您可以比較清楚地看到每一個影格的背景顏色(你也可以將閃爍/影格速率與上一章中的範例程式碼做比較)。 - `random(230,240)`:在前面的範例程式碼中,`random()` 函式裡只用了一個參數。此範例則提供了兩個參數,展示這個函式的不同使用方式。查看參考指南 (<https://p5js.org/reference/#/p5/random>)[^random],便會知道隨機函式回傳的是一個浮點數,這表示該數字並非整數,而是帶有小數點。在這種情況下,程式將回傳一個大於或等於 230.0 但小於 240.0 的浮點數(參見第 7 行),例如 231.34387。 - 下一步,您必須要記住如何使用網頁主控台(在 Firefox 的路徑是 Tools > Web Developer > Web Console)。 - 輸入 `print(width);` 然後按下 enter。 - 輸入 `console.log(width, height);` 然後按下 enter。 ![](https://hackmd.io/_uploads/HJp6l23ch.png) *圖 2.3:簡單習作* 輸入語法 `print(width);` 時,網頁主控台區域(見圖 2.3)會以像素為單位顯示實際寬度。另外,使用相當於 JavaScript 中的螢幕輸出函式 `console.log(width, height);`(這並非 p5.js 函數)時,則會根據您的螢幕大小顯示出兩個數值(您可以調整螢幕並再次嘗試,從而取得不同的數值)。只要在網頁主控台區域輸入這兩行,就能要求程式提供畫布的寬高數值。「width」和「height」兩者皆為 p5.js 的內建變數,專門用來查詢畫布尺寸,因此這個程式可以理解其意義(譯註:指變數不需要先宣告即可使用)。 ## 變數 在程式設計時,width 和 height 皆稱為「變數」(Variables),這是一個重要概念。在電腦程式中,變數是用來儲存資料和資訊的。您可以把變數想像成一個給定的廚房用容器,可用以放置不同類型的物品(如食物、廚房用具等),而這些物品可以其他東西替換,容器也能用來存放物品以備日後之用。變數的主要類型有兩種:在結構或函式區塊中定義的「區域變數」(local variables),只能在該程式碼區塊中使用;而可以在程式碼任何地方使用的,則稱為「全域變數」(global variables)。全域變數必須在程式 setup 之前進行定義(譯註:這裡指定義於 setup() 函式之前),位置通常會在程式碼的前幾行。 在前面的練習中,`windowWidth` 後面範例程式碼(第2行)內的數值,指的是被設為畫布寬度的視窗寬度。延續前述的容器比喻,我們可以說,這個名為「width」的容器(我們剛剛在網頁主控台中輸入的名稱)已被標記,並被用以儲存數值。程式可以透過使用 `width` 變數來取得畫布的尺寸,該數值會根據您的視窗寬度而更動,並且可以使用網頁主控台來取得和顯示(您也可以為其他需求,或在草稿碼其他部分使用變數 `width` 和 `height`)。 特別值得注意的是,您也可以自行為變數名稱命名(換句話說,您可以創造屬於自己的容器類型,並儲存其他數值)。 ```javascript= let moving_size = 50; let static_size = 20; … ellipse(255, 350, static_size, static_size); … ellipse(mouseX, mouseY, moving_size, moving_size); if (mouseIsPressed) { static_size = floor(random(5, 20)); } ``` 以上摘錄繪製兩個不同大小橢圓所需的完整程式碼的片段(如前一章所述,橢圓函數的最後兩個參數指的是寬度和高度)。不同於第一章〈入門〉是在函式中放置一個固定數值,本章將使用變數來保存數值(請見第 4 和第 6 行),特別是可以在程式的不同區塊重複使用的全域變數。使用變數需要進行三個步驟: 1. **宣告:** 為您想用來儲存數值的容器想一個名稱(以便您和他人閱讀時理解其意義,不過,這裡當然有空間可以進行概念性的取徑)。開頭請以語法「let」[^let]宣告(見上方程式碼第 1-2 行) 變數的命名有以下特定規則: * 通常以小寫英文字母開頭,而非數字或標點符號。 * 可包含英文字母大小寫混合字串及數字。 * 不可使用標點符號。 2. **初始化/賦值:** 您想在容器裡儲存什麼?是一個數字嗎?您必須使用等號來賦予一個值。在這個入門的階段,了解以下四種資料型態會有助於學習: * *number*,任何形式的數字。可以是整數,也可以是含小數點的浮點數 * *string*,字串。字串可以是單一或許多個字母,必須以單引號或雙引號括起來,例如:`let moving_size = "sixty";` * *boolean*,布林值。可以是 true 或 false,例如:`let moving_size = true;` * *color*,色彩值。可使用紅綠藍(RGB)或 HSB(色度、飽和度、亮度)等色彩設定方法,例如:`let moving_size = color(255,255,0);`,詳請參見「p5.js color reference」(<https://p5js.org/reference/#/p5/color>)。[^color] 3. **(重複)使用:** 您希望如何、何時取得儲存下來的資料?若變數會隨時間發生變化,您或許會想要多次重複使用。 在上面摘錄的程式碼中,步驟 1、2 被結合成一體,寫作 `let moving_size = 50;`。這裡有兩個變數:「moving_size」和「static_size」(請參見第 1 行和第 2 行),不過,我們可以說變數「static_size」其實比另一個變數更為動態。因為它的數值會隨滑鼠點按而變化,如第 8-10 行所示(如果您預計值不會發生變化,也可以考慮使用 `const`[^constant],在整個程式中,這個值會一直保持不變)。 範例中還有兩個變數:`mouseX` 和 `mouseY`(請見第 6 行),它們會追蹤與游標位置相應的 x 和 y 坐標,因此會隨著滑鼠的移動而改變。想知道確切的 mouseX 和 mouseY 坐標,也可以使用 `print()` 或 `console.log()` 函式,從而在網頁主控台區域顯示這兩個值(小練習:如何在網頁主控台上以一行程式碼來顯示或在螢幕上輸出 mouseX 值?)。 雖然以容器的比喻來說明變數的概念相當常見,但很重要的是,我們必須補充一點:每個容器都有一個位址(可以想成是容器在貨架上的特定位置,電腦運算時需要知道容器在何處)。變數名稱可以用人類可讀和具有意義的方式進行自訂,但在執行變數時,卻又並不會考慮到這些意義,因此程式設計會在自然語言表達以及電腦操作和執行之間搖擺(我們將在第七章《言說程式碼》中回到此處關於雙重編碼的討論)。 從技術上來說,宣告一個變數的同時,也代表宣告了一個位於電腦記憶體中,可以保存該值的位址。簡言之,每個變數都儲存在電腦實體而有形的記憶體區塊,如隨機存取記憶體(RAM),而該區塊裡的空間也能進行重新配置。各區塊都擁有一個稱為記憶體位址的標識符號,以便電腦在程式運行時知道在哪裡儲存和取得該區塊。建立和宣告變數不僅關乎寫程式,還涉及儲存資料、空間分配等硬體問題。因此,軟體和硬體是密不可分的,只是在處理資料時,我們無法看到電腦的內部微結構[^chun]。 ### 為何使用變數? 學會撰寫較為複雜的程式後,您會發現用變數來儲存值和資料是相當常見的方式。更重要的是,變數的值可以在程式運作時即時更改。上面提到的變數 `mouseX` 和`mouseY` 便說明了這一點,因為滑鼠的座標會因移動而改變。我們也將在下一章介紹陣列、迴圈和重複等概念時再次討論變數。 會使用變數還有另一個原因:若程式碼比較長,將所有程式宣告的變數都放在一個概覽中統一呈現會比較一目瞭然。而若在一個複雜的程式中,有許多地方都使用到同一個變數,您則可以直接更改全域變數的值來更改全部,而不用一一修改整份程式裡的多個部分,在測試/優化程式時,此功能可讓您無需針對特定、多行的程式碼進行修改,可謂相當實用。這又可以延伸到變數的可重複使用性。變數不僅可以在不同的函數中使用,更能多次利用(也可以作為傳遞給函式子程式的引數,我們將在下一章中討論)。一個很好的例子是範例程式碼中用於繪製橢圓和矩形的 `static_size` 變數,此變數的功能為處理空間中的變化和組合形狀。 此外,透過使用精心挑選,或者至少可以暗示變數的某些行為或動作的變數名稱,也能讓其他人更容易閱讀您的程式碼。隨著您越來越進步,您可能會與他人合作編寫程式碼,或編寫行數更多、規模的更大的程式,這種情況下,程式碼的可讀性更會成為重要考量。 ## 其他函式 本節將簡要介紹完整原始碼的一些其他新函式。若想繪製和設計表情符號,必須要在形狀、顏色和空間構圖方面做出各種不同的決定。 - `noStroke()`、`strokeWeight()`:這些函示代表形狀的設定,如輪廓和邊框的粗細等。 - `stroke()`、`fill()` 和 `nofill()`:這些函式是用來設定物件的顏色,例如邊框、形狀或文本。一般採用 RGB(預設)或 HSB 顏色設定,但若函式只有一個參數,則會顯示 0-255[^binarycolor] 之間的灰階漸層。如果函式有三個參數,如 `fill(255, 255, 0)`,則表示著物件/形狀/文字將以黃色填充(紅色和綠色的混合,無藍色成分)。名為「alpha」的可選填參數則是指顏色的不透明度,例:`fill(255, 255, 0, 127)`。 - `rect()`:此函式的使用方式類似於我們用以繪製橢圓的函示,但用於顯示矩形。 - `vertex()`、`beginShape ()` 和 `endShape ()`:這三個函式可透過使用多個頂點,來繪製更為複雜的形狀。`vertex()` 函式用以指示 x 和 y 座標,而所有頂點都可以使用 `endShape()` 中的「CLOSE」引數來連接。`beginShape()` 則用於記錄多邊形等複雜形狀的起始點。 - `floor()`:`random()` 函式會傳回一個浮點數,`floor()` 則用於計算最接近的整數值。 - `if (mouseIsPressed) {}`:這是程式的條件架構,會不斷地參照滑鼠點按的操作。這將在下文更詳細討論。 ## 條件結構 條件結構非常實用,它們讓您可以透過指定條件,來設定不同的路徑。事實上,基於條件的決定並不是寫程式的專利。比如在日常生活中,您也可以說出「如果餓了就吃點東西,如果渴了就喝點水,再不然就小睡一下」這種條件式語句。 ```javascript // 人類語言中的範例 if (I am hungry) { eat some food; } else if (thirsty) { drink some water; } else{ take a nap; } ``` 上面是一個「虛擬碼」(pseudocode)的例子,展示日常生活的抉擇在程式設計中可能長什麼樣子。關鍵字和語法 `if` 後緊接著便是條件,而此語法會檢查某個條件是否成立。因此,整個 if 語句是一個「布林運算式」(Boolean expression),也就是說,在真(True)或偽(False)兩個可能值中,有其中一個取值會是可能的,兩個取值各自會導向不同的路徑和操作。在電腦科學中,布林資料類型有兩個可能值,用以表示邏輯的兩個真值。 在範例程式碼中,我們實作了條件邏輯,用來持續不斷地檢查是否有點按滑鼠的操作發生,這就是為什麼點按滑鼠時,橢圓的大小會隨之變化。 ```javascript if (mouseIsPressed) { static_size = floor(random(5, 20)); } ``` ### 關係運算子 若要使用 `if()` 語法建立自己的條件陳述式,您可以利用多種組合來創造更複雜的運算式。舉例而言,您可以使用語法 `else if` 或邏輯運算子的組合來處理許多不同的情況,這裡再以邏輯「AND」(程式碼作「&&」)的情況,舉出另一個虛擬碼範例: ```javascript if (I am hungry) && (I am in a good mood) { print("go out"); } ``` 以下列出可在條件陳述式中使用的關係運算字和邏輯符號: ```javascript /* 關係運算子: > 大於 < 小於 >= 大於或等於 <= 小於或等於 == 等於 === 等於 (包含嚴格的資料類型檢查) != 不等於 !== 不等於 (包含嚴格的資料類型檢查) */ /* 邏輯運算子:布林邏輯: && 邏輯上的「AND」(與) || 邏輯上的「OR」(或) ! 邏輯上的「NOT」(非) */ /* 範例: if () { //在這裡做某事 } else if() { //在這裡做某事 } else{ //在這裡做某事 } */ ``` 下面是一個使用條件結構和條件運算子的小型草稿碼範例。儘管所有「if」或「else-if」的條件語句皆為真,但網頁主控台只會在螢幕上輸出「一個」條件。這是因為程式在滿足第一項條件後就會退出結構。換言之,順序非常重要,程式在執行至第一個為真的陳述式後,將不再運行其它「else-if」陳述式。 ```javascript let x = 18; if (x > 10 || x <= 20 ) { console.log("one"); } else if (x == 18) { console.log("two"); } else if (x === 18) { console.log("three"); } else { console.log("four"); } ``` ## 基本算術運算子 程式設計也可進行算術運算,這通常在函式的參數中進行。以下列出基本算術運算子: - (`+`) 加:用於加法和連接,可用於數字和文字/字元 - (`-`) 減 - (`*`) 乘 - (`/`) 除 - 特殊運算子:(`++`) 遞增、(`--`) 遞減 * * * 您可以在網頁主控台區域嘗試以下程式碼: ```javascript console.log(2*3); ``` > Output: <br> "6" ```javascript console.log("hello" + "world"); ``` > Output: <br> "helloworld" ## 課堂討論 1. 檢視一下現有的幾何表情符號(<https://gitlab.com/aesthetic-programming/book/-/blob/master/source/2-VariableGeometry/emojis.jpeg>)或手機上可使用的表情符號,可否就一個表情符號來描述其形狀?是什麼構成了這張臉?特定面部表情的構成需要哪些基本幾何元素?翻譯其意義的過程中又丟失了什麼? 2. 請反思人類情感,以及其漫畫表現(表情符號)的複雜性。您使用表情符號的體驗如何?表情符號的文化和政治含義是什麼(可參考上文的內容和介紹)? 3. 在這張臉之外,請檢視一下更多其他表情符號(<https://www.pngfind.com/pngs/m/90-903456_all-the-emojis-available-on-facebook-russian-revolution.png>)[^emojis2]。您有什麼想要補充的嗎? 4. 請使用 p5.js 進行實驗。您會如何將自己的想法轉化為一行行的程式碼?您可以再網頁主控台區域在螢幕上輸出滑鼠點按位置的座標,以取得您繪製的形狀更準確的位置。 ## While() 就算只用寥寥幾筆構成,人臉還是非常容易辨識,因此這會是個很好的起點,而《Multi》這項作品以極致簡單的三個字體元素排印出人臉,可說驗證這一點。顯然,人臉是日常生活和社會交往的核心,不用說,大家也認為面部特徵可以展現出人的獨特性和個性。但這個解讀其實有些流於表面。以這種方式運作的表情符號,似乎掩蓋了表情符號體驗的真實面貌,以及它們表達複雜感受的能力。人們很容易認為,表情符號這個名稱雖有「表情」兩字,但卻完全沒有情感。 在《千高原》中,吉爾斯・德勒茲(Gilles Deleuze)和菲利克斯·伽塔利(Félix Guattari)將人臉視為一種普遍強加於我們身上的「過度編碼」,這與本章前段關於 Unicode 的一些評論有所共鳴。兩位作者的主要觀點是,臉部(他們稱之為「臉性機器」)與特定的西方思想史(例如耶穌基督的臉)密切相關,而此論又將臉性的起源與白人種族(儘管耶穌並非白人)以及他們所謂由白種歐洲人傳播出去的「臉化」(強制聚焦臉部主題)掛鉤,從而提供一種理解種族偏見的方式,亦即「種族主義的運作,是基於確認某群人與白種人臉部的相差多少...」[^DG]。因此,人臉被理解為一種包含了語言和其他符號系統的「帝國機器」。作為表象的一部分,「臉」提倡同一性,並拒絕任何變形。 能夠從數位圖像或影片影格中辨識或驗證人臉的臉部辨識技術,似乎也適用於這些(帝國主義的)術語。這種技術會基於標準化資料集的模型,將某人的臉部形狀和紋理進行匹配,以達到辨識人臉的效果(我們將在第四章〈資料擷取〉中回到這項討論)。此外,資料集中白人面孔又佔了不成比例的大多數,這造成了一個眾所周知的狀況:臉部辨識系統難以辨識黑人,這個問題相當嚴重,尤其是這些技術在警務方面的應用,更因此受限。 當臉部表情改變時,這項辨識系統也會變得不可靠,即使只是較燦爛的笑容也會使結果失真,因此,現實生活中的笑臉很可能會造成辨識困難,這實在有點諷刺,就好像把「不友善」作為社會互動的標準一般。「笑臉」這個標誌性的表情符號似乎進一步強調了這點。在某些情況下,臉部本身或許能夠避免過度編碼,不過,表情符號確實是帶有偏見的「臉性機器」。因此,享受寫程式樂趣時的一項挑戰,就是要如何避免過度編碼,並開發替代的幾何形狀。 這種邏輯在芬穆珂・史奈爾汀的另一篇文章〈其他幾何形狀〉(Other Geometries)中至為明顯,該文討論了幾何形狀如何協助對抗主權基礎設施[^Snelting]。考慮到像圓形這樣簡單的形狀,以及這類形狀如何在空間和結構方面與集體形式連結,史奈爾汀如此寫道: >「圓是一種簡單的幾何形狀。[…] 圓在數學上的定義,是在同一平面中與共同中心點距離相同的所有點的集合;從一定點以定長的半徑移動的點所畫出的軌跡,就是圓形的邊界,或稱圓周。[…] 圓形在集體的實作和想像中無處不在。[… 然而,] 在更為複雜,並試圖囊括空間、物質和時間的關係概念中,圓形的平坦性卻很難提供可用以描述的詞彙,更不用說多種不同事物之間的混合體和其他不穩定的結合物了。始終與中心保持相同距離這項義務確保了平等的情況,但這種平等性卻是透過與相似性混為一談來實現的。圓形將空間分為內部和外部,這是一種難以克服的二元分離。我們迫切需要其他樞紐來向前邁進[^Snelting2]。」 史奈爾汀在尋找可以規避集體規範配置的其他幾何形狀。她還參考了以對臉部辨識系統的藝術性干預〈臉部武器化系列〉(Facial Weaponization Suite,2011-14)而聞名的札克・布拉斯(Zach Blas)的作品,從而指出節點和邊緣之間的幾何空間,並吸引更多對「關係」的關注。在過去,去中心化的分散式網路想像一直都是重新思考集中式權力結構的一部分,而上述想法則進一步「將我們對基礎設施的想望轉往其他方向」,更深入參考安娜・秦的著作,以及受真菌類分枝線狀結構「菌絲體」所啟發的「凌亂幾何」概念[^Tsing]。 接下來的挑戰,則是重新思考規範化的幾何形狀,並將它們上下翻轉、裡外顛倒。這就是本章的目的:避免幾何過度編碼並開發出替代方案。從這個意義上來說,寫程式的樂趣,便是在於能夠修改形式並偏離既定規則。寫程式時可以用不同的方式應用、調整或修改規則,甚至將之完全轉換。 ## 迷你習作:幾何表情符號 **目標:** * 嘗試各種幾何繪圖方法並尋找替代方案,特別是關於形狀和色彩繪圖方面。 * 在指定的文章基礎上,反思表情符號的政治/美學。 **更多靈感來源:** * *[AIMoji](https://process.studio/works/aimoji-ai-generated-emoji/)* by Process Studio (2019), as part of "[Uncanny Values](https://process.studio/works/uncanny-values/)," Vienna Biennale (2019). 表情符號文化相關文章: * Steve Witt, "[Chinese Characters as Ancient 'Emoji'](https://publish.illinois.edu/iaslibrary/2015/10/21/chinese-characters/)," *Glocal Notes* (2015). * Michael Grothaus, "Women Finally Get a Menstruation Emoji," *Fastcompany* (2019), <https://www.fastcompany.com/90302946/women-finally-get-a-menstruation-emoji>. **任務(RunMe):** 透過查閱 [p5.js 參考資料](https://p5js.org/reference/),探索形狀、幾何和其他相關語法,並設計出兩個表情符號, **在您的 ReadMe 檔案中可供思考的問題:** * 請**描述**您的程式,並說說您在寫程式的過程中使用了哪些元素,以及學到了什麼。 * 您要**如何**將您的表情符號置於涉及再現、身份、種族和殖民主義等政治,更為廣泛的社會和文化背景之下?請試著借助指定讀物和您寫程式的過程來思考,然後將其擴展到自身經驗和想法。這是一項艱鉅的任務,您可能會需要花一些時間來仔細思索。 ## 指定讀物 * Roel Roscam Abbing, Peggy Pierrot and Femke Snelting, "Modifying the Universal," in Helen Pritchard, Eric Snodgrass & Magda Tyżlik-Carver, eds., *Executing Practices* (London: Open Humanities Press, 2018), 35-51, <http://www.data-browser.net/db06.html>. * Daniel Shiffman, "1.3,1.4,2.1,2.2: Code! Programming with p5.js," (2018) <https://www.youtube.com/watch?v=yPWkPOfnGsw&list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA&index=2>. * Femke Snelting, "Other Geometries," *transmediale journal* 3, October 31 (2019), <https://transmediale.de/content/other-geometries>. ## 延伸讀物 * Crystal Abidin and Joel Gn, eds., "Histories and Cultures of Emoji Vernaculars," *First Monday* 23, no. 9, September (2018), <https://firstmonday.org/ojs/index.php/fm/issue/view/607>. * Christian Ulrik Andersen and Geoff Cox, eds., *A Peer-Reviewed Journal About Machine Feeling* 8, no. 1 (2019), <https://aprja.net//issue/view/8133>. * Derek Robinson, "Variables," in Matthew Fuller, ed., *Software Studies: A Lexicon* (Cambridge, MA: MIT Press, 2008). * Xin Xin, "1.2 2D Primitives - p5.js Tutorial," (2020) <https://www.youtube.com/watch?v=hISICBkFa4Q>. * Xin Xin, "1.3 Color and blendMode() - p5.js Tutorial," (2020) <https://www.youtube.com/watch?v=fTEvHLLwSBE>. ## 註釋 [^Fun]: Linus Torvalds and David Diamond, *Just for Fun: The Story of an Accidental Revolutionary* (Knutsford: Texere Publishing, 2001),參見 <http://en.wikipedia.org/wiki/Just_for_Fun>。其他範例包括:Jeremy Gibbons and Oege de Moor, *The Fun of Programming* (London: Palgrave Macmillan, 2003)。 [^Fun2]: 請參見童書 Vicky Owyang Chan, *Geometry Is Fun For Me* (Indianapolis, IL: Dog Ear Publishing, 2017)。 [^Olga]: Olga Goriunova, *Fun and Software: Exploring Pleasure, Paradox and Pain in Computing* (New York, London: Bloomsbury, 2014), 4. [^Femke]: Femke Snelting, "Other Geometries," *transmediale journal* 3 (October 31, 2019, <https://transmediale.de/content/other-geometries>. [^Emojis]: Roel Roscam Abbing, Peggy Pierrot and Femke Snelting, "Modifying the Universal," *Executing Practices*, Helen Pritchard, Eric Snodgrass & Magda Tyżlik-Carver, eds. (London: Open Humanities Press, 2018), 35-51, <http://www.data-browser.net/db06.html>. 此外,針對類似主題,芬穆珂・史奈爾汀有一個時長一小時十五分鐘的演講影片,請見:<https://www.youtube.com/watch?v=ZP2bQ_4Q7DY>。其他參考資料包括:Crystal Abidin and Joel Gn, "Between Art and Application: Special Issue on Emoji Epistemology," *First Monday* 23, no. 9 (September 3, 2018); Luke Stark, "Facial recognition, emotion and race in animated social media," *First Monday* 23, no. 9 (September 2018), 3; Miriam E Sweeney and Kelsea Whaley, "Technically White: Emoji Skin-tone Modifiers as American Technoculture," *First Monday* 24, no. 7 (1 July 1, 2019). [^Unicode]: 請見 <https://en.wikipedia.org/wiki/Unicode#Origin_and_development>。 [^Telegraph]: 請見 <https://www.telegraph.co.uk/technology/2016/07/15/new-gender-equality-emoji-to-show-women-at-work/>。 [^ideology]: Abbing, Pierrot and Snelting, *Modifying the Universal*, 210. [^almoji]: 該計畫採機器學習演算法,並以內含 3145 個現有表情符號的資料集作為輸入資料,來產生各種不可思議的表情符號模型。請參閱 <https://process.studio/works/aimoji-ai-generated-emoji/>。該計畫是 2019 年維也納雙年展「不可思議的價值觀」(Uncanny Values)展覽的一部分,<https://process.studio/works/uncanny-values/>。我們將在第十章更詳細地討論機器學習。 [^multi]: 請參見 <http://www.o-r-g.com/apps/multi>。《Multi》也為 Open Humanities 出版的 DATA 瀏覽器系列提供多種不同的書籍封面,<http://www.data-browser.net/>。 [^random]: 參見 p5.js 的 random 說明,<https://p5js.org/reference/#/p5/random>。 [^let]: ES6(ECMAScript - 腳本語言規範標準化)中新增了 `let`,用來宣告一個變數(不過 `var` 仍然很常被使用)。兩者的區別在於,let 屬於區塊作用域(block scoped),而 var 則為函式作用域(function scoped)。使用 `let` 時,如果於全域和區域兩邊都宣告了同一個變數,則區域變數值將被限制在特定的程式碼區塊中,並且不會被覆蓋。有關兩者區別的更多資訊,請參閱 <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var> 和 <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let>。 [^color]: 參見 p5.js 的 color 說明,<https://p5js.org/reference/#/p5/color>。 [^constant]: 參見 p5.js 的 const 說明,<https://p5js.org/reference/#/p5/const>。 [^chun]: 全喜卿討論了作為高階語言,將運算過程隱藏起來的符號式程式語言。這既賦予了使用者創造的能力,但反過來又使機器的內部的運作變得神秘。在此,變數可看作是電腦運作抽象化的其中一例。我們將在第六章〈物件抽象化〉中討論這點。參見 Wendy Hui Kyong Chun, “On Software, or the Persistence of Visual Knowledge,” *Grey Room* 18 (January 2005): 38, <https://doi.org/10.1162/1526381043320741>。 [^binarycolor]: 紅、綠、藍是所謂的三原色,將它們疊加在一起便能產生多種顏色。RGB 顏色值的範圍為 0 到 255,因此每種原色皆有 256 個可能的值。這個數值背後的原因,是所有顏色都是 24 位元格式,其中紅(R)、綠(G)、藍(B)各佔 8 位元。每個位元都儲存了兩個二進位值,而 2 的 8 次方得出 256,正是每種顏色的確切可能範圍。RGB 系統與二進制系統中的運算性質習習相關。 [^emojis2]: 參見 <https://www.pngfind.com/mpng/ohwmTJ_all-the-emojis-available-on-facebook-russian-revolution/>。 [^DG]: Gilles Deleuze and Félix Guattari, *A Thousand Plateaus: Capitalism and Schizophrenia* (Minneapolis: University of Minnesota Press, 1987), 178. [^Snelting]: Snelting, "Other Geometries." [^Snelting2]: Snelting, "Other Geometries." [^Tsing]: Anna Lowenhaupt Tsing, *The Mushroom at the End of the World: On the Possibility of Life in Capitalist Ruins* (Princeton, NJ: Princeton University Press, 2017). [^Blas]: The series of works *Facial Weaponization Suite* exposes some of the inequalities associated with biometric facial recognition by making collective masks, including *Fag Face Mask* a response to scientific studies that say they can determine sexual orientation through rapid facial recognition techniques, and another mask that explores the inability of biometric technologies to detect dark skin. See <http://www.zachblas.info/works/facial-weaponization-suite/>. [^playground]: See the tool p5.playground developed by Yining Shi, <https://1023.io/p5-inspector/>.