如何将度数转换为弧度?

How can I convert from degrees to radians?

我正在尝试将此 Obj-C 代码转换为 Swift 代码,但我不知道此代码的等价物应该是什么?

#define DEGREES_TO_RADIANS(degrees)((M_PI * degrees)/180)

我用谷歌搜索并找到 this

但我不明白如何在 Swift 中转换它?

Xcode 11 • Swift 5.1 或更高版本

extension BinaryInteger {
    var degreesToRadians: CGFloat { CGFloat(self) * .pi / 180 }
}

extension FloatingPoint {
    var degreesToRadians: Self { self * .pi / 180 }
    var radiansToDegrees: Self { self * 180 / .pi }
}

游乐场

45.degreesToRadians         // 0.7853981633974483

Int(45).degreesToRadians    // 0.7853981633974483
Int8(45).degreesToRadians   // 0.7853981633974483
Int16(45).degreesToRadians  // 0.7853981633974483
Int32(45).degreesToRadians  // 0.7853981633974483
Int64(45).degreesToRadians  // 0.7853981633974483

UInt(45).degreesToRadians   // 0.7853981633974483
UInt8(45).degreesToRadians  // 0.7853981633974483
UInt16(45).degreesToRadians // 0.7853981633974483
UInt32(45).degreesToRadians // 0.7853981633974483
UInt64(45).degreesToRadians // 0.7853981633974483

Double(45).degreesToRadians    // 0.7853981633974483
CGFloat(45).degreesToRadians   // 0.7853981633974483
Float(45).degreesToRadians     // 0.7853981
Float80(45).degreesToRadians   // 0.78539816339744830963

如果你想使二进制整数 return 成为浮点类型而不是总是 returning CGFloat 你可以创建一个泛型方法而不是计算 属性:

extension BinaryInteger {
    func degreesToRadians<F: FloatingPoint>() -> F {  F(self) * .pi / 180 }
}

let radiansDouble: Double = 45.degreesToRadians()   // 0.7853981633974483
let radiansCGFloat: CGFloat = 45.degreesToRadians() // 0.7853981633974483
let radiansFloat: Float = 45.degreesToRadians()     // 0.7853981
let radiansFloat80: Float80 = 45.degreesToRadians() // 0.78539816339744830963

Apple 提供这些 GLKit functions 用于转换:

func GLKMathDegreesToRadians(_ degrees: Float) -> Float
func GLKMathRadiansToDegrees(_ radians: Float) -> Float

此外,将弧度转换为度数(如果有人在 google 上偶然发现了这个):

var degrees = radians * (180.0 / M_PI)

创建变量名时不再局限于 ASCII 字符,那么使用 π (alt-p) 怎么样:

typealias RadianAngle = CGFloat

let π = RadianAngle(M_PI)
let π_x_2 = RadianAngle(M_PI * 2)
let π_2 = RadianAngle(M_PI_2)
let π_4 = RadianAngle(M_PI_4)

extension RadianAngle {
    var degrees: CGFloat {
        return self * 180 / π
    }
    init(degrees: Int) {
        self = CGFloat(degrees) * π / 180
    }
}

用法示例:

let quarterCircle = RadianAngle(degrees: 90)
print("quarter circle = \(quarterCircle) radians")
// quarter circle = 1.5707963267949 radians

let halfCircle = π
print("half circle = \(halfCircle.degrees) degrees")
// half circle = 180.0 degrees

这和你问的不一样,但是在Swift 3 / iOS 10中,你可以使用Measurement type并在不知道公式的情况下进行转换!

let result = Measurement(value: 45, unit: UnitAngle.degrees)
    .converted(to: .radians).value
let angle = 45° // angle will be in radians, 45 is in degrees

Swift 3 下编译。仍然保留所有值,使用 CGFloats 以弧度为单位进行所有计算...,但使用以度为单位的常量使代码更具可读性。 例如:90° ° 符号会神奇地将度数转换为弧度。

如何设置:

° 符号定义并使用后缀运算符。该运算符将进行从度数到弧度的转换。 此示例适用于 Ints,如果需要,也可以将其扩展为 Float 类型。

postfix operator °

protocol IntegerInitializable: ExpressibleByIntegerLiteral {
  init (_: Int)
}

extension Int: IntegerInitializable {
  postfix public static func °(lhs: Int) -> CGFloat {
    return CGFloat(lhs) * .pi / 180
  }
}

一些用法示例:

let angle = 45°

contentView.transform = CGAffineTransform(rotationAngle: 45°)

let angle = 45
contentView.transform = CGAffineTransform(rotationAngle: angle°)

警告!

使用此转换两次太容易了(错误地在一个已经以弧度为单位的值上),您将得到一个非常小的数字作为结果,并且看起来结果角度将始终为零...不要在同一个值上使用 ° 两次(不要转换两次)!!:

// OBVIOUSLY WRONG!
let angle = 45°° // ° used twice here

// WRONG! BUT EASY TO MISS
let angle = 45° // ° used here
contentView.transform = CGAffineTransform(rotationAngle: angle°) // ° also used here

我会使用上面提到的相同原则 @t1ser,但是创建 CGFloat 的扩展,以便更容易使用小数来表示度数(例如,你可以有 23.4 度) ):

extension CGFloat {
    func degrees() -> CGFloat {
        return self * .pi / 180
    }

    init(degrees: CGFloat) {
        self = degrees.degrees()
    }
}

使用它也很容易(主要是因为我个人不知道如何输入 ° - 如果您也不会,那就是 option+shift+8 顺便说一句):

let degreesToConvert: CGFloat = 45.7
.
.
.
let convertedDegrees = degreesToConvert.degrees()

或者使用初始化程序:

let convertedDegrees = CGFloat(degrees: 45.3)

Swift 4.2

您可以编写全局泛型函数:

public func radians<T: FloatingPoint>(degrees: T) -> T {
    return .pi * degrees / 180
}

public func degrees<T: FloatingPoint>(radians: T) -> T {
    return radians * 180 / .pi
}

示例:

let cgFloat: CGFloat = 23.0
let double: Double = 23.0
let float: Float = 23.0
let int: Int = 23

let cgf = radians(degrees: cgFloat) // 0.4014 CGFloat
let d = radians(degrees: double)    // 0.4014 Double
let f = radians(degrees: float)     // 0.4014 Float
let i = radians(degrees: int)       // compile error

如果您不想像这样扩展所有浮动类型

extension FloatingPoint { ... }

在度数和弧度之间转换 Double 的最有效和准确的方法:

import Foundation

extension Double {
    var radians: Double { return Measurement(value: self, unit: UnitAngle.degrees).converted(to: UnitAngle.radians).value }
    var degrees: Double { return Measurement(value: self, unit: UnitAngle.radians).converted(to: UnitAngle.degrees).value }
}

Apple 的基金会团队很久以前就通过开发超越所有其他解决方案解决了这个问题:

Measurements and Units - WWDC 2016, Session 238