Make Swift Assume Degrees for Trigonometry Calculations

后端 未结 7 2454
抹茶落季
抹茶落季 2020-12-06 14:01

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

7条回答
  •  误落风尘
    2020-12-06 14:20

    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)
    

提交回复
热议问题