Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. OS X
Code

Cara Membuat Grafik Vektor di iOS

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Hana Fransiska (you can also view the original English article)

Perkenalan

Sumber daya grafis di dunia digital terdiri dari dua tipe dasar, raster dan vektor. Gambar raster pada dasarnya merupakan array persegi panjang dari intensitas piksel. Grafis vektor, di sisi lain, adalah representasi bentuk matematis.

Meskipun ada situasi di mana gambar raster tidak tergantikan (foto, misalnya), dalam skenario lain, grafik vektor membuat pengganti yang mampu. Grafis vektor membuat tugas menciptakan sumber daya grafis untuk resolusi layar ganda sepele. Pada saat penulisan, ada setidaknya setengah lusin resolusi layar untuk bersaing dengan platform iOS.

Salah satu hal terbaik tentang grafik vektor adalah mereka dapat di-render ke resolusi apa pun sambil tetap benar-benar renyah dan halus. Inilah sebabnya font PostScript dan TrueType terlihat tajam pada pembesaran apa pun. Karena tampilan smartphone dan komputer bersifat raster, pada akhirnya, gambar vektor perlu ditampilkan ke layar sebagai citra raster pada resolusi yang sesuai. Ini biasanya diurus oleh pustaka grafis tingkat rendah dan programmer tidak perlu khawatir tentang hal ini.

1. Kapan Menggunakan Grafik Vektor?

Mari kita lihat beberapa skenario di mana Anda harus mempertimbangkan menggunakan grafik vektor.

Ikon Aplikasi dan Menu, Elemen Antarmuka Pengguna

Beberapa tahun yang lalu, Apple menghindari skeuomorphism di antarmuka pengguna aplikasi dan iOS itu sendiri, mendukung desain yang berani dan geometris yang tepat. Lihatlah ikon Kamera atau aplikasi Foto, misalnya.

Lebih mungkin daripada tidak, mereka dirancang menggunakan alat grafis vektor. Pengembang harus mengikuti dan sebagian besar aplikasi populer (non-game) mengalami metamorfosis lengkap untuk menyesuaikan dengan paradigma desain ini.

Permainan

Permainan dengan grafis sederhana (berpikir Asteroid) atau tema geometrik (Super Hexagon dan Geometri Jump datang ke pikiran) dapat memiliki sprite mereka yang diberikan dari vektor. Hal yang sama berlaku untuk permainan yang memiliki tingkat yang dihasilkan secara prosedural.

Gambar

Gambar di mana Anda ingin menyuntikkan sejumlah kecil keacakan untuk mendapatkan beberapa versi dari bentuk dasar yang sama.

2. Kurva Bezier

Apa kurva Bezier? Tanpa mempelajari teori matematika, mari kita bicara tentang fitur-fitur yang praktis digunakan untuk pengembang.

Derajat kebebasan

Kurva Bezier dicirikan oleh berapa derajat kebebasan yang mereka miliki. Semakin tinggi derajat ini, semakin banyak variasi kurva yang dapat digabungkan (tetapi juga semakin rumit matematisnya).

Derajat satu Beziers adalah segmen garis lurus. Derajat dua kurva disebut kurva quad. Derajat tiga kurva (kubik) adalah yang akan kita fokuskan, karena mereka menawarkan kompromi yang baik antara fleksibilitas dan kompleksitas.

Cubic Beziers dapat mewakili tidak hanya kurva halus sederhana, tetapi juga loop dan daun. Beberapa segmen Bezier kubik dapat dihubungkan ujung ke ujung untuk membentuk bentuk yang lebih rumit.

Kubik Bezier

Bezier kubik didefinisikan oleh dua titik akhirnya dan dua titik kontrol tambahan yang menentukan bentuknya. Secara umum, gelar n Bezier memiliki poin kontrol (n-1), tidak termasuk titik akhir.

Fitur menarik dari Beziers kubik adalah bahwa titik-titik ini memiliki intepretasi visual yang signifikan. Garis yang menghubungkan titik akhir ke titik kontrol yang berdekatan bertindak sebagai tangen pada kurva pada titik akhir. Fakta ini berguna untuk mendesain bentuk. Kami akan mengeksploitasi properti ini nanti di tutorial.

Transformasi Geometris

Karena sifat matematis dari kurva ini, Anda dapat dengan mudah menerapkan transformasi geometris kepada mereka, seperti penskalaan, rotasi, dan terjemahan, tanpa kehilangan kesetiaan.

Gambar berikut menunjukkan contoh berbagai jenis bentuk yang dapat dilakukan oleh satu kubik Bezier. Perhatikan bagaimana segmen garis hijau bertindak sebagai garis singgung ke kurva.

Cubic Bezier Shapes

3. Grafis Inti dan Kelas UIBezierPath

Pada iOS dan OS X, grafik vektor diimplementasikan menggunakan pustaka Inti Grafis berbasis-C. Dibangun di atas ini adalah UIKit / Kakao, yang menambah veneer orientasi objek. Pekerja keras adalah kelas UIBezierPath (NSBezierPath pada OS X), sebuah implementasi dari kurva Bezier matematis.

Kelas UIBezierPath mendukung kurva Bezier derajat satu (segmen garis lurus), dua (kurva quad), dan tiga (kurva kubik).

Secara terprogram, objek UIBezierPath dapat dibuat satu per satu dengan menambahkan komponen baru (sub-sub) ke dalamnya. Untuk memfasilitasi ini, objek UIBezierPath melacak properti currentPoint. Setiap kali Anda menambahkan segmen jalur baru, titik terakhir dari segmen yang ditambahkan menjadi titik saat ini. Gambar tambahan apa pun yang Anda lakukan umumnya dimulai pada titik ini. Anda dapat secara eksplisit memindahkan titik ini ke lokasi yang diinginkan.

Setiap kali Anda menambahkan segmen jalur baru, titik terakhir dari segmen yang ditambahkan menjadi titik saat ini. Gambar tambahan apa pun yang Anda lakukan umumnya dimulai pada titik ini. Anda dapat secara eksplisit memindahkan titik ini ke lokasi yang diinginkan.

Jalur keseluruhan bisa berupa bentuk terbuka atau tertutup. Ia bahkan dapat saling memotong atau memiliki beberapa komponen tertutup.

4. Memulai

Tutorial ini dimaksudkan untuk berfungsi sebagai tampilan luar-dasar-dasar pada pembuatan grafik vektor. Tetapi bahkan jika Anda adalah pengembang berpengalaman yang belum menggunakan Core Graphics atau UIBezierPath sebelumnya, Anda seharusnya dapat mengikutinya. Jika Anda baru menggunakan ini, saya sarankan untuk membaca sekilas melalui referensi kelas UIBezierPath (dan fungsi Inti Grafis yang mendasarinya) jika Anda belum terbiasa dengannya. Kami hanya dapat melakukan sejumlah fitur terbatas API dalam satu tutorial.

Cukup bicara. Mari mulai coding. Dalam sisa tutorial ini, saya akan menyajikan dua skenario di mana grafik vektor adalah alat yang ideal untuk digunakan.

Aktifkan Xcode, buat taman bermain baru, dan atur platform ke iOS. Kebetulan, taman bermain Xcode adalah alasan lain mengapa bekerja dengan grafis vektor sekarang menyenangkan. Anda dapat menyesuaikan kode Anda dan mendapatkan umpan balik visual instan. Perhatikan bahwa Anda harus menggunakan versi Xcode stabil terbaru, yaitu 7,2 pada saat penulisan ini.

Skenario 1: Membuat Bentuk Awan

Kami ingin menghasilkan gambar awan yang mematuhi bentuk awan dasar sementara memiliki beberapa keacakan sehingga setiap awan terlihat berbeda. Desain dasar yang saya tetapkan adalah bentuk gabungan, yang didefinisikan oleh beberapa lingkaran jari-jari acak yang berpusat di sepanjang jalur elips ukuran acak (dalam rentang yang sesuai).

Untuk memperjelas, inilah objek keseluruhan yang terlihat jika kita mengelus jalur vektor alih-alih mengisinya.

Anatomy of a Cloud

Jika geometri Anda sedikit berkarat, maka gambar Wikipedia ini menunjukkan bentuk elips.

Ellipse

Beberapa Fungsi Utilitas

Mari mulai dengan menulis beberapa fungsi pembantu.

Fungsi random(lower: upper :) menggunakan fungsi built-in arc4random_uniform() untuk menghasilkan angka acak dalam rentang lebih lower dan (upper-1). circle(at:center:) fungsi menghasilkan jalur Bezier, mewakili lingkaran dengan center dan radius yang diberikan.

Menghasilkan Poin dan Jalur

Mari sekarang fokus untuk menghasilkan poin di sepanjang jalur elips. Elips yang berpusat pada asal sistem koordinat dengan sumbunya yang disejajarkan sepanjang sumbu koordinat memiliki bentuk matematika yang sangat sederhana yang terlihat seperti ini.

Kami menetapkan nilai acak untuk panjang sumbu mayor dan minornya sehingga bentuknya terlihat seperti awan, lebih memanjang secara horizontal daripada vertikal.

Kami menggunakan fungsi stride() untuk menghasilkan sudut-sudut yang ditempatkan secara berkala di sekitar lingkaran, dan kemudian menggunakan map() untuk menghasilkan titik-titik spasi secara teratur pada elips menggunakan ekspresi matematika di atas.

Kami menghasilkan "massa" pusat awan dengan menggabungkan titik-titik di sepanjang jalur elips. Jika tidak, kami akan mendapatkan kekosongan besar di pusat.

Perhatikan bahwa jalur yang tepat tidak menjadi masalah, karena kami akan mengisi jalur, bukan membelai. Ini berarti bahwa itu tidak dapat dibedakan dari lingkaran.

Untuk menghasilkan lingkaran, pertama-tama kita secara heuristik memilih rentang untuk radius lingkaran acak. Fakta bahwa kami mengembangkan ini di taman bermain membantu saya bermain dengan nilai-nilai sampai saya mendapat hasil yang memuaskan.

Mempratinjau Hasilnya

Anda dapat melihat hasilnya dengan mengklik ikon "mata" di panel hasil di sebelah kanan, pada baris yang sama dengan pernyataan "jalur".

Quick look

Sentuhan Akhir

Bagaimana kita merasterisasikan ini untuk mendapatkan hasil akhir? Kami membutuhkan apa yang dikenal sebagai "konteks grafis" untuk menggambar jalur. Dalam kasus kami, kami akan menggambar menjadi gambar (contoh UIImage). Pada titik ini Anda perlu mengatur beberapa parameter yang menentukan apa jalur akhir yang akan ditampilkan, seperti warna dan lebar sapuan. Akhirnya, Anda mengelus atau mengisi jalur Anda (atau keduanya). Dalam kasus kami, kami ingin awan kami menjadi putih, dan kami hanya ingin mengisinya.

Mari kita paket kode ini menjadi fungsi sehingga kita dapat menghasilkan awan sebanyak yang kita inginkan. Dan sementara kami melakukannya, kami akan menulis beberapa kode untuk menggambar beberapa awan acak dengan latar belakang biru (mewakili langit) dan menggambar semua ini ke dalam tampilan langsung taman bermain.

Inilah kode terakhir:

Dan inilah hasil akhirnya:

Final clouds image

Siluet dari awan tampak sedikit buram pada gambar di atas, tetapi ini hanyalah sebuah ukuran artefak. Gambar hasil sebenarnya tajam.

Untuk melihatnya di Playground Anda sendiri, pastikan Asisten Editor terbuka. Pilih Tampilkan Editor Asisten dari menu View.

Skenario 2: Menghasilkan Jigsaw Puzzle Potongan

Potongan puzzle Jigsaw biasanya memiliki "bingkai" persegi, dengan setiap sisi menjadi rata, memiliki tab bundar menonjol keluar, atau slot dengan bentuk yang sama untuk di-tesellate dengan tab dari potongan yang berdekatan. Inilah bagian dari teka-teki jigsaw yang khas.

Jigsaw piece puzzle prototype

Menampung Variasi Dengan Grafis Vektor

Jika Anda mengembangkan aplikasi teka-teki jigsaw, Anda ingin menggunakan topeng berbentuk potongan puzzle untuk menyegmentasikan gambar yang mewakili teka-teki. Anda dapat pergi untuk masker raster yang diprasangkan sebelumnya yang dikirimkan dengan aplikasi, tetapi Anda harus menyertakan beberapa variasi untuk mengakomodasi semua variasi bentuk yang mungkin dari keempat sisi.

Dengan grafik vektor, Anda dapat menghasilkan topeng untuk jenis potongan apapun dengan cepat. Plus, akan lebih mudah untuk mengakomodasi variasi lain, seperti jika Anda ingin potongan persegi panjang atau miring (bukan potongan persegi).

Merancang Jigsaw Piece Boundary

Bagaimana kita benar-benar mendesain potongan puzzle, yang artinya, bagaimana kita mengetahui bagaimana menempatkan titik kontrol kita untuk menghasilkan jalur bezier yang terlihat seperti tab melengkung?

Ingat properti tangensi berguna dari Beziers kubik yang saya sebutkan sebelumnya. Anda dapat memulai dengan menggambar pendekatan ke bentuk yang diinginkan, memecahnya menjadi beberapa segmen dengan memperkirakan berapa banyak segmen kubik yang Anda perlukan (mengetahui jenis bentuk yang dapat dipenuhi oleh segmen kubik tunggal) dan kemudian menggambar garis singgung ke segmen ini untuk mencari tahu di mana Anda dapat menempatkan poin kontrol Anda. Berikut diagram yang menjelaskan apa yang saya bicarakan.

Bezier path for outward tab

Mengaitkan Bentuk dengan Titik Kontrol Kurva Bezier

Saya memutuskan bahwa untuk mewakili bentuk tab, empat segmen Bezier akan melakukannya dengan baik:

  • dua mewakili segmen garis lurus di kedua ujung bentuk
  • dua mewakili segmen berbentuk S yang mewakili tab di tengah

Perhatikan segmen garis putus-putus hijau dan kuning bertindak sebagai garis singgung ke segmen berbentuk S, yang membantu saya memperkirakan di mana menempatkan poin kontrol. Perhatikan juga bahwa saya memvisualisasikan potongan itu sebagai panjang satu unit, itulah sebabnya mengapa semua koordinat merupakan pecahan dari satu satuan. Saya bisa dengan mudah membuat kurva saya menjadi, katakanlah, 100 poin panjang (skala titik kontrol dengan faktor 100). Independensi resolusi grafik vektor berarti ini tidak masalah.

Terakhir, saya menggunakan Cubic Beziers bahkan untuk segmen garis lurus semata-mata demi kenyamanan, sehingga kode bisa ditulis lebih ringkas dan seragam.

Saya melewatkan menggambar titik kontrol dari segmen lurus dalam diagram untuk menghindari kekacauan. Tentu saja, kubik Bezier mewakili garis hanya memiliki titik akhir dan titik kontrol semua berbaring di sepanjang garis itu sendiri.

Fakta bahwa Anda mengembangkan ini di taman bermain berarti Anda dapat dengan mudah “rejig” nilai-nilai titik kontrol untuk menemukan bentuk yang menyenangkan Anda dan mendapatkan umpan balik instan.

Mulai

Mari mulai. Anda dapat menggunakan taman bermain yang sama seperti sebelumnya dengan menambahkan halaman baru ke dalamnya. Pilih New> Playground Page dari menu File atau buat taman bermain baru jika Anda mau.

Ganti kode apa pun di halaman baru dengan yang berikut:

Menghasilkan Semua Empat Sisi Menggunakan Transformasi Geometris

Perhatikan bahwa kami memutuskan untuk membuat jalur kami sepanjang 100 poin dengan menerapkan penskalaan skala ke poin.

Kami melihat hasil berikut menggunakan fitur "Tampilan Cepat":

Quick Look

Sejauh ini bagus. Bagaimana kita menghasilkan empat sisi potongan jigsaw? Jawabannya adalah (seperti yang bisa Anda tebak), menggunakan transformasi geometrik. Dengan menerapkan rotasi 90 derajat diikuti oleh terjemahan yang sesuai ke path di atas, kita dapat dengan mudah menghasilkan sisa sisi.

Peringatan: Masalah dengan Pengisian Interior

Ada peringatan di sini, sayangnya. Transformasi tidak akan secara otomatis menggabungkan segmen individual. Meskipun siluet jigsaw kami terlihat bagus, interiornya tidak akan dipenuhi dan kami akan menghadapi masalah saat menggunakannya sebagai topeng. Kita bisa mengamati ini di taman bermain. Tambahkan kode berikut:

Quick Look menunjukkan kepada kita hal-hal berikut:

Improperly-filled jigsaw piece

Perhatikan bagaimana bagian interiornya tidak berarsir, menandakan bahwa itu belum diisi.

Anda dapat mengetahui perintah menggambar yang digunakan untuk membuat UIBezierPath yang kompleks dengan memeriksa properti debugDeskripsi di taman bermain.

Menyelesaikan Masalah Pengisian

Transformasi geometrik pada UIBezierPath berfungsi cukup baik untuk kasus penggunaan umum, yaitu, ketika Anda sudah mendapatkan bentuk tertutup atau bentuk yang Anda transformasikan secara intrinsik terbuka, dan Anda ingin menghasilkan versi transformasi geometris darinya. Kasus penggunaan kami berbeda. Jalur ini berfungsi sebagai sub jalan dalam bentuk yang lebih besar yang kami bangun dan interiornya yang ingin kami isi. Ini sedikit rumit.

Salah satu pendekatan adalah mengacaukan internal path (menggunakan fungsi CGPathApply() dari Core Graphics API) dan secara manual menggabungkan segmen bersama untuk berakhir dengan bentuk tunggal, tertutup dan diisi dengan benar.

Tetapi opsi itu terasa sedikit bersifat peretasan dan itulah sebabnya saya memilih pendekatan yang berbeda. Kami menerapkan transformasi geometrik ke titik-titik itu sendiri terlebih dahulu, melalui fungsi CGPointApplyAffineTransform (), menerapkan transformasi yang sama persis yang kami coba gunakan beberapa saat yang lalu. Kami kemudian menggunakan poin yang diubah untuk membuat subpath, yang ditambahkan ke bentuk keseluruhan. Di akhir tutorial, kita akan melihat contoh di mana kita dapat menerapkan transformasi geometrik ke jalur Bezier dengan benar.

Menghasilkan Variasi Edge 

Bagaimana kami menghasilkan tab "innie"? Kita dapat menerapkan transformasi geometrik lagi, dengan faktor skala negatif dalam arah y (membalik bentuknya), tetapi saya memilih untuk melakukannya secara manual dengan hanya membalik koordinat-y dari titik-titik di outie_points.

Sedangkan untuk tab bermata datar, sementara saya hanya bisa menggunakan segmen garis lurus untuk menggambarkannya, untuk menghindari harus mengkhususkan kode untuk kasus yang berbeda, saya cukup mengatur koordinat-y dari setiap titik dalam outie_points menjadi nol . Ini memberi kita:

Sebagai latihan, Anda mungkin menghasilkan kurva Bezier dari tepi ini dan melihatnya menggunakan Quick Look.

Anda sekarang tahu cukup bagi saya untuk membombardir Anda dengan seluruh kode, yang mengikat semuanya bersama dalam satu fungsi.

Ganti semua konten halaman taman bermain dengan yang berikut:

Hanya ada beberapa hal yang lebih menarik dalam kode yang saya ingin klarifikasi:

  • Kami menggunakan enum untuk menentukan bentuk tepi yang berbeda. Kami menyimpan poin dalam kamus yang menggunakan nilai enumerasi sebagai kunci.
  • Kami mengumpulkan sub-sub (terdiri dari setiap sisi dari bentuk potongan jigsaw empat sisi) dalam fungsi incrementalPathBuilder(_), yang ditentukan secara internal ke fungsi jigsawPieceMaker(size: edges :).
  • Sekarang potongan jigsaw diisi dengan benar, seperti yang bisa kita lihat di output Quick Look, kita dapat dengan aman menggunakan metode applyTransform(_ :) untuk menerapkan transformasi geometrik ke bentuk. Sebagai contoh, saya telah menerapkan rotasi 60 derajat ke bagian kedua.
Examples of jigsaw puzzle pieces

Kesimpulan

Saya berharap dapat meyakinkan Anda bahwa kemampuan pemrograman menghasilkan grafik vektor dapat menjadi keterampilan yang berguna untuk dimiliki di gudang senjata Anda. Mudah-mudahan, Anda akan terinspirasi untuk memikirkan (dan mengkode) aplikasi menarik lainnya untuk grafik vektor yang dapat Anda gabungkan dalam aplikasi Anda sendiri.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.