自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇學(xué)會使用 SwiftUI 創(chuàng)建萬花尺

移動開發(fā) iOS
為了完成一些真正意義上的繪圖工作,我將帶您通過創(chuàng)建一個(gè)簡單的帶 SwiftUI 的 spirograph?!癝pirograph”是一種玩具的商標(biāo)名稱,你把一支鉛筆放在一個(gè)圓圈里,然后繞著另一個(gè)圓圈的圓周旋轉(zhuǎn),創(chuàng)造出各種幾何圖案,稱為輪盤賭——就像賭場游戲一樣。

[[412896]]

本文轉(zhuǎn)載自微信公眾號「Swift社區(qū)」,作者韋弦Zhy。轉(zhuǎn)載本文請聯(lián)系Swift社區(qū)公眾號。

為了完成一些真正意義上的繪圖工作,我將帶您通過創(chuàng)建一個(gè)簡單的帶 SwiftUI 的 spirograph。“Spirograph”是一種玩具的商標(biāo)名稱,你把一支鉛筆放在一個(gè)圓圈里,然后繞著另一個(gè)圓圈的圓周旋轉(zhuǎn),創(chuàng)造出各種幾何圖案,稱為輪盤賭——就像賭場游戲一樣。

這段代碼包含一個(gè)非常具體的公式。我會解釋的,但是如果你不感興趣的話,跳過這一章是完全可以的——這只是為了好玩,這里沒有介紹新的 Swift 或 SwiftUI。

我們的算法有四個(gè)輸入:

  • 內(nèi)圈的半徑。
  • 外圈的半徑。
  • 虛擬筆與外圓中心的距離。
  • 要畫多少輪盤賭。這是可選的,但我認(rèn)為它確實(shí)有助于顯示算法工作時(shí)發(fā)生的情況。

因此,讓我們開始吧:

  1. struct Spirograph: Shape { 
  2.     let innerRadius: Int 
  3.     let outerRadius: Int 
  4.     let distance: Int 
  5.     let amount: CGFloat 

然后,我們從數(shù)據(jù)中準(zhǔn)備三個(gè)值,從內(nèi)半徑和外半徑的最大公約數(shù)(GCD)開始。計(jì)算兩個(gè)數(shù)字的GCD通常是用Euclid算法完成的,它的形式稍微簡化如下:

  1. func gcd(_ a: Int,  _ b: Int) -> Int { 
  2.     var a = a 
  3.     var b = b 
  4.     while b != 0 { 
  5.         let temp = b 
  6.         b = a % b 
  7.         a = temp 
  8.     } 
  9.     return a 

把這個(gè)方法添加到Spirograph結(jié)構(gòu)體中。

另外兩個(gè)值是內(nèi)半徑和外半徑之間的差異,以及我們需要執(zhí)行多少步驟來繪制輪盤——這是360度乘以外半徑除以最大公約數(shù),再乘以我們的數(shù)量輸入。我們所有的輸入以整數(shù)形式提供時(shí)效果最好,但是在繪制輪盤賭時(shí),我們需要使用CGFloat,因此我們還將創(chuàng)建輸入的CGFloat副本。

現(xiàn)在將這個(gè)path(in:)方法添加到Spirograph結(jié)構(gòu)體:

  1. func path(in rect: CGRect) -> Path { 
  2.     let divisor = gcd(innerRadius, outerRadius) 
  3.     let outerRadius = CGFloat(self.outerRadius) 
  4.     let innerRadius = CGFloat(self.innerRadius) 
  5.     let distance = CGFloat(self.distance) 
  6.     let difference = innerRadius - outerRadius 
  7.     let endPoint = ceil(2 * CGFloat.pi * outerRadius / CGFloat(divisor)) * amount 
  8.  
  9.     // more code to come 

最后,我們可以通過循環(huán)從 0 到我們的終點(diǎn)來畫輪盤賭,并放置在精確的 X/Y 坐標(biāo)點(diǎn)。計(jì)算循環(huán)中給定點(diǎn)的 X/Y 坐標(biāo)(稱為“theta:θ”)是真正的數(shù)學(xué)來源,但老實(shí)說,我只是把維基百科上的標(biāo)準(zhǔn)方程式轉(zhuǎn)換成 Swift ——這不是我夢寐以求的記憶!

  • X等于半徑差乘以 θ 的余弦,再乘以半徑差的余弦除以外半徑乘以θ的距離。
  • Y等于半徑差乘以 θ 的正弦,減去距離乘以半徑差的正弦除以外半徑乘以 θ。

這是核心算法,但我們要做兩個(gè)小的改變:我們要分別將繪圖矩形的一半寬度或高度添加到X和Y,使其在繪圖空間中居中;如果 θ 為 0,即如果這是輪盤中繪制的第一個(gè)點(diǎn),我們將我們的路徑中調(diào)用move(to:)而不是addLine(to:)。

以下是path(in:)方法的最后一個(gè)代碼——用以下內(nèi)容替換// more code to come注釋:

  1. var path = Path() 
  2.  
  3. for theta in stride(from: 0, through: endPoint, by: 0.01) { 
  4.     var x = difference * cos(theta) + distance * cos(difference / outerRadius * theta) 
  5.     var y = difference * sin(theta) - distance * sin(difference / outerRadius * theta) 
  6.  
  7.     x += rect.width / 2 
  8.     y += rect.height / 2 
  9.  
  10.     if theta == 0 { 
  11.         path.move(to: CGPoint(x: x, y: y)) 
  12.     } else { 
  13.         path.addLine(to: CGPoint(x: x, y: y)) 
  14.     } 
  15.  
  16. return path 

我意識到這有很多繁重的數(shù)學(xué),但回報(bào)即將到來:我們現(xiàn)在可以在視圖中使用該形狀,添加各種滑塊來控制內(nèi)半徑、外半徑、距離、數(shù)量,甚至顏色:

  1. struct ContentView: View { 
  2.     @State private var innerRadius = 125.0 
  3.     @State private var outerRadius = 75.0 
  4.     @State private var distance = 25.0 
  5.     @State private var amount: CGFloat = 1.0 
  6.     @State private var hue = 0.6 
  7.  
  8.     var body: some View { 
  9.         VStack(spacing: 0) { 
  10.             Spacer() 
  11.  
  12.             Spirograph(innerRadius: Int(innerRadius), outerRadius: Int(outerRadius), distance: Int(distance), amount: amount) 
  13.                 .stroke(Color(hue: hue, saturation: 1, brightness: 1), lineWidth: 1) 
  14.                 .frame(width: 300, height: 300) 
  15.  
  16.             Spacer() 
  17.  
  18.             Group { 
  19.                 Text("Inner radius: \(Int(innerRadius))"
  20.                 Slider(value: $innerRadius, in: 10...150, step: 1) 
  21.                     .padding([.horizontal, .bottom]) 
  22.  
  23.                 Text("Outer radius: \(Int(outerRadius))"
  24.                 Slider(value: $outerRadius, in: 10...150, step: 1) 
  25.                     .padding([.horizontal, .bottom]) 
  26.  
  27.                 Text("Distance: \(Int(distance))"
  28.                 Slider(value: $distance, in: 1...150, step: 1) 
  29.                     .padding([.horizontal, .bottom]) 
  30.  
  31.                 Text("Amount: \(amount, specifier: "%.2f")"
  32.                 Slider(value: $amount) 
  33.                     .padding([.horizontal, .bottom]) 
  34.  
  35.                 Text("Color"
  36.                 Slider(value: $hue) 
  37.                     .padding(.horizontal) 
  38.             } 
  39.         } 
  40.     } 

這是很多代碼,但我希望你花時(shí)間運(yùn)行應(yīng)用程序,并欣賞有多么美麗的輪盤。你所看到的其實(shí)只是一種輪盤賭形式,被稱為 hypotrochoid ——通過對算法的小調(diào)整,你可以生成 epitrochoids 等,它們以不同的方式很漂亮。

在我結(jié)束之前,我想提醒你,這里使用的參數(shù)方程是數(shù)學(xué)標(biāo)準(zhǔn),而不是我剛剛發(fā)明的東西——我真的去百度了關(guān)于 hypotrochoids[1] 的頁面,并將它們轉(zhuǎn)換為 Swift。

參考資料

[1]hypotrochoids: http://www.durangobill.com/Trochoids.html

 

責(zé)任編輯:武曉燕 來源: Swift社區(qū)
相關(guān)推薦

2021-12-28 07:20:43

Hippo WebAssembly云原生

2021-05-30 07:56:51

QSettingsLog4Qt變量

2022-01-02 08:43:46

Python

2021-06-26 16:05:15

內(nèi)核線程運(yùn)行

2022-02-07 11:01:23

ZooKeeper

2022-01-12 07:36:01

Java數(shù)據(jù)ByteBuffer

2023-11-29 13:59:00

trait定義接口

2022-01-01 20:02:25

Metadata動態(tài)元數(shù)據(jù)

2023-01-03 08:31:54

Spring讀取器配置

2021-05-11 08:54:59

建造者模式設(shè)計(jì)

2021-07-05 22:11:38

MySQL體系架構(gòu)

2021-07-06 08:59:18

抽象工廠模式

2022-08-26 09:29:01

Kubernetes策略Master

2023-11-28 08:29:31

Rust內(nèi)存布局

2021-07-02 09:45:29

MySQL InnoDB數(shù)據(jù)

2022-08-23 08:00:59

磁盤性能網(wǎng)絡(luò)

2021-10-15 09:55:48

Myloader數(shù)據(jù)教程

2021-07-02 08:51:29

源碼參數(shù)Thread

2021-07-16 22:43:10

Go并發(fā)Golang

2021-09-28 08:59:30

復(fù)原IP地址
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號