Skip to content

Instantly share code, notes, and snippets.

@carlynorama
Created July 1, 2022 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlynorama/f45aa233a693ec962b203a36c9d79539 to your computer and use it in GitHub Desktop.
Save carlynorama/f45aa233a693ec962b203a36c9d79539 to your computer and use it in GitHub Desktop.
potential extension to WeatherKit.Wind.CompassDirection testable as a playground
import Foundation
import SwiftUI
//TEST
print("----")
print("North")
print(Compass(degrees: 0).rawValue)
print(Compass(degrees: 5).rawValue)
print(Compass(degrees: 360-5).rawValue)
print("----")
print("East")
print(Compass(degrees: 90).rawValue)
print(Compass(degrees: 90+12).rawValue)
print(Compass(degrees: 90-12).rawValue)
print("----")
print("South")
print(Compass(degrees: 180).rawValue)
print(Compass(degrees: 180+10).rawValue)
print(Compass(degrees: 180-10).rawValue)
print("----")
print("West")
print(Compass(degrees: 270).rawValue)
print("----")
print("LARGE")
print(Compass(degrees: 6723).rawValue)
print(Compass(degrees: 450).rawValue)
print("----")
print("Small")
print(Compass(degrees: -90).rawValue)
print(Compass(degrees: -90+5).rawValue)
print(Compass(degrees: -90-5).rawValue)
print(Compass(degrees: 0.000005).rawValue)
print(Compass(degrees: -6723).rawValue)
print(Compass(degrees: -450).rawValue)
print("----")
enum Compass:String, CaseIterable {
case north
case northNortheast
case northeast
case eastNortheast
case east
case eastSoutheast
case southeast
case southSoutheast
case south
case southSouthwest
case southwest
case westSouthwest
case west
case westNorthwest
case northwest
case northNorthwest
}
extension Compass {
static let degreesCircle = 360.0
static let numberOfWedges = 16
static let wedgeSize = Measurement<UnitAngle>(value: degreesCircle/Double(numberOfWedges), unit: .degrees)
static let halfWedgeSize = wedgeSize/2.0
static let wedgeOffSet = -1 * halfWedgeSize
static func wedgeNumberFor(angle:Measurement<UnitAngle>) -> Int {
var compassAngle = angle.converted(to: .degrees)
if compassAngle.value.magnitude > degreesCircle {
print("Caught a large magnitude value")
compassAngle.value = compassAngle.value.truncatingRemainder(dividingBy: degreesCircle)
print("newRadiansValue: \(compassAngle)")
}
var wedgeShiftedAngle = compassAngle + wedgeOffSet
print("adjusted degrees: \(wedgeShiftedAngle)")
if wedgeShiftedAngle.value < 0 {
print("Caught a negative value")
wedgeShiftedAngle.value = wedgeShiftedAngle.value + degreesCircle
print("newDegreesValue: \(wedgeShiftedAngle)")
}
let wedgeNumberRaw:Double = (wedgeShiftedAngle.value/wedgeSize.value)
print("raw \(wedgeNumberRaw)")
var wedgeNumberToReturn = Int(wedgeNumberRaw.rounded(.awayFromZero))
print("as Int \(wedgeNumberToReturn)")
if wedgeNumberToReturn == Int(numberOfWedges) {
wedgeNumberToReturn = 0
}
print("got wedgeNumber \(wedgeNumberToReturn)")
return wedgeNumberToReturn
}
static func wedgeNumberFor(degrees:Double) -> Int {
wedgeNumberFor(angle: Measurement<UnitAngle>(value: degrees, unit: .degrees))
}
static func wedgeNumberFor(radians:Double) -> Int {
wedgeNumberFor(angle: Measurement<UnitAngle>(value: radians, unit: .radians))
}
init(compassAngle:Measurement<UnitAngle>) {
self = Self.init(wedgeNumber: Self.wedgeNumberFor(angle:compassAngle))
}
init(degrees:Double) {
self = Self.init(wedgeNumber: Self.wedgeNumberFor(degrees: degrees))
}
init(radians:Double) {
self = Self.init(wedgeNumber: Self.wedgeNumberFor(radians: radians))
}
init(wedgeNumber:Int) {
self = Self.directionFromWedgeNumber(wedgeNumber: wedgeNumber)
}
static func directionFromWedgeNumber(wedgeNumber:Int) -> Self {
guard Range(0...(Self.numberOfWedges - 1)).contains(wedgeNumber) else {
//TODO: throw error? clamp? divide?
print("Bad wedgeNumer: \(wedgeNumber)")
fatalError("Attempted wedgeNumber \(wedgeNumber) is out of bounds")
}
return Self.allCases.first(where: { $0.wedgeNumber == wedgeNumber })!
}
var wedgeNumber:Int {
switch self {
case .north: return 0
case .northNortheast: return 1
case .northeast: return 2
case .eastNortheast: return 3
case .east: return 4
case .eastSoutheast: return 5
case .southeast: return 6
case .southSoutheast: return 7
case .south: return 8
case .southSouthwest: return 9
case .southwest: return 10
case .westSouthwest: return 11
case .west: return 12
case .westNorthwest: return 13
case .northwest: return 14
case .northNorthwest: return 15
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment