如何将度数转换为弧度?


107

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

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

我用Google搜索并找到了这个

但是我不知道如何在Swift中转换它?


我认为您缺少一些代码。你们都可以添加所有相关代码吗?还有其他定义吗?
BlackHatSamurai 2015年

这是我的快速代码:pastebin.com/bZ4a7EVN
Dharmesh Kheni 2015年

你能告诉我你的.h文件吗?
BlackHatSamurai 2015年

这是一个宏。您需要一个功能。
gnasher729

Answers:


267

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

如果要使二进制整数返回浮点类型而不是始终返回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

4
你不应该扩展CGFloat吗?
Zorayr 2015年

1
@Zorayr已更新为Swift 3,并扩展了FloatingPoint现在将它们全部扩展了
Leo Dabus

3
实际上,在Swift 3中,您可以使用Measurement类型,而您根本不需要了解转换公式!
马特

3
注意,但是,此superpro技巧... stackoverflow.com/a/28600210/294884
Fattie 2016年

1
无缘无故地投票没有任何意义。发表评论
Leo Dabus

63

这与您的要求不同,但是在Swift 3 / iOS 10中,您可以使用Measurement类型并执行转换而无需知道公式!

let result = Measurement(value: 45, unit: UnitAngle.degrees)
    .converted(to: .radians).value

4
再次@matt上班了,谢谢!不幸的是只有iOS 10。
含义-2016年

有趣的是,让弧度= CGFloat(30.3 * .pi / 180.0)让弧度2 =测量(值:30.3,单位:UnitAngle.degrees).converted(至:.radians)。值将不同:0.5288347633542818和0.5288345742619878
Zaporozhchenko Oleksandr

并确保“'Measurement'仅在iOS 10.0或更高版本上可用”
Zaporozhchenko Oleksandr

42

Apple提供了以下GLKit函数进行转换:

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

GLKit即将退出舞台,因为现在它是Metal的世界,再见GL。将iPad应用程序移植到Mac时,不再支持GLKit!。
菊光

17
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

IntegerInitializable协议是没有意义的。Int已符合ExpressibleByIntegerLiteral
Leo Dabus

顺便说一句,您可以使此运算符通用以支持任何Integer并返回任何浮点数。public extension FixedWidthInteger { postfix static func °<T: FloatingPoint>(lhs: Self) -> T { T(lhs) * .pi / 180 } }
Leo Dabus

在创建泛型方法时,在对它进行注释之前,如果编译器无法推断出结果类型,则需要显式设置结果类型let angle: CGFloat = 45°。但是不需要它的地方是期望的CGFloat或任何FloatingPoint类型的东西CGAffineTransform(rotationAngle: 45°)
Leo Dabus

11

另外,要将fron弧度转换为度数(如果有人在Google上偶然发现了这一点):

var degrees = radians * (180.0 / M_PI)

3

创建变量名称时,您不再局限于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

2

斯威夫特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 { ... }

为什么不简单return .pi * degrees / 180
Leo Dabus

@LeoDabus因为TFloatingPoint类型,而180是Int类型。不能迅速对不同类型进行计算。
Tikhonov Alexander

你错了。Swift可以推断出类型。它的行为与您扩展FloatingPoint类型的行为完全相同。180可以是任何东西。不一定是Int
Leo Dabus

1
FloatingPoint符合ExpressibleByIntegerLiteral,这就是为什么您可以在那里写180的原因
Leo Dabus

1
180.0需要T,因为T不一定是Double。它可以是任何浮点类型。您初始化从你的双180.0一个新的
狮子座Dabus

1

我将使用与上述@ 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)

-5

迅捷2.3

func  kilometersBetween(Place1:CLLocationCoordinate2D , Place2:CLLocationCoordinate2D) -> Double{
    var start = MKMapPointForCoordinate(Place1)
    var finish = MKMapPointForCoordinate(Place2)
    print(MKMetersBetweenMapPoints(start, finish) / 1000)
    return MKMetersBetweenMapPoints(start, finish) / 1000
} 

1
尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高​​答案的长期价值。
Nic3500 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.