成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇學會使用 SwiftUI 創建萬花尺

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

[[412896]]

本文轉載自微信公眾號「Swift社區」,作者韋弦Zhy。轉載本文請聯系Swift社區公眾號。

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

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

我們的算法有四個輸入:

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

因此,讓我們開始吧:

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

然后,我們從數據中準備三個值,從內半徑和外半徑的最大公約數(GCD)開始。計算兩個數字的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 

把這個方法添加到Spirograph結構體中。

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

現在將這個path(in:)方法添加到Spirograph結構體:

  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 

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

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

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

以下是path(in:)方法的最后一個代碼——用以下內容替換// 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 

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

  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.     } 

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

在我結束之前,我想提醒你,這里使用的參數方程是數學標準,而不是我剛剛發明的東西——我真的去百度了關于 hypotrochoids[1] 的頁面,并將它們轉換為 Swift。

參考資料

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

 

責任編輯:武曉燕 來源: Swift社區
相關推薦

2021-12-28 07:20:43

Hippo WebAssembly云原生

2021-05-30 07:56:51

QSettingsLog4Qt變量

2022-01-02 08:43:46

Python

2022-01-12 07:36:01

Java數據ByteBuffer

2021-06-26 16:05:15

內核線程運行

2022-02-07 11:01:23

ZooKeeper

2021-07-02 09:45:29

MySQL InnoDB數據

2021-07-06 08:59:18

抽象工廠模式

2023-01-03 08:31:54

Spring讀取器配置

2023-11-28 08:29:31

Rust內存布局

2021-07-05 22:11:38

MySQL體系架構

2022-08-26 09:29:01

Kubernetes策略Master

2022-08-23 08:00:59

磁盤性能網絡

2021-05-11 08:54:59

建造者模式設計

2023-11-29 13:59:00

trait定義接口

2022-01-01 20:02:25

Metadata動態元數據

2021-10-15 09:55:48

Myloader數據教程

2021-09-28 08:59:30

復原IP地址

2021-10-14 10:22:19

逃逸JVM性能

2022-04-12 08:30:52

回調函數代碼調試
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 伊人久操| 日韩中文在线视频 | 福利一区二区在线 | 久久伦理电影 | 亚洲午夜av久久乱码 | 91麻豆精品国产91久久久久久久久 | 狠狠av| 国产精品久久久久久久久久久久 | 女同久久另类99精品国产 | 久久久久久网站 | 成人三级网址 | 国产一区高清 | 久久久久国 | 亚洲手机在线 | 久久精品一区二区视频 | 狠狠爱综合| 91精品久久久久久久久久 | 国产成人在线观看免费 | 91精品成人久久 | 黄色免费在线观看网站 | 精品一级毛片 | 99成人| 成人免费一区二区三区视频网站 | 日韩在线免费视频 | 久久久久久综合 | 中文字幕中文字幕 | 日产久久| 日韩免费一区 | 欧美精品欧美精品系列 | 男人av在线播放 | 91精品国产综合久久久久蜜臀 | 久久精品91久久久久久再现 | 美人の美乳で授乳プレイ | 极品粉嫩国产48尤物在线播放 | 日韩欧美三区 | 超碰免费在线观看 | 久久精品视频网站 | 日本黄色的视频 | 精品成人一区二区 | 国产一区二区欧美 | 天天拍天天插 |