③⑥以程式繪製烏克蘭與巴西國旗

使用 UIBezierPath 走直線與圓弧練習

Min
彼得潘的 Swift iOS / Flutter App 開發教室
88 min readAug 14, 2023

--

基本題

今天要試著第一次不使用圖形化介面來畫出圖案。講到國旗,立刻想到現在還在進行中的俄烏戰爭。恰巧烏克蘭的國旗是比較簡單的幾何圖形,決定先畫出烏克蘭國旗,也算是小小的聲援他們。烏克蘭國旗的藍色代表象徵自由與主權的天空及海洋;黃色代表麥田,象徵該國悠久的農業歷史。

烏克蘭國旗

圖形疊疊樂:Subview 與 Superview

因為國旗的圖案都不是單一顏色,把不同的 View 前後堆疊會使用到 Subview 跟 Superview 的觀念。舉日本國旗為例,當先做好白色的長方形,再把紅色的圓形放到白色長方形之中,那紅色的圓形就是白色長方形的 Subview。白色長方形則是紅色圓形的 Superview。

與眾不同的顏色設定:UIColor

因為在 Swift 裡面,RGB 三個顏色都是從 0–1,不像他們原先的 0–225,因此在使用 UIColor 為圖形上色的時候,必須要把他們的 RGB 數字各除以 225。

開始製作烏克蘭國旗

在這邊先放我第一次失敗的代碼。我天真的以為,烏克蘭國旗的兩條長方形沒有誰前誰後的關係,只有上下並排,那好像不需要用到 subview 的概念,直接做出一上一下的長方形,更改 y 軸就可以了(也太喜歡複製貼上)。聽起來很美好…

import UIKit
// 設定烏克蘭國旗上方的長方形為變數 rect1
var rect1 = CGRect (x: 0, y: 0, width: 1915, height: 638)
// 把剛剛的長方形 rect1 放到 UIView 裡面,現在他們合為一體變成 rect1View
let rect1View = UIView(frame: rect1)
// 設定 rect1View 的顏色
rect1View.backgroundColor = UIColor(red: 35/255, green: 86/255, blue: 177/255, alpha: 1)
// 設定烏克蘭國旗下方的長方形為變數 rect2
var rect2 = CGRect (x: 0, y: 638, width: 1915, height: 638)
// 把剛剛的長方形 rect2 放到 UIView 裡面,現在他們合為一體變成 rect2View
let rect2View = UIView(frame: rect2)
// 設定 rect2View 的顏色
rect2View.backgroundColor = UIColor(red: 248/255, green: 216/255, blue: 73/255, alpha: 1)
// 顯示 rect1View
rect1View
// 顯示 rect2View
rect2View

實際上,他們沒辦法上下並排顯示在 playground 裡面,分成兩條。

果然就像登山一樣,還是不要想走捷徑得好,延著大路走比較安全。

更正後的代碼:

import UIKit
// 設定烏克蘭國旗上方的長方形為變數 rect
var rect = CGRect (x: 0, y: 0, width: 1915, height: 1276)
// 把剛剛的長方形 rect 放到 UIView 裡面,現在他們合為一體變成 rect1View
let rect1View = UIView(frame: rect)
// 設定 rect1View 的顏色
rect1View.backgroundColor = UIColor(red: 35/255, green: 86/255, blue: 177/255, alpha: 1)
// 更改 rect 為烏克蘭國旗下方的長方形位置
rect = CGRect (x: 0, y: 638, width: 1915, height: 638)
// 把剛剛的長方形 rect2 放到 UIView 裡面,現在他們合為一體變成 rect2View
let rect2View = UIView(frame: rect)
// 設定 rect2View 的顏色
rect2View.backgroundColor = UIColor(red: 248/255, green: 216/255, blue: 73/255, alpha: 1)
// 在 rect1View 中加入要當 subview 的 rect2View
rect1View.addSubview(rect2View)
// 顯示 rect1View
rect1View

成功了!

補充一下第二次的代碼,除了使用 addSubview 來添加圖形之外,我少使用了變數 rect 2(原先使用 rect 1 跟 rect 2)。因為當 rect1View 設定完顏色之後,其實不會再使用到 rect 裡面的東西,因此這個變數可以更改為下方長方形的資料。而且如果只用一次的話,我也應該設定兩個常數才是。這個觀念還要再適應才行。

進階題

做完長方形的國旗,要來挑戰不同的形狀了!今年因緣際會認識了許多熱情的巴西人,來繪製巴西國旗送給他們!

巴西國旗的背景綠色與黃色菱形源於巴西帝國時期(c. 1822–1889)的國旗,中央的藍色球形是天球儀,上面的有27顆以南十字星為中心的白星,中央寫著 ORDEM E PROGRESSO是葡文的巴西國家格言:秩序與進步。

規劃繪製順序

因為設定 subview 是以先來後到的順序決定圖層的高低,先加入的在下面,後加入的在上方,並遮住先加入的 subview。因此,讓綠色背景成為 groundView,接著依序加入黃色菱形、藍色圓形、白色帶子與星星應該是安全的順序。我們來按著順序一一完成它。

使用 SwiftUI 預覽 UIBezierPath 的繪圖結果

在開始之前,因為要畫的圖片比較複雜,我們先套用 SwiftUI 來創建方便預覽結果的介面。參考彼得潘的方式一步一步建立:

先建立專案,選擇 SwiftUI:

在 ContentView.swift 貼上以下程式,將能利用 SwiftUI 幫我們預覽繪製的圖案:

import SwiftUI

struct DrawView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()

return view
}

func updateUIView(_ uiView: UIView, context: Context) {
}

}

struct ContentView: View {
var body: some View {
DrawView()
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

果然與 playground 不一樣,模擬器直接在旁邊可視。

接下來,皆在 function makeUIView 裡面繪圖,將程式寫在 let view = UIVIEW()return view 之間:

func makeUIView(context: Context) -> UIView {
let view = UIView()

return view
}

以 UIBezierPath 繪製路徑

在開始前,先了解一下原理:

可以把 UIBezierPath 想成拿著一支筆,只用一筆劃畫完整個圖形。所以先想好所有圖形會經過的轉折點(像是小朋友喜歡的連連看畫圖,從 1 連到 100 可以畫出一隻動物的那種),使用 UIBezierPath 從起點開始,延著轉折點,最後回到起點,就可以產出一個圖形。

UIBezierPath 就像是這張圖,給出每個點的位置,由 1 畫到 44 再畫回 1,就會完成一隻鴨子

先用 UIBezierPath 畫出背景的綠色長方形,以下是在 makeUIView 裡使用 UIBezierPath 繪製長方形的路徑:

func makeUIView(context: Context) -> UIView {
let view = UIView()

let path = UIBezierPath()
path.move(to: CGPoint(x:0, y:0))
path.addLine(to: CGPoint(x: 393, y: 0))
path.addLine(to: CGPoint(x: 393, y: 275))
path.addLine(to: CGPoint(x: 0, y: 275))
path.close()

return view
}

func updateUIView(_ uiView: UIView, context: Context) {
}

以 CAShapeLayer 生成能顯示在畫面上的形狀

由於 UIBezierPath 繪製的是虛擬路徑, App 畫面上顯示不出來,所以要產生能顯示在畫面上的 CAShapeLayer。

但因為rectLayer.path(長方形)的型別是 CGPath,與 CAShapeLayer 代表某形狀的型別不同,人鬼殊途。得再利用 path. cgPath 讀取長方形的路徑後再存到 rectLayer.path 裡。詳見:

但到這邊只會顯示 View,還要再加入一行view.layer.addSublayer(triangLayer)才會呈現剛剛的 rectLayer。

func makeUIView(context: Context) -> UIView {
// 創建一個新的 UIView 實例
let view = UIView()

// 創建一個 UIBezierPath 實例,用於定義形狀的路徑
let path = UIBezierPath()

// 移動畫筆到指定的起始點 (0, 0)
path.move(to: CGPoint(x: 0, y: 0))

// 添加一條線到指定的點 (393, 0)
path.addLine(to: CGPoint(x: 393, y: 0))

// 添加一條線到指定的點 (393, 275)
path.addLine(to: CGPoint(x: 393, y: 275))

// 添加一條線到指定的點 (0, 275)
path.addLine(to: CGPoint(x: 0, y: 275))

// 關閉路徑,將筆點連接到起始點,形成一個封閉的形狀
path.close()

// 創建一個 CAShapeLayer 實例,用於在 UIView 上繪製路徑
let rectLayer = CAShapeLayer()

// 設置 CAShapeLayer 的路徑為之前定義的 UIBezierPath 的路徑
rectLayer.path = path.cgPath

// 將 CAShapeLayer 添加為 UIView 的子圖層,從而將繪製的形狀添加到 UIView 上
view.layer.addSublayer(rectLayer)

// 返回創建並設置好的 UIView
return view
}

上面程式的註解寫的很專業吧!是請 AI 寫的!

下方如願在預覽中看見長方形。

基底的長方形出現了

不過我們的長方形是綠色的,而不是預設的黑色。因此設定 CAShapeLayer 的 fillColor,改變填色(這行程式放在 let rectLayer = CAShapeLayer()之後)。

rectLayer.fillColor = CGColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)

耶比!

加入第二個 Layer

接著是黃色菱形。因為 path 要重複使用,因此把它改為變數。因為黃色菱形是後出現的,因此為疊在綠色長方形上面。

func makeUIView(context: Context) -> UIView {
let view = UIView()

// 綠色長方形
var path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 393, y: 0))
path.addLine(to: CGPoint(x: 393, y: 275))
path.addLine(to: CGPoint(x: 0, y: 275))
path.close()
let rectLayer = CAShapeLayer()
rectLayer.fillColor = CGColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
rectLayer.path = path.cgPath
view.layer.addSublayer(rectLayer)
// 黃色菱形
path = UIBezierPath()
path.move(to: CGPoint(x: 33, y: 138))
path.addLine(to: CGPoint(x: 197, y: 33))
path.addLine(to: CGPoint(x: 360, y: 138))
path.addLine(to: CGPoint(x: 197, y: 243))
path.close()
let diamondLeyer = CAShapeLayer()
diamondLeyer.fillColor = CGColor(red: 249/255, green: 224/255, blue: 75/255, alpha: 1)
diamondLeyer.path = path.cgPath
view.layer.addSublayer(diamondLeyer)

return view
}

第二步完成!

加入圓形 Layer

接著是天球儀,漂亮的藍色圓形。先參考圓形的畫法:

圓形與橢圓形使用 UIBezierPath(ovalIn:CGRect()) 。ovalIn 是可以在矩型 CGRect 的範圍中畫出橢圓與圓形的參數。只要給出 CGRect 裡的座標與矩型大小,就可在其中生成橢圓/圓形。

// 天球儀
//僅改變第一行為圓形,其他行規則一樣
path = UIBezierPath(ovalIn: CGRect(x: 127, y: 68, width: 139, height: 139))
let celestialGlobeLeyer = CAShapeLayer()
celestialGlobeLeyer.fillColor = CGColor(red: 12/255, green: 38/255, blue: 113/255, alpha: 1)
celestialGlobeLeyer.path = path.cgPath
view.layer.addSublayer(celestialGlobeLeyer)
做到這邊,已經可以明確的知道是巴西國旗

接下來,才是痛苦的開始

巴西人怎麼會在國旗上寫字呢!這豈不是大幅增加了繪製的難度!!

由於星星與寫著字的白色腰帶互不相交,因此先來畫星星,最後再給他冠軍腰帶(X)。

先了解一下如何創造星星:

打開 https://www.geogebra.org/calculator 網站,上傳巴西國旗:

接著調整圖片的位置與大小:

將圖片左上角對齊(0,0),使用 A 與 B 兩點調整圖片大小。

再來複製 10 個小圓點到每個星星上,這星系實在有點大,有 27 顆星星,每一顆還都不一樣大…因此總共需要 270 個點 😱😱😱。

選取一個點 A,按下 Duplicate 可以複製出 A1,再拖移 A1 即可。直接 cmd+c,cmd+d也可以複製。

意識到這並非一兩首歌的時間可以完成,我們必須聽長一點的音樂:

太慘了,聽完這首協奏曲竟然一顆星星都還沒畫好…(原來星星才是坑阿)

因為星星實在太小,A1A2這些數字會互相干擾,還好可以讓他們不要顯示:

把左邊圈圈點掉,只留有顏色的會顯示出來

終於完成第一顆星了QQ ,記得 y 軸的負號要拿掉,因為在 Swift 裡的座標 y 軸往下是正的。程式如下:

     //白色星星1
path = UIBezierPath()
path.move(to: CGPoint(x: 147.6366010542469, y: 135.8738615169675))
path.addLine(to: CGPoint(x: 148.115501239807,y: 137.9490956543948))
path.addLine(to: CGPoint(x: 150.2971576406922,y: 138.2683624447684))
path.addLine(to: CGPoint(x: 148.5944014253672,y: 139.6518518697199))
path.addLine(to: CGPoint(x: 149.232935006114,y: 141.7802971388761))
path.addLine(to: CGPoint(x: 147.2109120004157,y: 141.0353412946715))
path.addLine(to: CGPoint(x: 145.0824667312595,y: 141.6738748754183))
path.addLine(to: CGPoint(x: 146.0906259941078,y: 139.6952843556943))
path.addLine(to: CGPoint(x: 144.614567117206,y: 138.2652352916095))
path.addLine(to: CGPoint(x: 146.4746652453757,y: 137.8272058531586))
path.close()
let whiteStar1Leyer = CAShapeLayer()
whiteStar1Leyer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar1Leyer.path = path.cgPath
view.layer.addSublayer(whiteStar1Leyer)
畫到第九顆星星的時候,才發現第一顆星星就已經位移了…

既然頭已洗下去,也沒辦法了。找更長的歌單吧!

這個 forro 歌單有 314 首歌,就不相信畫不完剩下的 26 顆星

為了怕在 GeoGebra 的座標軸裡點到一半的時候不小心移動到國旗圖,可以右鍵點選國旗並固定物件。不然會像本人一樣,80 個座標畫完發現全部位移…只能全部重來。

看看A1與它左上角星星的距離,就是整個位移的距離阿阿阿阿阿!!!!只能把前面的星星按照 x 座標- 7, y 座標 -14,80 顆一顆一顆調整回來。

點點的代號可以移位子,避免很多代號互相遮擋。拖移代號本身即可。

拖著代號往外移動,座標不會跟著動

然後像素盡可能找越大越好,因為我的巴西國旗相素不夠大,因此要放大看很小的星星的時候其實是一片模糊,等於有點半猜了。因此會看到我的星星有胖有歪(明顯是偽造的XD)

終於畫好了…不過星星比較…看得出來不是原版冏

冠軍腰帶

冠軍腰帶的組成分為白色帶子與綠色的文字。白色帶子是有著特別弧度的曲線,可以使用 UIbezierpath 旗下的 addQuadCurve 與 addCurve 兩個方法來完成。

相比畫星星是比較機械性的重複動作,畫腰帶才是燒腦的部分(都是坑,不同類型的坑XD)。先請問 ChatGPT 有關 addQuadCurve 與 addCurve 使用的場景與差異:

在 Swift 中,UIBezierPath 是一個用於創建和操作各種形狀路徑的類別。它提供了許多方法來添加直線、曲線、弧線等元素到路徑中。其中,addCurve(to:controlPoint1:controlPoint2:)addQuadCurve(to:controlPoint:) 是用於添加曲線元素到路徑的方法。

addQuadCurve(to:controlPoint:): 此方法用於添加一個二次貝塞爾曲線到路徑中。它需要兩個參數:

to:表示曲線的結束點。

controlPoint:表示曲線的控制點,它決定了曲線的彎曲程度和方向。

這個方法將以當前路徑的最後一點為起始點,然後繪製一條以控制點為控制點的二次貝塞爾曲線,終點是 to 參數指定的點。

addCurve(to:controlPoint1:controlPoint2:): 此方法用於添加一個三次貝塞爾曲線到路徑中。它需要三個參數:

to:表示曲線的結束點。

controlPoint1:表示第一個控制點。

controlPoint2:表示第二個控制點。

這個方法將以當前路徑的最後一點為起始點,然後繪製一條以兩個控制點為控制點的三次貝塞爾曲線,終點是 to 參數指定的點。

簡而言之,差別在於使用的控制點數量和曲線的彎曲程度。addQuadCurve 使用一個控制點來定義曲線,適用於簡單的弧線。而 addCurve 使用兩個控制點,使得曲線的彎曲程度更加靈活,適用於更複雜的曲線形狀。

在使用這些方法時,您需要提供適當的結束點和控制點來繪製所需的曲線。您可以通過調整控制點的位置來控制曲線的形狀。

經過 ChatGPT 詳細的解說,可以發現要畫出巴西國旗上的白帶子,因為它的曲線一次只往一個方向偏,因此只需要使用addQuadCurve 即可。

白帶子有上下左右四個邊,我們一條一條產生出來:

上邊:

上邊與下邊應該屬於另一個更大的圓形,利用 GeoGebra 提供的工具可以把圓形與角度都算出來。

原本找座標是在 Algebra 的欄位進行,先改到 Tools,往下拉到 Circles 的群組,點選第一個 Circle with Center。然後在座標區中,選好自己的圓心就會出現圓形,再選取位於白帶上的點成為圓周一點。在我的圖形裡,圓周的點是不變的,因為要去找的是能夠跟白帶的弧形完整貼合的圓形,因此固定圓周上的點之後,拖動圓心( C 點),可以調整圓形的大小到白帶的弧度。這個圓還真不是普通的大呀!

調好之後就得到我們程式所需的圓心座標,這裡還很好心的幫忙計算出半徑平方,我們只需自己開根號就能知道半徑。

接下來要找到這個大圓的圓周在天球儀中畫白帶的角度,使用 Measure 裡的 Angle:

在座標軸上點選要畫角度的三個點,角度就出現了。

白帶上邊的終點也依樣畫葫蘆可求得。

目前元素都收集到了,放進 Xcode 裡試試看,將此程式接在第 27 顆星星後面:

//白腰帶
// aDegree 是弧度
let aDegree = CGFloat.pi/180
//白帶上方,0度在右側,90度在正下方
path = UIBezierPath(arcCenter: CGPoint(x: 157.7921701008629, y: 272.2092676661875), radius: 164.538, startAngle: aDegree * 261, endAngle: aDegree * 311, clockwise: true)

註解:

let aDegree = CGFloat.pi/180 可以算出 1 度的大小,存在常數 aDegree 裡面。

arcCenter 是圓心的位置

radius 是半徑

startAngle 與 endAngle 分別是白帶上與大圓交會起迄的度數,因為 0 度在右側,90 度在正下方,因此我們剛剛得到的角度需要用 360 度減掉才能使用。

clockwise true 是順時針轉, false 為逆時針轉。

它給的角度是從右方為 0 度逆時針取的角度,但程式裡是順時針的角度,因此要用 360 度減掉98度

在 return view 之前加入下方程式,讓我們調整的內容可以被看見:

let whiteBelt = CAShapeLayer()
whiteBelt.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteBelt.path = path.cgPath
view.layer.addSublayer(whiteBelt)

成功畫出上邊,依據跟上方星星的距離看起來應該算準的,接下來畫右邊。

不用 path.close()也會自己把圖形合起來,因而得到這個形狀

右邊:

由於右邊的起訖點都在天球儀的圓周上,因此使用天球儀的圓心與半徑即可。再回 GeoGebra 查詢角度。

當初創造天球儀的正方形位置:
x: 127, y: 68, width: 139, height: 139
可知半徑:69.5
圓心位置:(x: 196.5, y: 137.5)

結果發現因為我都用圓形的資訊去計算,沒有使用到弧線的 controlPoint,也就表示,完全不會用到addQuadCurve。 但這引發了另一個問題:該用什麼方法去繼續畫呢?原本的 path.addLine 只能畫出直線,但我們需要的是弧線。在 path. 後面的方法一個一個瀏覽,發現了 addArc 好像可以一試:

path.addArc(withCenter: CGPoint(x: 196.5, y: 137.5), radius: 69.5, startAngle: aDegree * 7.18, endAngle: aDegree * 16.58, clockwise: true)

出現了!

下邊:

下邊是與上邊弧度相同的弧線,因此我們把做上邊時使用的大圓像下拖動即可。

但需要注意,因為是反方向畫回去,因此 clockwise 要設為 false。

        //白帶下邊
path.addArc(withCenter: CGPoint(x: 155.9, y: 281.8), radius: 164.538, startAngle: aDegree * 311, endAngle: aDegree * 261, clockwise: false)
能在同個視窗裡直接看到效果真的很方便,可以針對從 GeoGebra 搬過來的數據對比畫面進行微調

左邊:

其實從上圖會覺得差不多完成了,因為那段弧線很短,畫成直線不仔細看看不出來。還是先使用右邊的方法畫畫看。

//白腰帶左邊
path.addArc(withCenter: CGPoint(x: 196.5, y: 137.5), radius: 69.5, startAngle: aDegree * 194.744, endAngle: aDegree * 204.47, clockwise: true)
左圖為還未再畫一條弧線,右邊有,因此右邊看起來跟天球儀比較密合

文字:

距離完成巴西國旗,只剩一步之遙,就是葡文 ORDEM E PROGRESSO。

參考了這篇 emoji 跟旋轉的方式,每個字設定自己的位置大小與傾斜度:

//文字 ORDEM E PROGRESSO 中 ORDEM 的 O
//設定 text1 常數,加入位置與Rectangle大小
let text1 = UILabel(frame: CGRect(x: 137.7383148809027, y: 108.3, width: 10, height: 10))
//加入文字內容
text1.text = "O"
//設定文字顏色
text1.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
//設定文字字型與大小
text1.font = UIFont(name: "Helvetica-Bold", size: 8)
//將文字加入當前的 view => 可被看見
view.addSubview(text1)
//轉移文字角度
text1.transform = CGAffineTransform(rotationAngle: .pi/180 * 0)

因為通篇的圖案都是用 layer ,所以文字也用了 layer.addSublayer,然後就發生錯誤了。請教彼得潘才知道,原來屬於 storyboard 裡的元件都是 view,還是要用 addSubview 才可以…雖然還是懵懂,接下來其他篇繼續練習 iOS SDK,應該能越來越清楚。

完成啦!來跟原圖比一比!最可惜的是抓不准星星的座標,所以都偏大了一點…當作用天文望遠鏡看的吧!(X)

謝謝收看!

完整程式碼(烏克蘭)

import UIKit
// 設定烏克蘭國旗上方的長方形為變數 rect1
var rect = CGRect (x: 0, y: 0, width: 1915, height: 1276)
// 把剛剛的長方形 rect1 放到 UIView 裡面,現在他們合為一體變成 rect1View
let rect1View = UIView(frame: rect)
// 設定 rect1View 的顏色
rect1View.backgroundColor = UIColor(red: 35/255, green: 86/255, blue: 177/255, alpha: 1)
// 設定烏克蘭國旗下方的長方形為變數 rect2
rect = CGRect (x: 0, y: 638, width: 1915, height: 638)
// 把剛剛的長方形 rect2 放到 UIView 裡面,現在他們合為一體變成 rect2View
let rect2View = UIView(frame: rect)
// 設定 rect2View 的顏色
rect2View.backgroundColor = UIColor(red: 248/255, green: 216/255, blue: 73/255, alpha: 1)
// 在 rect1View 中加入要當 subview 的 rect2View
rect1View.addSubview(rect2View)
// 顯示 rect1View
rect1View

完整程式碼(巴西)

//
// ContentView.swift
// BrazilFlag
//
// Created by Min Hu on 2023/8/12.
//

import SwiftUI

struct DrawView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()

// 綠色長方形
var path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 393, y: 0))
path.addLine(to: CGPoint(x: 393, y: 275))
path.addLine(to: CGPoint(x: 0, y: 275))
path.close()
let rectLayer = CAShapeLayer()
rectLayer.fillColor = CGColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
rectLayer.path = path.cgPath
view.layer.addSublayer(rectLayer)
// 黃色菱形
path = UIBezierPath()
path.move(to: CGPoint(x: 33, y: 138))
path.addLine(to: CGPoint(x: 197, y: 33))
path.addLine(to: CGPoint(x: 360, y: 138))
path.addLine(to: CGPoint(x: 197, y: 243))
path.close()
let diamondLayer = CAShapeLayer()
diamondLayer.fillColor = CGColor(red: 249/255, green: 224/255, blue: 75/255, alpha: 1)
diamondLayer.path = path.cgPath
view.layer.addSublayer(diamondLayer)
// 天球儀
path = UIBezierPath(ovalIn: CGRect(x: 127, y: 68, width: 139, height: 139))
let celestialGlobeLayer = CAShapeLayer()
celestialGlobeLayer.fillColor = CGColor(red: 12/255, green: 38/255, blue: 113/255, alpha: 1)
celestialGlobeLayer.path = path.cgPath
view.layer.addSublayer(celestialGlobeLayer)
//白色星星1
path = UIBezierPath()
path.move(to: CGPoint(x: 140.5366010542469, y: 121.8738615169675))
path.addLine(to: CGPoint(x: 141.115501239807,y: 123.9490956543948))
path.addLine(to: CGPoint(x: 143.2971576406922,y: 124.2683624447684))
path.addLine(to: CGPoint(x: 141.5944014253672,y: 125.6518518697199))
path.addLine(to: CGPoint(x: 142.232935006114,y: 127.7802971388761))
path.addLine(to: CGPoint(x: 140.2109120004157,y: 127.0353412946715))
path.addLine(to: CGPoint(x: 138.0824667312595,y: 127.6738748754183))
path.addLine(to: CGPoint(x: 139.0906259941078,y: 125.6952843556943))
path.addLine(to: CGPoint(x: 137.614567117206,y: 124.2652352916095))
path.addLine(to: CGPoint(x: 139.4746652453757,y: 123.8272058531586))
path.close()
let whiteStar1Layer = CAShapeLayer()
whiteStar1Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar1Layer.path = path.cgPath
view.layer.addSublayer(whiteStar1Layer)
// 白色星星2
path.move(to: CGPoint(x: 137.860576930023, y: 157.676560021899))
path.addLine(to: CGPoint(x: 138.983198215442, y: 159.0345719559403))
path.addLine(to: CGPoint(x: 140.8260502667171, y: 159.4598455062345))
path.addLine(to: CGPoint(x: 139.9046242410796, y: 160.5230293819701))
path.addLine(to: CGPoint(x: 139.6919874659324, y: 162.5785182083922))
path.addLine(to: CGPoint(x: 138, y: 161.4))
path.addLine(to: CGPoint(x: 136.2897990635785, y: 162.7202760584903))
path.addLine(to: CGPoint(x: 136.5024358387256, y: 160.5939083070192))
path.addLine(to: CGPoint(x: 135.4392519629901, y: 159.1763298060384))
path.addLine(to: CGPoint(x: 137.211225089216, y: 158.9636930308912))
path.close()
let whiteStar2Layer = CAShapeLayer()
whiteStar2Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar2Layer.path = path.cgPath
view.layer.addSublayer(whiteStar2Layer)
//白色星星3
path.move(to: CGPoint(x: 146.3191669580177, y: 151.060692887923))
path.addLine(to: CGPoint(x: 147.1697140586062, y: 152.5491503139528))
path.addLine(to: CGPoint(x: 149.3024001976509, y: 153.3996974145413))
path.addLine(to: CGPoint(x: 147.5949876089004, y: 154.3565629027033))
path.addLine(to: CGPoint(x: 148.3392163219153, y: 156.6955674293216))
path.addLine(to: CGPoint(x: 146.6381221207384, y: 155.8450203287331))
path.addLine(to: CGPoint(x: 144.6180727568408, y: 156.5892490417481))
path.addLine(to: CGPoint(x: 144.8559830822821, y: 154.675518065424))
path.addLine(to: CGPoint(x: 143.5548888811052, y: 152.9744238642471))
path.addLine(to: CGPoint(x: 145.3623014698557, y: 152.8681054766735))
path.close()
let whiteStar3Layer = CAShapeLayer()
whiteStar3Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar3Layer.path = path.cgPath
view.layer.addSublayer(whiteStar3Layer)
//白色星星4
path.move(to: CGPoint(x: 153.2, y: 147.9))
path.addLine(to: CGPoint(x: 153.8441461673907, y: 148.8372784249961))
path.addLine(to: CGPoint(x: 154.8364511180773, y: 149.457057208689))
path.addLine(to: CGPoint(x: 153.9859040174888, y: 150.0240886090813))
path.addLine(to: CGPoint(x: 154.269419717685, y: 151.2526566432647))
path.addLine(to: CGPoint(x: 153.0408516835016, y: 150.7328778595717))
path.addLine(to: CGPoint(x: 151.8540414994164, y: 151.2108987931666))
path.addLine(to: CGPoint(x: 152.4793150497106, y: 150.0130990758788))
path.addLine(to: CGPoint(x: 151.4122836493183, y: 148.695520574898))
path.addLine(to: CGPoint(x: 151.4122836493183, y: 148.695520574898))
path.addLine(to: CGPoint(x: 152.7573359833055, y: 148.7482679581986))
path.close()
let whiteStar4Layer = CAShapeLayer()
whiteStar4Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar4Layer.path = path.cgPath
view.layer.addSublayer(whiteStar4Layer)
//白色星星5
path.move(to: CGPoint(x: 170.3825620121666, y: 137.3367610253038))
path.addLine(to: CGPoint(x: 171.020472337608, y: 138.7543395262846))
path.addLine(to: CGPoint(x: 173.1468400890792, y: 139.463128776775))
path.addLine(to: CGPoint(x: 171.8710194381964, y: 140.2427969523144))
path.addLine(to: CGPoint(x: 172.0836562133436, y: 142.5818014789327))
path.addLine(to: CGPoint(x: 170.5243198622647, y: 141.8021333033933))
path.addLine(to: CGPoint(x: 168.3270731857445, y: 142.7235593290308))
path.addLine(to: CGPoint(x: 169.1776202863329, y: 140.5263126525106))
path.addLine(to: CGPoint(x: 167.405647160107, y: 139.1796130765788))
path.addLine(to: CGPoint(x: 169.6737727616762, y: 138.8252184513336))
let whiteStar5Layer = CAShapeLayer()
whiteStar5Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar5Layer.path = path.cgPath
view.layer.addSublayer(whiteStar5Layer)
//白色星星6
path.move(to: CGPoint(x: 160.3531941177276, y: 158.1042860646723))
path.addLine(to: CGPoint(x: 161.4518174559877, y: 159.7345013408002))
path.addLine(to: CGPoint(x: 163.2946695072627, y: 160.2306538161434))
path.addLine(to: CGPoint(x: 162.01884885638, y: 161.22295876683))
path.addLine(to: CGPoint(x: 162.7276381068704, y: 162.924052968007))
path.addLine(to: CGPoint(x: 161.0265439056934, y: 162.1443847924675))
path.addLine(to: CGPoint(x: 159.1128129293694, y: 162.8531740429579))
path.addLine(to: CGPoint(x: 159.6089654047127, y: 161.22295876683))
path.addLine(to: CGPoint(x: 158.1205079786828, y: 160.2306538161434))
path.addLine(to: CGPoint(x: 159.7507232548107, y: 159.7345013408002))
path.close()
let whiteStar6Layer = CAShapeLayer()
whiteStar6Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar6Layer.path = path.cgPath
view.layer.addSublayer(whiteStar6Layer)
//白色星星7
path.move(to: CGPoint(x: 158.8, y: 165.6))
path.addLine(to: CGPoint(x: 159.1836918544185, y: 166.9027856596836))
path.addLine(to: CGPoint(x: 160.9556649806445, y: 166.9006959851249))
path.addLine(to: CGPoint(x: 159.8924811049089, y: 168.0494852356153))
path.addLine(to: CGPoint(x: 160.034238955007, y: 169.8214583618413))
path.addLine(to: CGPoint(x: 158.7584183041243, y: 168.8291534111548))
path.addLine(to: CGPoint(x: 157.3408398031435, y: 169.9632162119394))
path.addLine(to: CGPoint(x: 157.4825976532416, y: 168.3330009358115))
path.addLine(to: CGPoint(x: 156.419413777506, y: 166.7736645847326))
path.addLine(to: CGPoint(x: 157.9787501285848, y: 166.9154224348307))
path.close()
let whiteStar7Layer = CAShapeLayer()
whiteStar7Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar7Layer.path = path.cgPath
view.layer.addSublayer(whiteStar7Layer)
//白色星星8
path.move(to: CGPoint(x: 168.894104586137, y: 170.955521162626))
path.addLine(to: CGPoint(x: 169.8155306117745, y: 172.8148575137048))
path.addLine(to: CGPoint(x: 172.0836562133437, y: 172.8236467641952))
path.addLine(to: CGPoint(x: 170.5951987873139, y: 174.2159517148818))
path.addLine(to: CGPoint(x: 170.9495934125591, y: 176.6258351665491))
path.addLine(to: CGPoint(x: 169.1067413612841, y: 175.4208934407155))
path.addLine(to: CGPoint(x: 167.122131459911, y: 176.6258351665491))
path.addLine(to: CGPoint(x: 167.3347682350581, y: 174.570346340127))
path.addLine(to: CGPoint(x: 165.9171897340773, y: 172.7274942888519))
path.addLine(to: CGPoint(x: 167.9017996354504, y: 172.798373213901))
path.close()
let whiteStar8Layer = CAShapeLayer()
whiteStar8Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar8Layer.path = path.cgPath
view.layer.addSublayer(whiteStar8Layer)
//白色星星9
path.move(to: CGPoint(x: 196.4191928811959, y: 190.2316002869065))
path.addLine(to: CGPoint(x: 197.183598161304, y: 190.7727667703387))
path.addLine(to: CGPoint(x: 197.8047326011885, y: 191.2868563969284))
path.addLine(to: CGPoint(x: 196.945007123963, y: 191.5710832849053))
path.addLine(to: CGPoint(x: 197.4643833303227, y: 192.3252002033623))
path.addLine(to: CGPoint(x: 196.2695085347144, y: 191.8167191355412))
path.addLine(to: CGPoint(x: 195.6419237933469, y: 192.2855815177759))
path.addLine(to: CGPoint(x: 196.0777293347977, y: 191.5724451772202))
path.addLine(to: CGPoint(x: 195.0080248239641, y: 191.3347330637016))
path.addLine(to: CGPoint(x: 195.9588732780384, y: 190.7800714654916))
path.close()
let whiteStar9Layer = CAShapeLayer()
whiteStar9Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar9Layer.path = path.cgPath
view.layer.addSublayer(whiteStar9Layer)
//白色星星10
path.move(to: CGPoint(x: 196.5226791050458, y: 165.0881170744895))
path.addLine(to: CGPoint(x: 197.5314181386408, y: 166.9275823710451))
path.addLine(to: CGPoint(x: 199.6675713862538, y: 167.3429455025254))
path.addLine(to: CGPoint(x: 198.1247940407555, y: 169.182410799081))
path.addLine(to: CGPoint(x: 198.5994947624473, y: 171.199888866271))
path.addLine(to: CGPoint(x: 196.7006918756802, y: 169.8944618816186))
path.addLine(to: CGPoint(x: 194.6238762182787, y: 171.081213685848))
path.addLine(to: CGPoint(x: 195.0985769399705, y: 169.1230732088695))
path.addLine(to: CGPoint(x: 193.7338123651066, y: 167.2242703221024))
path.addLine(to: CGPoint(x: 195.8106280225081, y: 166.8495696004107))
path.close()
let whiteStar10Layer = CAShapeLayer()
whiteStar10Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar10Layer.path = path.cgPath
view.layer.addSublayer(whiteStar10Layer)
//白色星星11
path.move(to: CGPoint(x: 192.9455273437503, y: 157.9242773437476))
path.addLine(to: CGPoint(x: 193.4255273437503, y: 158.9142773437476))
path.addLine(to: CGPoint(x: 194.6255273437503, y: 159.0342773437476))
path.addLine(to: CGPoint(x: 194, y: 160))
path.addLine(to: CGPoint(x: 194.2955273437503, y: 161.1042773437476))
path.addLine(to: CGPoint(x: 193.1255273437503, y: 160.6242773437476))
path.addLine(to: CGPoint(x: 191.8055273437503, y: 161.0742773437476))
path.addLine(to: CGPoint(x: 192.3755273437503, y: 160.0242773437476))
path.addLine(to: CGPoint(x: 191.0255273437503, y: 159.2142773437476))
path.addLine(to: CGPoint(x: 192.4355273437503, y: 158.9142773437476))
path.close()
let whiteStar11Layer = CAShapeLayer()
whiteStar11Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar11Layer.path = path.cgPath
view.layer.addSublayer(whiteStar11Layer)
//白色星星12
path.move(to: CGPoint(x: 189.5523193641036, y: 152.6298346429213))
path.addLine(to: CGPoint(x: 190.2007934006097, y: 153.7106247037647))
path.addLine(to: CGPoint(x: 191.8219784918747, y: 153.9808222189755))
path.addLine(to: CGPoint(x: 190.9573464432, y: 155.0616122798189))
path.addLine(to: CGPoint(x: 191.3896624675374, y: 156.8989553832526))
path.addLine(to: CGPoint(x: 189.660398370188, y: 155.9262443284936))
path.addLine(to: CGPoint(x: 188.3094107941338, y: 156.8989553832526))
path.addLine(to: CGPoint(x: 188.3094107941338, y: 156.8989553832526))
path.addLine(to: CGPoint(x: 188.5255688063024, y: 155.2777702919875))
path.addLine(to: CGPoint(x: 187.0665022241639, y: 154.142940728102))
path.addLine(to: CGPoint(x: 188.7417268184711, y: 153.7106247037647))
path.close()
let whiteStar12Layer = CAShapeLayer()
whiteStar12Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar12Layer.path = path.cgPath
view.layer.addSublayer(whiteStar12Layer)
//白色星星13
path.move(to: CGPoint(x: 196.3991782382904, y: 145.1127782535239))
path.addLine(to: CGPoint(x: 197.3540547145948, y: 146.9638581193164))
path.addLine(to: CGPoint(x: 199.2890175654596, y: 147.0684507058496))
path.addLine(to: CGPoint(x: 198.138499113594, y: 148.8988209701811))
path.addLine(to: CGPoint(x: 198.4522768731937, y: 150.7814875277792))
path.addLine(to: CGPoint(x: 196.5696103155956, y: 149.9447468355134))
path.addLine(to: CGPoint(x: 194.6346474647308, y: 150.8337838210458))
path.addLine(to: CGPoint(x: 195.0007215175971, y: 148.9511172634477))
path.addLine(to: CGPoint(x: 193.7456104791984, y: 147.0684507058496))
path.addLine(to: CGPoint(x: 195.6282770367965, y: 146.9638581193164))
path.close()
let whiteStar13Layer = CAShapeLayer()
whiteStar13Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar13Layer.path = path.cgPath
view.layer.addSublayer(whiteStar13Layer)
//白色星星14
path.move(to: CGPoint(x: 204.6232394786543, y: 151.4613393402456))
path.addLine(to: CGPoint(x: 205.6691653439866, y: 153.1871170180439))
path.addLine(to: CGPoint(x: 207.656424488118, y: 153.3963021911104))
path.addLine(to: CGPoint(x: 205.9829431035863, y: 155.1743761621752))
path.addLine(to: CGPoint(x: 206.5059060362524, y: 157.10933901304))
path.addLine(to: CGPoint(x: 204.5709431853877, y: 156.0634131477077))
path.addLine(to: CGPoint(x: 202.7405729210562, y: 157.0570427197733))
path.addLine(to: CGPoint(x: 203.1066469739225, y: 155.1220798689086))
path.addLine(to: CGPoint(x: 201.4854618826574, y: 153.6577836574434))
path.addLine(to: CGPoint(x: 203.5250173200554, y: 153.1871170180439))
path.close()
let whiteStar14Layer = CAShapeLayer()
whiteStar14Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar14Layer.path = path.cgPath
view.layer.addSublayer(whiteStar14Layer)
//白色星星15
path.move(to: CGPoint(x: 215.2463612126745, y: 131.4744454986735))
path.addLine(to: CGPoint(x: 216.0461832602593, y: 132.7105341176683))
path.addLine(to: CGPoint(x: 218.0093828316041, y: 132.9286674033732))
path.addLine(to: CGPoint(x: 216.5551609269043, y: 134.382889308073))
path.addLine(to: CGPoint(x: 216.9914274983142, y: 136.2006666889477))
path.addLine(to: CGPoint(x: 215.4280499745544, y: 135.2916890223028))
path.addLine(to: CGPoint(x: 213.5012949270347, y: 135.9098223080078))
path.addLine(to: CGPoint(x: 214.4011169746196, y: 134.328311498543))
path.addLine(to: CGPoint(x: 212.9196061651548, y: 133.0013784986082))
path.addLine(to: CGPoint(x: 214.5192502603246, y: 132.7105341176683))
path.close()
let whiteStar15Layer = CAShapeLayer()
whiteStar15Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar15Layer.path = path.cgPath
view.layer.addSublayer(whiteStar15Layer)
//白色星星16
path.move(to: CGPoint(x: 218.0820939268391, y: 112.5695607375765))
path.addLine(to: CGPoint(x: 219.2454714505989, y: 114.6781824993911))
path.addLine(to: CGPoint(x: 221.2905377362386, y: 115.0417379755661))
path.addLine(to: CGPoint(x: 219.8271602124788, y: 116.4232487850309))
path.addLine(to: CGPoint(x: 220.2634267838888, y: 118.5318705468455))
path.addLine(to: CGPoint(x: 218.154805022074, y: 117.6593374040257))
path.addLine(to: CGPoint(x: 216.2643165459643, y: 118.2410261659056))
path.addLine(to: CGPoint(x: 216.4097387364343, y: 116.4959598802658))
path.addLine(to: CGPoint(x: 215, y: 115))
path.addLine(to: CGPoint(x: 216.9914274983142, y: 114.6054714041561))
path.close()
let whiteStar16Layer = CAShapeLayer()
whiteStar16Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar16Layer.path = path.cgPath
view.layer.addSublayer(whiteStar16Layer)
//白色星星17
path.move(to: CGPoint(x: 211.5645357539572, y: 173.3609939287015))
path.addLine(to: CGPoint(x: 212.4337380816785, y: 175.2842187177555))
path.addLine(to: CGPoint(x: 213.996528776881, y: 175.4530817658898))
path.addLine(to: CGPoint(x: 212.8213349800794, y: 176.5095417124248))
path.addLine(to: CGPoint(x: 213.2651334292798, y: 178.2161308568277))
path.addLine(to: CGPoint(x: 211.8023427340773, y: 177.5660016589599))
path.addLine(to: CGPoint(x: 210.2582858891414, y: 178.2973970065611))
path.addLine(to: CGPoint(x: 210.6646166378088, y: 176.6720740118918))
path.addLine(to: CGPoint(x: 209.2268905415402, y: 175.6781463648237))
path.addLine(to: CGPoint(x: 210.9458827875422, y: 175.1467510172224))
path.close()
let whiteStar17Layer = CAShapeLayer()
whiteStar17Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar17Layer.path = path.cgPath
view.layer.addSublayer(whiteStar17Layer)
//白色星星18
path.move(to: CGPoint(x: 217.1106024868065, y: 181.0330752067905))
path.addLine(to: CGPoint(x: 217.9413231285264, y: 182.6945164902303))
path.addLine(to: CGPoint(x: 220.0723021659818, y: 182.9834628003937))
path.addLine(to: CGPoint(x: 218.5553340376237, y: 184.4281943512109))
path.addLine(to: CGPoint(x: 218.7359254814759, y: 186.197990500962))
path.addLine(to: CGPoint(x: 217.1106024868065, y: 185.3311515704717))
path.addLine(to: CGPoint(x: 215.051860026892, y: 185.8729259020281))
path.addLine(to: CGPoint(x: 215.9909355349232, y: 184.35595777367))
path.addLine(to: CGPoint(x: 214.1489028076312, y: 182.7667530677711))
path.addLine(to: CGPoint(x: 216.3521184226275, y: 182.7306347790007))
path.close()
let whiteStar18Layer = CAShapeLayer()
whiteStar18Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar18Layer.path = path.cgPath
view.layer.addSublayer(whiteStar18Layer)
//白色星星19
path.move(to: CGPoint(x: 222.9562523498691, y: 175.427913645881))
path.addLine(to: CGPoint(x: 223.6412436993678, y: 177.0361816498008))
path.addLine(to: CGPoint(x: 225.4495117032876, y: 177.2439914465192))
path.addLine(to: CGPoint(x: 224.279834475758, y: 178.198201816346))
path.addLine(to: CGPoint(x: 224.6184252521481, y: 179.6449078609222))
path.addLine(to: CGPoint(x: 223.2640621465874, y: 178.8753833691264))
path.addLine(to: CGPoint(x: 221.5711082646366, y: 179.8603747186251))
path.addLine(to: CGPoint(x: 222.1867278580732, y: 178.3521067147052))
path.addLine(to: CGPoint(x: 220.8939267118562, y: 177.459458304222))
path.addLine(to: CGPoint(x: 222.6098517767606, y: 177.0593055684882))
path.close()
let whiteStar19Layer = CAShapeLayer()
whiteStar19Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar19Layer.path = path.cgPath
view.layer.addSublayer(whiteStar19Layer)
//白色星星20
path.move(to: CGPoint(x: 230.5415681254492, y: 172.836080828443))
path.addLine(to: CGPoint(x: 231.4712280406089, y: 174.2969749808366))
path.addLine(to: CGPoint(x: 233.1092002720806, y: 174.2969749808366))
path.addLine(to: CGPoint(x: 231.9581927580734, y: 175.5365215343828))
path.addLine(to: CGPoint(x: 232.3123489162295, y: 177.130224246085))
path.addLine(to: CGPoint(x: 230.7629157242968, y: 176.4219119297729))
path.addLine(to: CGPoint(x: 229.1249434928251, y: 177.2630328053935))
path.addLine(to: CGPoint(x: 229.5676386905201, y: 175.6693300936913))
path.addLine(to: CGPoint(x: 228.239553097435, y: 174.4297835401452))
path.addLine(to: CGPoint(x: 230.0103338882152, y: 174.2969749808366))
path.close()
let whiteStar20Layer = CAShapeLayer()
whiteStar20Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar20Layer.path = path.cgPath
view.layer.addSublayer(whiteStar20Layer)
//白色星星21
path.move(to: CGPoint(x: 230.8957242836052, y: 179.5207783136382))
path.addLine(to: CGPoint(x: 232.0238098766904, y: 181.3259419858014))
path.addLine(to: CGPoint(x: 234.0388601872401, y: 181.0702115055709))
path.addLine(to: CGPoint(x: 232.4008879557684, y: 182.7967227765816))
path.addLine(to: CGPoint(x: 232.9763917127719, y: 184.6560426069008))
path.addLine(to: CGPoint(x: 231.0728023626832, y: 183.9034607708192))
path.addLine(to: CGPoint(x: 229.1692130125945, y: 184.6560426069008))
path.addLine(to: CGPoint(x: 229.7889862893676, y: 182.7524532568121))
path.addLine(to: CGPoint(x: 228.3723616567434, y: 181.1587505451099))
path.addLine(to: CGPoint(x: 230.3431424475236, y: 181.2702115055709))
path.close()
let whiteStar21Layer = CAShapeLayer()
whiteStar21Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar21Layer.path = path.cgPath
view.layer.addSublayer(whiteStar21Layer)
//白色星星22
path.move(to: CGPoint(x: 230.9399938033747, y: 186.8252490756066))
path.addLine(to: CGPoint(x: 231.5154975603783, y: 188.0647956291527))
path.addLine(to: CGPoint(x: 233.0206612325415, y: 188.2418737082307))
path.addLine(to: CGPoint(x: 231.8696537185343, y: 189.2158031431599))
path.addLine(to: CGPoint(x: 232.1352708371514, y: 190.632427775784))
path.addLine(to: CGPoint(x: 230.7186462045272, y: 190.012654499011))
path.addLine(to: CGPoint(x: 229.213482532364, y: 190.720966815323))
path.addLine(to: CGPoint(x: 229.6119082102896, y: 189.2600726629294))
path.addLine(to: CGPoint(x: 228.3280921369739, y: 188.1976041884612))
path.addLine(to: CGPoint(x: 230.3644900463712, y: 188.1090651489222))
path.close()
let whiteStar22Layer = CAShapeLayer()
whiteStar22Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar22Layer.path = path.cgPath
view.layer.addSublayer(whiteStar22Layer)
//白色星星23
path.move(to: CGPoint(x: 237.62469128857, y: 174.8724787378401))
path.addLine(to: CGPoint(x: 238.3330036048821, y: 175.9349472123083))
path.addLine(to: CGPoint(x: 240, y: 176))
path.addLine(to: CGPoint(x: 238.9527768816552, y: 177.2187632856239))
path.addLine(to: CGPoint(x: 239.3954720793502, y: 178.5911183984786))
path.addLine(to: CGPoint(x: 237.9, y: 178))
path.addLine(to: CGPoint(x: 236.1637971361764, y: 178.8124659973261))
path.addLine(to: CGPoint(x: 236.6950313734104, y: 177.3073023251629))
path.addLine(to: CGPoint(x: 235.4997543396338, y: 176.0677557716168))
path.addLine(to: CGPoint(x: 237.004918011797, y: 175.9349472123083))
path.close()
let whiteStar23Layer = CAShapeLayer()
whiteStar23Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar23Layer.path = path.cgPath
view.layer.addSublayer(whiteStar23Layer)
//白色星星24
path.move(to: CGPoint(x: 243.3797288586057, y: 170.7554133992761))
path.addLine(to: CGPoint(x: 244, y: 172))
path.addLine(to: CGPoint(x: 246.0359000447761, y: 172.4376551505173))
path.addLine(to: CGPoint(x: 244.7520839714604, y: 173.5001236249855))
path.addLine(to: CGPoint(x: 244.9734315703079, y: 175.2709044157657))
path.addLine(to: CGPoint(x: 243.5568069376838, y: 174.7839396983011))
path.addLine(to: CGPoint(x: 242.0516432655206, y: 175.3594434553047))
path.addLine(to: CGPoint(x: 242.1844518248291, y: 173.632932184294))
path.addLine(to: CGPoint(x: 241.033444310822, y: 172.3933856307478))
path.addLine(to: CGPoint(x: 242.7156860620632, y: 172.0834989923613))
path.close()
let whiteStar24Layer = CAShapeLayer()
whiteStar24Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar24Layer.path = path.cgPath
view.layer.addSublayer(whiteStar24Layer)
//白色星星25
path.move(to: CGPoint(x: 247.4967941971698, y: 165.398801507166))
path.addLine(to: CGPoint(x: 248.6035321914074, y: 166.6383480607121))
path.addLine(to: CGPoint(x: 249.9316177844925, y: 166.7711566200206))
path.addLine(to: CGPoint(x: 248.7363407507159, y: 168.0992422131058))
path.addLine(to: CGPoint(x: 249.179035948411, y: 169.604405885269))
path.addLine(to: CGPoint(x: 247.6296027564783, y: 168.7632850096484))
path.addLine(to: CGPoint(x: 246.1687086040846, y: 169.6486754050385))
path.addLine(to: CGPoint(x: 246.5228647622406, y: 168.1435117328753))
path.addLine(to: CGPoint(x: 245.416126768003, y: 166.9039651793291))
path.addLine(to: CGPoint(x: 247.0098294797052, y: 166.5940785409426))
path.close()
let whiteStar25Layer = CAShapeLayer()
whiteStar25Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar25Layer.path = path.cgPath
view.layer.addSublayer(whiteStar25Layer)
//白色星星26
path.move(to: CGPoint(x: 244.6051896558614, y: 158.4082418853808))
path.addLine(to: CGPoint(x: 245.7823564315506, y: 160.3098189845709))
path.addLine(to: CGPoint(x: 248, y: 160))
path.addLine(to: CGPoint(x: 246.2351128837387, y: 162.2566717289798))
path.addLine(to: CGPoint(x: 246.6878693359268, y: 163.7507680212006))
path.addLine(to: CGPoint(x: 244.8315678819555, y: 162.8452551168244))
path.addLine(to: CGPoint(x: 243.1110933636406, y: 163.7507680212006))
path.addLine(to: CGPoint(x: 243.5638498158288, y: 162.3472230194174))
path.addLine(to: CGPoint(x: 242.0697535236079, y: 160.3550946297897))
path.addLine(to: CGPoint(x: 244.0166062680169, y: 160.3098189845709))
path.close()
let whiteStar26Layer = CAShapeLayer()
whiteStar26Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar26Layer.path = path.cgPath
view.layer.addSublayer(whiteStar26Layer)
//白色星星27
path.move(to: CGPoint(x: 254.5205559587813, y: 160.4456459202273))
path.addLine(to: CGPoint(x: 255.3807932179388, y: 161.5417101150412))
path.addLine(to: CGPoint(x: 256.6674087031903, y: 161.6228126959164))
path.addLine(to: CGPoint(x: 255.6977227344705, y: 162.6188768907303))
path.addLine(to: CGPoint(x: 255.7429983796893, y: 164.0224218925135))
path.addLine(to: CGPoint(x: 254.611107249219, y: 163.3432872142313))
path.addLine(to: CGPoint(x: 253.4339404735298, y: 163.9318706020759))
path.addLine(to: CGPoint(x: 253.6150430544051, y: 162.7094281811679))
path.addLine(to: CGPoint(x: 252.3473249882784, y: 161.8491909220105))
path.addLine(to: CGPoint(x: 253.8414212804992, y: 161.5058831793847))
path.close()
let whiteStar27Layer = CAShapeLayer()
whiteStar27Layer.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteStar27Layer.path = path.cgPath
view.layer.addSublayer(whiteStar27Layer)
//白腰帶
// aDegree 是弧度
let aDegree = CGFloat.pi/180
//白腰帶上邊,0度在右側,90度在正下方
path = UIBezierPath(arcCenter: CGPoint(x: 157.7921701008629, y: 272.2092676661875), radius: 164.538, startAngle: aDegree * 261, endAngle: aDegree * 311, clockwise: true)
//白腰帶右邊
path.addArc(withCenter: CGPoint(x: 196.5, y: 137.5), radius: 69.5, startAngle: aDegree * 7.18, endAngle: aDegree * 16.58, clockwise: true)
//白腰帶下邊
path.addArc(withCenter: CGPoint(x: 155.9, y: 281.8), radius: 164.538, startAngle: aDegree * 311, endAngle: aDegree * 260.6, clockwise: false)
//白腰帶左邊
path.addArc(withCenter: CGPoint(x: 196.5, y: 137.5), radius: 69.5, startAngle: aDegree * 194.744, endAngle: aDegree * 204.47, clockwise: true)
//白腰帶的顏色與顯示
let whiteBelt = CAShapeLayer()
whiteBelt.fillColor = CGColor(red: 1, green: 1, blue: 1, alpha: 1)
whiteBelt.path = path.cgPath
view.layer.addSublayer(whiteBelt)
//文字 ORDEM E PROGRESSO 中 ORDEM 的 O
let text1 = UILabel(frame: CGRect(x: 137.7383148809027, y: 108.3, width: 10, height: 10))
text1.text = "O"
text1.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text1.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text1)
text1.transform = CGAffineTransform(rotationAngle: .pi/180 * 0)
//文字 ORDEM E PROGRESSO 中 ORDEM 的 R
let text2 = UILabel(frame: CGRect(x: 146, y: 107.9387055424686, width: 10, height: 10))
text2.text = "R"
text2.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text2.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text2)
text2.transform = CGAffineTransform(rotationAngle: .pi/180 * 357)
//文字 ORDEM E PROGRESSO 中 ORDEM 的 D
let text3 = UILabel(frame: CGRect(x: 153.5, y: 107.8, width: 10, height: 10))
text3.text = "D"
text3.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text3.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text3)
text3.transform = CGAffineTransform(rotationAngle: .pi/180 * 0)
//文字 ORDEM E PROGRESSO 中 ORDEM 的 E
let text4 = UILabel(frame: CGRect(x: 162, y: 107.8387055424686, width: 10, height: 10))
text4.text = "E"
text4.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text4.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text4)
text4.transform = CGAffineTransform(rotationAngle: .pi/180 * 2)
//文字 ORDEM E PROGRESSO 中 ORDEM 的 M
let text5 = UILabel(frame: CGRect(x: 170.7200727961999, y: 108.6, width: 10, height: 10))
text5.text = "M"
text5.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text5.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text5)
text5.transform = CGAffineTransform(rotationAngle: .pi/180 * 8)
//文字 ORDEM E PROGRESSO 中 E 的 E
let text6 = UILabel(frame: CGRect(x: 185.5925365744933, y: 111, width: 10, height: 10))
text6.text = "E"
text6.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text6.font = UIFont(name: "Helvetica-Bold", size: 7)
view.addSubview(text6)
text6.transform = CGAffineTransform(rotationAngle: .pi/180 * 12)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的 P
let text7 = UILabel(frame: CGRect(x: 197, y: 114, width: 10, height: 10))
text7.text = "P"
text7.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text7.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text7)
text7.transform = CGAffineTransform(rotationAngle: .pi/180 * 15)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的 R
let text8 = UILabel(frame: CGRect(x: 204.5, y: 116.5, width: 10, height: 10))
text8.text = "R"
text8.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text8.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text8)
text8.transform = CGAffineTransform(rotationAngle: .pi/180 * 20)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的 O
let text9 = UILabel(frame: CGRect(x: 212, y: 119.5, width: 10, height: 10))
text9.text = "O"
text9.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text9.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text9)
text9.transform = CGAffineTransform(rotationAngle: .pi/180 * 23)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的 G
let text10 = UILabel(frame: CGRect(x: 220, y: 122.6, width: 10, height: 10))
text10.text = "G"
text10.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text10.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text10)
text10.transform = CGAffineTransform(rotationAngle: .pi/180 * 23)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的第二個 R
let text11 = UILabel(frame: CGRect(x: 227.4005593775355, y: 126.3, width: 10, height: 10))
text11.text = "R"
text11.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text11.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text11)
text11.transform = CGAffineTransform(rotationAngle: .pi/180 * 29)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的 E
let text12 = UILabel(frame: CGRect(x: 234.8, y: 130.2, width: 10, height: 10))
text12.text = "E"
text12.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text12.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text12)
text12.transform = CGAffineTransform(rotationAngle: .pi/180 * 29)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的 S
let text13 = UILabel(frame: CGRect(x: 241.7, y: 134.7, width: 10, height: 10))
text13.text = "S"
text13.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text13.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text13)
text13.transform = CGAffineTransform(rotationAngle: .pi/180 * 36)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的第二個 S
let text14 = UILabel(frame: CGRect(x: 248, y: 138.7, width: 10, height: 10))
text14.text = "S"
text14.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text14.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text14)
text14.transform = CGAffineTransform(rotationAngle: .pi/180 * 36)
//文字 ORDEM E PROGRESSO 中 PROGRESSO 的第二個 O
let text15 = UILabel(frame: CGRect(x: 253.8, y: 143, width: 10, height: 10))
text15.text = "O"
text15.textColor = UIColor(red: 68/255, green: 153/255, blue: 71/255, alpha: 1)
text15.font = UIFont(name: "Helvetica-Bold", size: 8)
view.addSubview(text15)
text15.transform = CGAffineTransform(rotationAngle: .pi/180 * 38)

return view
}

func updateUIView(_ uiView: UIView, context: Context) {
}

}


struct ContentView: View {
var body: some View {
DrawView()
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

Reference:

--

--