Dharmesh Kheni
Dharmesh Kheni

Reputation: 71852

How can I convert from degrees to radians?

I am trying to convert this Obj-C code to Swift code but I don't know what the equivalent of this code should be ?

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

I googled and found this

But I don't understand how to convert that in Swift in my case?

Upvotes: 117

Views: 78865

Answers (10)

nylki
nylki

Reputation: 503

If it is ok to import SwiftUI or if you are already using it you could use the Angle type to convert between angle units, eg.:

import SwiftUI

let radians = Angle(degrees: 45).radians

This will convert from Double to Double.

Upvotes: 1

James Bush
James Bush

Reputation: 1525

The most efficient and accurate way to convert a Double between degrees and radians:

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 }
}

The Foundation team at Apple addressed this problem long ago by developing a solution that surpasses all others:

Measurements and Units - WWDC 2016, Session 238

Upvotes: 5

Leo Dabus
Leo Dabus

Reputation: 236508

Xcode 11 • Swift 5.1 or later

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

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

Playground

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

If you would like to make the binary integer return a floating point type instead of always returning a CGFloat you can make a generic method instead of a computed property:

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

Upvotes: 286

Tikhonov Aleksandr
Tikhonov Aleksandr

Reputation: 14349

Swift 4.2

You can write global generic functions:

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

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

Example:

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

In case when you don't want to extension all your floating types like this

extension FloatingPoint { ... }

Upvotes: 2

Septronic
Septronic

Reputation: 1176

I'd use the same principle @t1ser mentioned above, but create an extension of CGFloat to make it easier to use decimals for the degree as well (so you could have a 23.4 degrees, for example):

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

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

Using it would be pretty easy as well (mainly because I personally didn't know how to type ° 😜 - in case you didn't either, it's option+shift+8 btw):

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

Or to use the initialiser:

let convertedDegrees = CGFloat(degrees: 45.3)

Upvotes: 1

t1ser
t1ser

Reputation: 1624

let angle = 45° // angle will be in radians, 45 is in degrees

Compiles under Swift 3. Still keep all values, do all calculations in radians with CGFloats..., but make the code more readable with the constants in degrees. For example: 90° The ° sign will magically do the degrees to radians conversion.

How to set this up:

Define and use a postfix operator for the ° sign. This operator will do the conversion from degrees to radians. This example is for Ints, extend these also for the Float types if you have the need.

postfix operator °

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

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

Some examples of usage:

let angle = 45°

contentView.transform = CGAffineTransform(rotationAngle: 45°)

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

Warning!

It is too easy to use this conversion twice (on a value already in radians by mistake), you will get a very small number as the result, and seemingly the resulting angle will be always zero... DO NOT use ° on the same value twice (do not convert twice)!!:

// 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

Upvotes: 19

matt
matt

Reputation: 535925

This is not identically what you asked, but in Swift 3 / iOS 10, you can use the Measurement type and do the conversion without knowing the formula!

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

Upvotes: 73

Ashley Mills
Ashley Mills

Reputation: 53183

You're no longer limited to ASCII characters when creating variable names, so how about this using π (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
    }
}

Example usage:

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

Upvotes: 3

nikans
nikans

Reputation: 2565

Also, to convert fron radians to degrees (if anyone stumbles upon this on google):

var degrees = radians * (180.0 / M_PI)

Upvotes: 12

Crashalot
Crashalot

Reputation: 34523

Apple provides these GLKit functions for conversion:

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

Upvotes: 43

Related Questions