Bagaimana cara mengonversi dari derajat ke radian?

107

Saya mencoba untuk mengubah Obj-Ckode ini menjadi Swiftkode tetapi saya tidak tahu apa yang seharusnya setara dengan kode ini?

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

Saya mencari di Google dan menemukan ini

Tapi saya tidak mengerti bagaimana mengubahnya di Swift dalam kasus saya?

Dharmesh Kheni
sumber
Saya pikir Anda kehilangan beberapa kode. Bisakah Anda menambahkan semua kode yang relevan? Definisi lainnya, seperti derajat?
BlackHatSamurai
ini adalah kode cepat saya: pastebin.com/bZ4a7EVN
Dharmesh Kheni
Bisakah Anda menunjukkan kepada saya file .h?
BlackHatSamurai
Itu makro. Anda menginginkan sebuah fungsi.
gnasher729
1
ultratip ... stackoverflow.com/a/28600210/294884
Fattie

Jawaban:

267

Xcode 11 • Swift 5.1 atau lebih baru

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

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

Tempat bermain

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

Jika Anda ingin membuat bilangan bulat biner mengembalikan tipe titik mengambang alih-alih selalu mengembalikan CGFloat, Anda dapat membuat metode umum alih-alih properti yang dihitung:

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
Leo Dabus
sumber
4
Tidakkah sebaiknya Anda memperpanjang CGFloat?
Zorayr
1
@Zorayr memperbarui ke Swift 3 dan memperluas FloatingPoint sekarang memperluas semuanya
Leo Dabus
3
Sebenarnya, di Swift 3 Anda dapat menggunakan jenis Pengukuran dan Anda tidak perlu mengetahui rumus konversinya sama sekali!
matt
3
CATATAN NAMUN tip superpro ini ... stackoverflow.com/a/28600210/294884
Fattie
1
Memberi suara tanpa alasan tidak masuk akal. Posting komentar
Leo Dabus
63

Ini tidak persis seperti yang Anda minta, tetapi di Swift 3 / iOS 10, Anda dapat menggunakan jenis Pengukuran dan melakukan konversi tanpa mengetahui rumusnya!

let result = Measurement(value: 45, unit: UnitAngle.degrees)
    .converted(to: .radians).value
Matt
sumber
4
Luar biasa @matt di tempat kerja lagi, terima kasih! Hanya iOS 10 sayangnya.
arti-penting
Hal yang menarik biarkan radian = CGFloat (30.3 * .pi / 180.0) biarkan radians2 = Measurement (value: 30.3, unit: UnitAngle.degrees) .converted (to: .radians) .value akan berbeda: 0.5288347633542818 and 0.5288345742619878
Zaporozhchenko Oleksandr
dan tentu "'Pengukuran' hanya tersedia di iOS 10.0 atau yang lebih baru"
Zaporozhchenko Oleksandr
42

Apple menyediakan fungsi GLKit berikut untuk konversi:

func GLKMathDegreesToRadians(_ degrees: Float) -> Float
func GLKMathRadiansToDegrees(_ radians: Float) -> Float
Crashalot
sumber
GLKit akan segera turun panggung, karena sekarang dunia Metal, bye GL. Sebagai aplikasi porting iPad ke Mac, GLKit tidak lagi didukung !.
Juguang
17
let angle = 45° // angle will be in radians, 45 is in degrees

Dikompilasi dengan Swift 3 . Tetap pertahankan semua nilai, lakukan semua penghitungan dalam radian dengan CGFloat ..., tetapi buat kode lebih mudah dibaca dengan konstanta dalam derajat. Misalnya: 90 ° Tanda ° secara ajaib akan melakukan konversi derajat menjadi radian.

Bagaimana mengatur ini:

Tentukan dan gunakan operator postfix untuk tanda ° . Operator ini akan melakukan konversi dari derajat ke radian. Contoh ini untuk Ints, perluas ini juga untuk tipe Float jika Anda membutuhkannya.

postfix operator °

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

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

Beberapa contoh penggunaan:

let angle = 45°

contentView.transform = CGAffineTransform(rotationAngle: 45°)

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

Peringatan!

Terlalu mudah untuk menggunakan konversi ini dua kali (pada nilai yang sudah dalam radian karena kesalahan), Anda akan mendapatkan angka yang sangat kecil sebagai hasilnya, dan tampaknya sudut yang dihasilkan akan selalu nol ... JANGAN gunakan ° pada hal yang sama nilai dua kali (jangan dikonversi dua kali) !!:

// 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
t1ser
sumber
IntegerInitializableprotokol tidak ada gunanya. Int sudah sesuai denganExpressibleByIntegerLiteral
Leo Dabus
Btw Anda dapat menjadikan operator ini generik untuk mendukung Integer dan mengembalikan Floating Point juga. public extension FixedWidthInteger { postfix static func °<T: FloatingPoint>(lhs: Self) -> T { T(lhs) * .pi / 180 } }
Leo Dabus
Dan sebelum Anda mengomentarinya saat membuat metode umum, Anda perlu menyetel secara eksplisit jenis yang dihasilkan jika kompilator tidak dapat menyimpulkan jenis yang dihasilkan let angle: CGFloat = 45°. Tetapi tidak diperlukan di mana ia mengharapkan CGFloatatau FloatingPointjenis apa punCGAffineTransform(rotationAngle: 45°)
Leo Dabus
11

Juga, untuk mengubah radian fron menjadi derajat (jika ada yang menemukan ini di google):

var degrees = radians * (180.0 / M_PI)
nikans
sumber
3

Anda tidak lagi dibatasi pada karakter ASCII saat membuat nama variabel, jadi bagaimana kalau menggunakan π (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
    }
}

Contoh penggunaan:

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
Ashley Mills
sumber
2

Swift 4.2.0

Anda dapat menulis fungsi umum global:

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

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

Contoh:

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

Jika Anda tidak ingin memperpanjang semua tipe floating Anda seperti ini

extension FloatingPoint { ... }
Tikhonov Alexander
sumber
Mengapa tidak sederhana return .pi * degrees / 180?
Leo Dabus
@LeoDabus karena Tmerupakan FloatingPointjenis dan 180 adalah Intjenis. Dengan cepat Anda tidak dapat melakukan kalkulasi pada tipe yang berbeda.
Tikhonov Alexander
Anda salah. Swift bisa menyimpulkan tipenya. Ini berperilaku persis sama seperti jika Anda memperluas tipe FloatingPoint. 180 bisa apa saja. belum tentu seorang Int
Leo Dabus
1
FloatingPoint sesuai dengan ExpressibleByIntegerLiteral itulah sebabnya Anda dapat menulis 180 di sana
Leo Dabus
1
180.0 membutuhkan T karena T belum tentu Double. Ini bisa berupa tipe floating point apa saja. Anda menginisialisasi yang baru dari
180,0
1

Saya akan menggunakan prinsip yang sama @ t1ser yang disebutkan di atas, tetapi buat ekstensi CGFloatuntuk membuatnya lebih mudah menggunakan desimal untuk derajatnya juga (jadi Anda bisa memiliki 23,4 derajat, misalnya):

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

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

Menggunakannya akan sangat mudah juga (terutama karena saya pribadi tidak tahu cara mengetik ° 😜 - jika Anda juga tidak, itu option+shift+8btw):

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

Atau untuk menggunakan penginisialisasi:

let convertedDegrees = CGFloat(degrees: 45.3)
Septronic
sumber
-5

swift 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
} 
HardikParmar
sumber
1
Meskipun kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa kode ini memecahkan masalah akan meningkatkan nilai jangka panjang jawaban.
Nic3500