Angle.swift 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import Foundation
  2. /// A geometric angle whose value you access in either radians or degrees.
  3. public struct Angle: Hashable, Sendable {
  4. /// An angle in degrees
  5. public var degrees: Double {
  6. get {
  7. radians / Self.conversionFactor
  8. }
  9. set {
  10. radians = newValue * Self.conversionFactor
  11. }
  12. }
  13. /// An angle in radians
  14. public var radians: Double
  15. /// Creates an angle from a double value in degrees.
  16. public init(degrees: Double) {
  17. self.radians = degrees * Self.conversionFactor
  18. }
  19. /// Creates an angle from a double value in radians.
  20. public init(radians: Double) {
  21. self.radians = radians
  22. }
  23. /// Creates an angle based on the direction between two unit points.
  24. /// - Parameters:
  25. /// - origin: The starting point of the vector.
  26. /// - destination: The end point used to calculate the angle from the origin.
  27. public init(origin: UnitPoint, destination: UnitPoint) {
  28. let deltaX = destination.x - origin.x
  29. let deltaY = destination.y - origin.y
  30. self.init(radians: atan2(deltaY, deltaX))
  31. }
  32. /// The factor for converting an angle in degrees to the same angle in radians.
  33. private static let conversionFactor = Double.pi / 180
  34. /// Adds two angles together.
  35. public static func + (lhs: Self, rhs: Self) -> Self {
  36. Angle(radians: lhs.radians + rhs.radians)
  37. }
  38. /// Subtracts two angles.
  39. public static func - (lhs: Self, rhs: Self) -> Self {
  40. Angle(radians: lhs.radians - rhs.radians)
  41. }
  42. }
  43. extension Angle {
  44. /// The zero angle (0 degrees).
  45. public static let zero = Angle(degrees: 0)
  46. /// Creates an angle from a double value in radians.
  47. public static func radians(_ radians: Double) -> Angle {
  48. Angle(radians: radians)
  49. }
  50. /// Creates an angle from a double value in degrees.
  51. public static func degrees(_ degrees: Double) -> Angle {
  52. Angle(degrees: degrees)
  53. }
  54. }