NSAffineTransform — adalah kelas dari AppKit (macOS) yang merepresentasikan transformasi affine dalam grafis dua dimensi. Kelas ini merangkum matriks 3×3 yang mendeskripsikan kombinasi perpindahan, penskalaan, rotasi, dan pencongan koordinat. Menurut Apple Documentation (2026), NSAffineTransform banyak digunakan di Core Graphics untuk mentransformasi jalur, titik, dan konteks grafis di macOS.
Hal utama
NSAffineTransform — adalah kelas dari framework AppKit, hanya tersedia di macOS. Kelas ini merepresentasikan transformasi affine dalam ruang dua dimensi melalui matriks 3×3. Tidak seperti CGAffineTransform dari Core Graphics (yang tersedia di iOS), NSAffineTransform adalah pembungkus berorientasi objek dari struktur CGAffineTransform, menambahkan metode yang nyaman untuk bekerja dengan NSBezierPath, NSPoint, dan NSSize.
Transformasi affine — adalah transformasi bidang yang mempertahankan relasi “titik terletak pada garis lurus” dan paralelisme garis. Dengan kata lain, setelah transformasi affine, garis paralel tetap paralel, dan garis lurus tetap lurus. Namun, jarak, sudut, dan luas dapat berubah: penskalaan, rotasi, dan pencongan adalah kasus khusus dari transformasi affine.
Di iOS, padanan NSAffineTransform adalah struktur CGAffineTransform dari Core Graphics. Kedua API didasarkan pada model matematika yang sama — matriks transformasi affine 3×3, di mana baris terakhir selalu [0, 0, 1]. Perbedaannya adalah NSAffineTransform adalah kelas (dengan retain/release di Objective-C), sedangkan CGAffineTransform adalah struktur (tipe nilai) di Swift dan C.
NSAffineTransform mendukung empat jenis dasar transformasi: translate (perpindahan), scale (penskalaan), rotate (rotasi), dan shear (pencongan). Setiap jenis diwakili oleh metode terpisah dan dapat diterapkan ke objek transformasi yang ada maupun digunakan untuk membuat yang baru.
| Operasi | Metode NSAffineTransform | Parameter | Efek visual |
|---|---|---|---|
| Translate | translateXBy:yBy: | deltaX, deltaY | Perpindahan objek sepanjang sumbu X dan Y |
| Scale | scaleBy: / scaleXBy:yBy: | factor / scaleX, scaleY | Memperbesar atau memperkecil ukuran |
| Rotate | rotateByDegrees: / rotateByRadians: | sudut dalam derajat atau radian | Rotasi di sekitar titik asal koordinat |
| Shear | Melalui setTransformStruct | komponen m12, m21 matriks | Pencongan objek sepanjang sumbu |
Translate menambahkan perpindahan ke koordinat semua titik objek. Parameter deltaX dan deltaY menentukan besarnya perpindahan horizontal dan vertikal. Nilai deltaX positif menggeser ke kanan, deltaY — ke atas. Translate tidak mengubah bentuk atau ukuran objek — hanya posisinya.
Scale mengalikan koordinat titik dengan faktor yang diberikan. Pada penskalaan seragam (satu parameter), objek membesar atau mengecil secara proporsional. Pada penskalaan tidak seragam, bentuk terdistorsi. Faktor 1.0 mempertahankan ukuran, lebih besar dari 1.0 memperbesar, dari 0.0 hingga 1.0 memperkecil. Nilai negatif menciptakan pencerminan.
Rotate memutar objek di sekitar titik asal koordinat dengan sudut yang diberikan. Sudut rotasi positif sesuai dengan rotasi berlawanan arah jarum jam. rotateByDegrees menerima derajat (0–360), rotateByRadians — radian (0–2π). Rotasi selalu dilakukan relatif terhadap titik (0, 0), oleh karena itu untuk rotasi di sekitar titik sembarang, rotate harus digabungkan dengan translate.
Transformasi affine di NSAffineTransform direpresentasikan oleh matriks 3×3, di mana baris terakhir selalu [0, 0, 1]. Ini adalah representasi matematika standar yang memungkinkan penyajian kombinasi transformasi sebagai produk matriks. Struktur matriks ditentukan melalui NSAffineTransformStruct, yang berisi enam komponen penting: m11, m12, m21, m22, tX, tY.
Komponen m11, m12, m21, m22 bertanggung jawab untuk penskalaan, rotasi, dan pencongan. Komponen tX dan tY bertanggung jawab untuk perpindahan. Dalam konfigurasi standar (matriks identitas) m11 = 1, m22 = 1, sisanya 0. Untuk mendapatkan nilai matriks saat ini, gunakan transformStruct — properti NSAffineTransform yang mengembalikan struktur NSAffineTransformStruct.
Perkalian matriks adalah operasi non-komutatif. Ini berarti urutan penerapan transformasi penting: translate + rotate memberikan hasil yang berbeda dari rotate + translate. Saat menggabungkan, NSAffineTransform mengalikan matriks baru di sebelah kiri matriks saat ini: newMatrix = operation × currentMatrix. Oleh karena itu, transformasi yang ditambahkan terakhir diterapkan pertama.
NSAffineTransform memungkinkan menggabungkan beberapa transformasi dalam satu objek. Setiap panggilan translateXBy:yBy:, scaleBy:, atau rotateByDegrees: memodifikasi matriks internal — mengalikan matriks saat ini dengan matriks transformasi yang sesuai. Ini memungkinkan pembuatan transformasi kompleks dari urutan operasi sederhana.
Untuk membalikkan transformasi gabungan, gunakan metode invert. Inversi menciptakan transformasi affine baru yang membatalkan yang asli: jika kita menerapkan transformasi asli ke suatu titik, lalu yang dibalikkan, titik tersebut kembali ke posisi awal. Inversi berguna untuk membatalkan transformasi konteks sebelum menggambar elemen UI yang tidak boleh ditransformasi.
Memeriksa apakah transformasi adalah identitas (tidak mengubah koordinat) dapat dilakukan melalui properti isIdentity. Transformasi identitas adalah matriks identitas, di mana koordinat titik tidak berubah saat dikalikan. Objek NSAffineTransform baru dibuat sebagai transformasi identitas. Properti ini berguna untuk optimasi: jika transformasi adalah identitas, penerapannya dapat dilewati.
NSAffineTransform dapat diterapkan ke empat jenis objek: NSPoint, NSSize, NSBezierPath, dan konteks grafis NSGraphicsContext. Untuk setiap tujuan ada metode terpisah: transformPoint:, transformSize:, transformBezierPath:, dan set.
Metode transformPoint: mengalikan matriks transformasi dengan vektor koordinat titik (x, y, 1), mengembalikan posisi baru titik. transformSize: bekerja serupa tetapi tidak memperhitungkan komponen tX dan tY — perpindahan tidak diterapkan, hanya penskalaan, rotasi, dan pencongan. Ini berguna untuk transformasi vektor dan ukuran yang tidak boleh dipindahkan.
Metode transformBezierPath: membuat objek NSBezierPath baru, di mana setiap titik ditransformasi sesuai dengan matriks NSAffineTransform. Jalur asli tidak berubah — dibuat salinan dengan koordinat yang ditransformasi. Ini adalah operasi mahal untuk jalur kompleks dengan jumlah simpul yang besar.
Metode set menerapkan transformasi ke konteks grafis saat ini (NSGraphicsContext), memodifikasi CTM (Current Transformation Matrix). Setelah memanggil set, semua gambar selanjutnya dalam konteks ini akan ditransformasi. Untuk transformasi sementara, gunakan saveGraphicsState / restoreGraphicsState sebelum dan sesudah set.
Mari kita lihat contoh praktis penggunaan NSAffineTransform dalam aplikasi macOS untuk transformasi objek grafis.
Contoh membuat NSAffineTransform yang menggabungkan perpindahan, rotasi, dan penskalaan. Pertama objek dipindahkan sebesar (100, 50), kemudian diputar 45 derajat, dan akhirnya diperbesar 1.5 kali. Urutan penting: rotate setelah translate menghasilkan rotasi relatif terhadap titik asal koordinat baru.
import AppKit
let transform = NSAffineTransform()
transform.translateXBy(100, yBy: 50)
transform.rotateByDegrees(45)
transform.scaleBy(1.5)
// Menerapkan ke titik
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)
// Menerapkan ke ukuran
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)
Contoh menunjukkan penerapan NSAffineTransform ke konteks grafis melalui set dan concat. Setelah penerapan transformasi, semua gambar selanjutnya dilakukan dalam sistem koordinat yang ditransformasi. Menyimpan status grafis melalui saveGraphicsState memungkinkan kembali ke matriks asli.
func drawWithTransform(in rect: NSRect) {
guard let ctx = NSGraphicsContext.current
else { return }
ctx.saveGraphicsState()
let xfm = NSAffineTransform()
xfm.translateXBy(rect.midX, yBy: rect.midY)
xfm.rotateByDegrees(30)
xfm.scaleBy(0.8)
xfm.concat()
// Menggambar dalam sistem koordinat yang ditransformasi
let path = NSBezierPath(roundedRect: NSRect(
x: -50, y: -50,
width: 100, height: 100
), xRadius: 10, yRadius: 10)
NSColor.blue.setFill()
path.fill()
ctx.restoreGraphicsState()
}
Contoh mendemonstrasikan pembuatan salinan NSBezierPath dengan koordinat yang ditransformasi. Jalur asli tetap tidak berubah, dan salinan yang ditransformasi dapat digambar secara terpisah — ini berguna untuk membuat elemen berulang di posisi yang berbeda.
func createTransformedTriangle() -> NSBezierPath {
let triangle = NSBezierPath()
triangle.move(to: NSPoint(x: 0, y: 0))
triangle.line(to: NSPoint(x: 100, y: 0))
triangle.line(to: NSPoint(x: 50, y: 100))
triangle.close()
let xfm = NSAffineTransform()
xfm.translateXBy(200, yBy: 100)
xfm.scaleXBy(1.5, yBy: 1.5)
xfm.rotateByDegrees(45)
let transformed = xfm.transform(triangle)
return transformed
}
Pertanyaan yang sering diajukan
NSAffineTransform — adalah kelas dari AppKit (hanya macOS), sedangkan CGAffineTransform — adalah struktur dari Core Graphics (iOS dan macOS). NSAffineTransform adalah pembungkus berorientasi objek dan menyediakan metode untuk bekerja dengan NSBezierPath. CGAffineTransform adalah struktur tipe nilai ringan yang digunakan dengan CGPath.
Untuk memutar di sekitar pusat, lakukan tiga langkah: 1) translate ke pusat objek (memindahkan titik asal koordinat ke pusat), 2) rotate dengan sudut yang diinginkan, 3) translate kembali dengan vektor negatif pusat. Kombinasi translate—rotate—translate memberikan rotasi di sekitar titik sembarang, bukan di sekitar titik asal koordinat.
Tidak, NSAffineTransform hanya tersedia di macOS dalam AppKit. Di iOS digunakan struktur CGAffineTransform dari Core Graphics, yang menyediakan kemampuan serupa: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation, dan CGAffineTransformConcat.
Gunakan metode invert, yang mengembalikan transformasi terbalik. Jika kita mengalikan transformasi asli dengan yang terbalik, kita mendapatkan matriks identitas (transformasi identitas). Untuk penerapan sementara, panggil saveGraphicsState sebelum set dan restoreGraphicsState setelahnya.
Gunakan skala negatif: transform.scaleXBy(-1, yBy: 1) menciptakan pencerminan horizontal, dan scaleXBy(1, yBy: -1) — pencerminan vertikal. Untuk pencerminan relatif terhadap sumbu sembarang, gabungkan translate (perpindahan ke sumbu), scale dengan -1, dan translate terbalik.
Ringkasan
invert membatalkan efek transformasi affine apa punKami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga