Is it possible to change a setting, property, etc in Swift for iOS so that it assumes degrees for trigonometry calculations rather than radians?
For example si
This runs in a playground, and provides a type-safe implementation of degree/radian units. The type definitions are freely taken from here on the Swift evolution mailing list with a couple of minor syntax fixes. I wrote in some of the trig functions; the rest are a straightforward continuation of what I've shown.
import Cocoa
//MARK:- AngleType
protocol AngleType: FloatLiteralConvertible, IntegerLiteralConvertible {
var value: Double { get set }
init(_ value: Double)
init(_ value: Int)
init(integerLiteral value: T)
init(floatLiteral value: T)
}
// Implement FloatLiteralConvertible and IntegerLiteralConvertible
extension AngleType {
init(integerLiteral value: T) {
self.init(value)
}
init(_ value: T) {
self.init(integerLiteral: value)
}
init(floatLiteral value: T) {
self.init(value)
}
init(_ value: T) {
self.init(floatLiteral: value)
}
}
//MARK:- Degree
struct Degree: AngleType {
typealias FloatLiteralType = Double
typealias IntegerLiteralType = Int
var value: Double
init(_ value: Double) {
self.value = value
}
init(_ value: Int) {
self.value = Double(value)
}
}
protocol DegreeConvertible {
init(degreeLiteral value: Degree)
}
extension Degree: CustomStringConvertible, CustomDebugStringConvertible {
var description: String {
return self.value.description
}
var debugDescription: String {
return "\(self.value.description)°"
}
}
extension Degree: RadianConvertible {
init(radianLiteral value: Radian) {
self.value = Double(radianLiteral:value) * 180.0 / M_PI
}
init(_ value: Radian) {
self.init(radianLiteral: value)
}
}
//MARK:- Radian
struct Radian: AngleType {
typealias FloatLiteralType = Double
typealias IntegerLiteralType = Int
var value: Double
init(_ value: Double) {
self.value = value
}
init(_ value: Int) {
self.value = Double(value)
}
}
protocol RadianConvertible {
init(radianLiteral value: Radian)
}
extension Radian: CustomStringConvertible, CustomDebugStringConvertible {
var description: String {
return self.value.description
}
var debugDescription: String {
return "\(self.value.description)㎭"
}
}
extension Radian: DegreeConvertible {
init(degreeLiteral value: Degree) {
self.value = Double(degreeLiteral: value) * M_PI / 180.0
}
init(_ value: Degree) {
self.init(degreeLiteral: value)
}
}
//MARK:- Adding Conformance To Built In Types
extension FloatLiteralType: DegreeConvertible, RadianConvertible {
init(degreeLiteral degree: Degree) {
self = degree.value
}
init(radianLiteral radian: Radian) {
self = radian.value
}
}
extension CGFloat: DegreeConvertible, RadianConvertible {
init(degreeLiteral degree: Degree) {
self.init(degree.value)
}
init(radianLiteral radian: Radian) {
self.init(radian.value)
}
init(_ degree: Degree) {
self.init(degreeLiteral: degree)
}
init(_ radian: Radian) {
self.init(radianLiteral: radian)
}
}
func sin(value: Radian) -> Double { return sin(Double(value.value)) }
func asin(value: Double) -> Radian { return Radian(Double(asin(value))) }
func cos(value: Radian) -> Double{ return cos(Double(value.value)) }
func acos(value: Double) -> Radian { return Radian(Double(acos(value))) }
func sin(value: Degree) -> Double{ return sin(Radian(value)) }
func asin(value: Double) -> Degree { return Degree(Double(asin(value))) }
func cos(value: Degree) -> Double{ return cos(Radian(value)) }
func acos(value: Double) -> Degree { return Degree(Double(acos(value))) }
let d180: Degree = Degree(180.0)
let r180: Radian = Radian(degreeLiteral: d180)
let d0 = Degree(0.0)
let r0 = Radian(d0)
let dsin180 = sin(d180)
let rsin180 = sin(r180)
let dcos180 = cos(d180)
let rcos180 = cos(r180)
let dsin0 = sin(d0)
let rsin0 = sin(r0)
let dcos0 = cos(d0)
let rcos0 = cos(r0)
let adsin180: Degree = asin(dsin180)
let adcos180: Degree = acos(dcos180)