ฉันกำลังพยายามแปลงObj-C
รหัสนี้เป็นSwift
รหัส แต่ฉันไม่รู้ว่ารหัสนี้ควรจะเทียบเท่ากับอะไร?
#define DEGREES_TO_RADIANS(degrees)((M_PI * degrees)/180)
ฉัน googled และพบสิ่งนี้
แต่ฉันไม่เข้าใจวิธีการแปลงใน Swift ในกรณีของฉัน?
ฉันกำลังพยายามแปลงObj-C
รหัสนี้เป็นSwift
รหัส แต่ฉันไม่รู้ว่ารหัสนี้ควรจะเทียบเท่ากับอะไร?
#define DEGREES_TO_RADIANS(degrees)((M_PI * degrees)/180)
ฉัน googled และพบสิ่งนี้
แต่ฉันไม่เข้าใจวิธีการแปลงใน 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
หากคุณต้องการให้เลขฐานสองจำนวนเต็มส่งคืนประเภททศนิยมแทนที่จะส่งคืน 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
CGFloat
?
นี่ไม่ใช่สิ่งที่คุณถาม แต่ใน Swift 3 / iOS 10 คุณสามารถใช้ประเภทการวัดและทำการแปลงโดยไม่ต้องรู้สูตร!
let result = Measurement(value: 45, unit: UnitAngle.degrees)
.converted(to: .radians).value
Apple มีฟังก์ชัน GLKitเหล่านี้สำหรับการแปลง:
func GLKMathDegreesToRadians(_ degrees: Float) -> Float
func GLKMathRadiansToDegrees(_ radians: Float) -> Float
let angle = 45° // angle will be in radians, 45 is in degrees
รวบรวมภายใต้สวิฟท์ 3 ยังคงเก็บค่าทั้งหมดทำการคำนวณทั้งหมดเป็นเรเดียนด้วย CGFloats ... แต่ทำให้โค้ดอ่านง่ายขึ้นโดยมีค่าคงที่เป็นองศา ตัวอย่างเช่น 90 ° เครื่องหมาย°จะทำการแปลงองศาเป็นเรเดียนอย่างน่าอัศจรรย์
วิธีตั้งค่านี้:
กำหนดและใช้ตัวดำเนินการ postfix สำหรับเครื่องหมาย° ตัวดำเนินการนี้จะทำการแปลงจากองศาเป็นเรเดียน ตัวอย่างนี้ใช้สำหรับ 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
public extension FixedWidthInteger { postfix static func °<T: FloatingPoint>(lhs: Self) -> T { T(lhs) * .pi / 180 } }
let angle: CGFloat = 45°
ได้ แต่ไม่จำเป็นต้องคาดหวังCGFloat
หรือFloatingPoint
ประเภทใด ๆCGAffineTransform(rotationAngle: 45°)
นอกจากนี้ในการแปลงฟรอนเรเดียนเป็นองศา (ถ้าใครสะดุดกับสิ่งนี้ใน google):
var degrees = radians * (180.0 / M_PI)
คุณไม่ จำกัด อักขระ ASCII อีกต่อไปเมื่อสร้างชื่อตัวแปรดังนั้นวิธีการใช้ about (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 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
?
T
เป็นFloatingPoint
ประเภทและ 180 เป็นInt
ประเภท คุณไม่สามารถคำนวณประเภทต่างๆได้อย่างรวดเร็ว
ฉันจะใช้หลักการเดียวกันกับ @ t1ser ที่กล่าวมาข้างต้น แต่สร้างส่วนขยายCGFloat
เพื่อให้ง่ายต่อการใช้ทศนิยมสำหรับองศาเช่นกัน (ตัวอย่างเช่นคุณอาจมี 23.4 องศา):
extension CGFloat {
func degrees() -> CGFloat {
return self * .pi / 180
}
init(degrees: CGFloat) {
self = degrees.degrees()
}
}
การใช้มันจะค่อนข้างง่ายเช่นกัน (ส่วนใหญ่เป็นเพราะโดยส่วนตัวแล้วฉันไม่รู้วิธีพิมพ์°😜 - ในกรณีที่คุณไม่ได้ทำเช่นกันมันก็เป็นoption+shift+8
btw):
let degreesToConvert: CGFloat = 45.7
.
.
.
let convertedDegrees = degreesToConvert.degrees()
หรือใช้ตัวเริ่มต้น:
let convertedDegrees = CGFloat(degrees: 45.3)