Last active
March 14, 2026 16:27
-
-
Save johnhaney/a8ff84417d53847b9b2f284175b9e2ec to your computer and use it in GitHub Desktop.
Calculate PI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // ContentView.swift | |
| // CalculatePi | |
| // | |
| // Created by John Haney on 3/14/24. | |
| // | |
| import SwiftUI | |
| import Combine | |
| struct ContentView: View { | |
| @State var sticks: [(CGPoint, CGPoint)] = [] | |
| @State var timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect() | |
| var sticksCrossing: Int { | |
| sticks.filter({ | |
| let bottom: CGFloat = 40.0 * ceil($0.0.y / 40.0) | |
| let top: CGFloat = $0.1.y | |
| return bottom < top | |
| }).count | |
| } | |
| var estimation: CGFloat { | |
| let crossing = sticksCrossing | |
| guard crossing > 0 else { return 0 } | |
| return 2 * CGFloat(sticks.count) / CGFloat(crossing) | |
| } | |
| var body: some View { | |
| VStack { | |
| Text("Sticks: \(sticks.count)") | |
| Text("Sticks Crossing: \(sticksCrossing)") | |
| Text("Pi: \(estimation)") | |
| Canvas { context, size in | |
| do { | |
| var path = Path() | |
| path.addRects([ | |
| CGRect(x: 0, y: 0, width: size.width, height: size.height*0.1), | |
| CGRect(x: 0, y: size.height*0.2, width: size.width, height: size.height*0.1), | |
| CGRect(x: 0, y: size.height*0.4, width: size.width, height: size.height*0.1), | |
| CGRect(x: 0, y: size.height*0.6, width: size.width, height: size.height*0.1), | |
| CGRect(x: 0, y: size.height*0.8, width: size.width, height: size.height*0.1), | |
| ]) | |
| context.fill(path, with: .color(.gray)) | |
| } | |
| var path = Path() | |
| for (point, point2) in sticks { | |
| path.move(to: point) | |
| path.addLine(to: point2) | |
| } | |
| context.stroke(path, with: .color(.orange)) | |
| } | |
| .frame(width: 300, height: 400) | |
| Button("Drop") { | |
| dropStick() | |
| } | |
| } | |
| .monospacedDigit() | |
| .onReceive(timer, perform: { _ in | |
| dropStick() | |
| }) | |
| } | |
| func dropStick() { | |
| let x = CGFloat.random(in: 40...260) | |
| let y = CGFloat.random(in: 40...360) | |
| let angle = Angle(degrees: .random(in: 0...360)) | |
| let x2 = x + 40 * cos(angle.radians) | |
| let y2 = y + 40 * sin(angle.radians) | |
| let points = [ | |
| CGPoint(x: x, y: y), | |
| CGPoint(x: x2, y: y2) | |
| ].sorted(by: { $0.y < $1.y }) | |
| sticks.append((points[0], points[1])) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment