Created
July 1, 2022 21:28
-
-
Save carlynorama/f45aa233a693ec962b203a36c9d79539 to your computer and use it in GitHub Desktop.
potential extension to WeatherKit.Wind.CompassDirection testable as a playground
This file contains 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
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