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?


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

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

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

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

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

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)

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

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

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)

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.