Lulucat

Mengapa Kami Menggantikan Tiga Enjin Geometri Penyerlah dengan Cop

Gaoge ZhangGaoge Zhang

Data Apple Pencil sebenar mendedahkan kecacatan yang terlepas daripada ujian sintetik, lalu Lulucat Notes beralih daripada tiga enjin garis luar kepada model cop MaLiang.

Dikemas kini

Lulucat Notes bermula dengan perender penyerlah konvensional: bina garis luar geometri di sekeliling laluan sampel, kemudian isikan garis luar itu sekali dengan warna lut sinar. Satu isian mengelakkan jalur yang lebih gelap di tempat segmen lut sinar bertindih. Ia juga meletakkan setiap sambungan, persilangan diri, cap dan sapuan pendek dalam masalah geometri yang sama.

Tiga generasi geometri tersuai masing-masing menghapuskan satu kelas kecacatan dan mendedahkan kelas yang lain. Perender yang kami hantar sekarang menggunakan cop bulat lembut berasaskan MaLiang, iaitu rangka kerja lukisan sumber terbuka berlesen MIT oleh Harley-xk. Sebagai pertukaran untuk menghapuskan seluruh kategori kegagalan garis luar, kami menerima persilangan diri yang lebih gelap dan hujung yang meruncing mengikut tekanan.

Tulisan penyerlah biru yang ditangkap pada iPad, dengan cangkuk nipis kelihatan pada permulaan dan pengakhiran beberapa sapuan.

Tangkapan skrin asal peranti pada zum 228%. Cangkuk kecil muncul pada kedua-dua hujung beberapa sapuan.

Tulisan tangan sebenar menghasilkan cangkuk yang tiada dalam adegan sintetik

Adegan sintetik kami meliputi garis lurus, lengkok, ketikan pendek, gerakan berundur, perubahan tekanan dan belokan tajam, dan semuanya dirender dengan bersih. Namun tulisan tangan Cina sebenar masih menghasilkan cangkuk sepanjang kira-kira 1–3 titik pada permulaan dan pengakhiran banyak sapuan.

Oleh itu, kami menambah butang simpan pada aplikasi dan merakam 29 sapuan lengkap. Setiap sampel mengekalkan kedudukan, jejari, tekanan, azimut, altitud, cap masa dan flag anggaran UIKit. Program luar talian menyahkod JSON itu dan mengompilasi fail Stroke.swift, StrokeRenderer.swift dan HighlighterStrokeBuilder.swift yang sama seperti yang digunakan oleh aplikasi. Outputnya sepadan dengan tangkapan skrin peranti sapuan demi sapuan, termasuk cangkuk tersebut.

Oleh sebab perender luar talian mengeluarkan semula kecacatan hanya daripada input yang dirakam, puncanya terletak pada sampel dan geometri, bukannya tingkah laku paparan. Kini kami boleh membaca sampel tepat yang telah masuk ke dalam perender.

Hipotesis pertama kami menyalahkan orientasi Pencil yang dianggarkan ketika sentuhan dan pengangkatan. Data menolaknya. Merentasi kesemua 29 sapuan, azimut berubah paling banyak 0.09 radian dan altitud paling banyak 0.02 radian dalam lapan sampel pertama dan terakhir, dan setiap flag anggaran bernilai false pada iPad itu. Orientasi kekal stabil sementara tekanan dan arah berubah dengan mendadak.

Ambang tekanan datang daripada jurang yang jelas dalam data

Sampel terakhir bagi setiap sapuan yang dirakam mempunyai tekanan 0.000. Sampel ketika menulis berada pada atau melebihi 0.01, manakala sampel yang dirakam selepas Pencil meninggalkan permukaan berada pada atau di bawah 0.002. Sampel di udara itu sering berterusan selama 2–7 titik dan bergerak sejauh 0.8–9.0 titik, dan arahnya boleh membelok kira-kira 90 darjah menjauhi sapuan yang ditulis.

Sapuan 2 menunjukkan mekanismenya. Badannya berakhir antara 143 dan 180 darjah. Ekor bertekanan rendah itu kemudian membelok dari −90 hingga −67 darjah dan bergerak lagi sejauh 8.5 titik. Perender garis luar menganggap titik terakhir di udara sebagai titik hujung yang muktamad, lalu meregangkan cebisan geometri yang sempit ke arah titik tersebut.

Tekanan yang diukur meninggalkan jurang hampir satu tertib magnitud antara penulisan dan pergerakan di udara, jadi kami meletakkan cutoff di dalam jurang itu:

private static let pressureFloor: CGFloat = 0.005

Hanya sampel bertekanan rendah pada kedua-dua hujung yang dibuang. Sampel bertekanan rendah di tengah sapuan kekal sebagai sebahagian daripadanya. Peraturan ini mengikuti sempadan peristiwa yang diukur dan membiarkan laluan tulisan tidak diedit.

Close-up berinstrumentasi sebelum pemangkasan: sampel input hijau membelok menjauhi sapuan, sementara garis luar merah membentuk cangkuk sempit.

Sebelum pemangkasan, perender menambat cap pada sampel di udara. Titik hijau ialah sampel mentah; garis merah ialah garis luar yang dijana.

Close-up berinstrumentasi selepas pemangkasan: isian biru berakhir pada sampel tulisan terakhir dan titik hijau bertekanan rendah kekal di luarnya.

Selepas memangkas sampel di bawah 0.005, cap berakhir pada titik tulisan terakhir. Ambang tekanan ini kekal dalam perender cop semasa.

Ambang itu menghapuskan cangkuk panjang di udara. Seretan sentuhan dan lengkok pengangkatan yang pendek dengan tekanan kekal di atas 0.005 terselamat kerana kedua-duanya ialah gerakan tulisan. Mengendalikan gerakan tersebut dalam model garis luar membawa kepada pusingan geometri yang seterusnya.

Tiga enjin geometri hanya mengalihkan kecacatan

Generasi pertama: satu garis luar, satu isian

Enjin pertama yang sensitif terhadap tekanan mengikuti saluran paip yang biasa. Ia melicinkan tulang belakang, mengira ofset kiri dan kanan, menyambungkannya menjadi satu poligon, lalu mengisi poligon itu sekali. Mata pen ialah elips yang dipacu azimut dan altitud Apple Pencil, jadi keratan rentasnya berubah mengikut arah tulisan. Ketikan pendek mempunyai bentuk tersendiri, dan cap rata menggunakan sedikit asimetri untuk mengelakkan poket winding sifar.

Isian tunggal menyelesaikan pengumpulan kelegapan di dalam sapuan, tetapi memerlukan poligon yang sah pada setiap belokan. Seretan sentuhan menghasilkan baji antara cap dan badan. Gerakan berundur boleh menghasilkan poket bulan sabit putih. Belokan tajam boleh menyebabkan garis luar dalaman bersilang dengan dirinya sendiri dan meninggalkan takik yang tidak terisi.

Generasi kedua: membaiki garis luar berhampiran hujungnya

Enjin kedua mengekalkan garis luar dan menambah pembaikan setempat: pemangkasan gerakan berundur, redaman untuk sifat yang dianggarkan pada peringkat awal, pelurusan titik hujung, pemangkasan arah sementara dan sedikit sambungan cap. Setiap tampalan menangani kegagalan yang telah dihasilkan semula. Bersama-sama, tampalan itu menjadikan tingkah laku titik hujung bergantung pada beberapa ambang dan tetingkap.

Tulisan sebenar kemudian menghasilkan kes di luar tetingkap tersebut. Tetingkap pelurusan tetap sepanjang 24 titik memadamkan cangkuk yang disengajakan dalam sapuan pendek. Tetingkap adaptif mengekalkan cangkuk itu, tetapi lengkok pengangkatan masih boleh menjadi bucu yang kelihatan. Pemangkasan yang menyedari arah membuang lebih banyak gerakan sementara, dengan kos membuang kira-kira 2.5 titik daripada permulaan yang benar-benar melengkung dalam satu sapuan yang dirakam.

Setiap tampalan membaiki kes sasarannya. Namun model di bawahnya masih memerlukan garis luar keras yang kekal sah di bawah input yang bising dan melengkung.

Generasi ketiga: gabungan liputan dengan cap segi empat yang dipotong

Enjin ketiga berhenti membina satu kontur. Ia melukis trapezium bagi setiap segmen dan cakera pada setiap sampel dalaman ke dalam topeng skala kelabu, mengambil gabungan liputannya, kemudian mengenakan warna penyerlah sekali. Bulan sabit gerakan berundur, penggelapan akibat persilangan diri dan lubang winding sifar hilang kerana perender tidak lagi bergantung pada winding poligon.

Gabungan itu membulatkan hujung, lalu kami memulihkan cap segi empat dengan memotong liputan terhadap dua separuh satah titik hujung. Potongan itu membaiki garis lurus bertekanan malar dan memperkenalkan kecacatan yang lebih serius: badan sapuan melengkung boleh melintasi separuh satah titik hujung secara sah, lalu potongan cap membuang sebahagian tengah sapuan. Semasa input langsung, arah titik hujung terus berubah, maka kawasan yang dipotong bergerak dan sapuan berkelip.

Sapuan biru melengkung sebelum pembaikan potongan cap, dengan bahagian atas badannya terpotong oleh garis pepenjuru; titik hijau menunjukkan laluan sampel penuh.

Kekangan cap global memotong badan sapuan yang melengkung.

Sapuan biru melengkung yang sama selepas menambah gerbang panjang lengkok setempat, dengan kedua-dua cabang dipulihkan di sekeliling laluan sampel hijau.

Menghadkan pemotongan cap kepada primitif dalam jarak separuh lebar dari titik hujung memulihkan sapuan ini.

Gerbang panjang lengkok menjadikan pemotongan cap setempat dan membaiki setiap kes yang dirakam. Namun cangkuk sintetik yang ekstrem masih menunjukkan takik putih kecil apabila hujung bertekanan rendah bertemu cap yang dipotong. Enjin ketiga sekali lagi menukar satu kegagalan geometri dengan kegagalan yang lain.

MaLiang menghapuskan sempadan keras

MaLiang membina sapuan daripada cop tekstur berulang, bukan satu garis luar tertutup. Penjana laluannya menggunakan segmen Bézier kuadratik yang melalui titik tengah sampel bersebelahan, dan perender garisnya meletakkan cop pada langkah yang sekata sepanjang laluan itu. Saiz, putaran, warna dan kelegapan cop semuanya boleh berubah sepanjang sapuan.

Cop lembut tidak mempunyai cap, sambungan atau peraturan winding yang berasingan. Perubahan arah yang tajam kekal sebagai urutan tanda yang bertindih. Gerakan berundur tidak boleh mencipta poket poligon kosong, dan separuh satah titik hujung tidak boleh memotong tengah sapuan kerana model ini tiada potongan titik hujung.

Kami menggunakan modelnya, bukan kodnya. HighlighterStrokeBuilder semasa melaksanakan empat operasi:

  1. Buang hanya sampel titik hujung yang tekanannya di bawah 0.005.
  2. Licinkan kedudukan dengan segmen Bézier kuadratik titik tengah.
  3. Letakkan satu cop bulat bagi setiap titik panjang lengkok.
  4. Tetapkan diameter cop daripada tekanan yang dinormalkan dan gabungkan cop dengan alfa source-over.

Builder itu berkurang daripada 686 baris kepada 190. Azimut, altitud, pembinaan garis luar, topeng gabungan, tetingkap arah titik hujung, sambungan cap dan pemotongan cap semuanya keluar daripada laluan penyerlah. Kami masih merakam orientasi Pencil kerana model input menyokongnya, tetapi penyerlah itu sendiri tidak lagi membaca medan tersebut.

Formula tekanan MaLiang memerlukan penentukuran peranti

MaLiang menentukan saiz cop dengan formula yang setara dengan

yang mengandaikan bahawa force menggunakan bahagian julat 0 hingga 1 yang berguna. Data peranti kami tidak begitu. Daripada kira-kira 3,400 sampel Apple Pencil, tekanan median ialah 0.047 dan maksimum ialah 0.178. Memasukkan nilai tersebut terus ke dalam formula menjadikan tulisan biasa jauh lebih nipis daripada saiz berus nominal.

Oleh itu kami menormalkan sekitar median yang diperhatikan, kemudian menggunakan eksponen dan mengehadkan hasilnya:

Tekanan median ketika menulis kini dipetakan kepada diameter nominal 12 titik. Sentuhan yang sangat ringan kekal kelihatan pada 35% saiz nominal, manakala tekanan berat berhenti membesar pada 120%.

Penentukuran ini berkaitan dengan peranti input dan tingkah laku berus, bukannya MaLiang. Menyalin formula asal tanpa mengukur taburan tekanan kami sendiri akan mengekalkan seni bina tetapi menghasilkan berus yang salah.

Alfa setiap cop datang daripada kiraan pertindihan yang diketahui

MaLiang mengimbangi cop lut sinar yang bertindih dengan ungkapan empirikal alpha ÷ overlapping × 2.5. Berus kami mempunyai diameter nominal tetap 12 titik dan langkah cop 1 titik, jadi garis tengahnya menerima kira-kira 12 lapisan. Dalam kes kami, kiraan pertindihan diketahui dan pampasan boleh diselesaikan, bukan dianggarkan.

Untuk kelegapan sapuan sasaran dan lapisan source-over yang sama, kelegapan cop menghasilkan

maka satu cop memerlukan

Dengan dan , setiap cop menggunakan kelegapan kira-kira . Bahagian tengah mencapai warna yang dikehendaki selepas penggabungan berulang, manakala tepi menerima lebih sedikit cop dan mengekalkan peralihan berbulu sepanjang satu atau dua titik.

Helaian sapuan penyerlah biru yang pelbagai, dirender oleh model cop lembut terakhir, termasuk gelung, cangkuk, tanda pendek dan persilangan diri.

Perender akhir mengulangi laluan peranti yang dirakam. Cangkuk, potongan pepenjuru dan poket putih tidak ada.

Dua kos yang kami terima

Persilangan diri menjadi lebih gelap. Komposisi source-over mengira setiap cop, termasuk cop yang diletakkan oleh laluan terdahulu melalui kawasan yang sama, sedangkan enjin gabungan liputan mengelakkannya. Kami menerima pertindihan yang lebih gelap kerana ia boleh dijangka dan mengekalkan bentuk sapuan.

Hujung mengecil mengikut tekanan. Pengangkatan sebenar mengurangkan tekanan, lalu mengurangkan diameter cop; sapuan meruncing dan bukannya berakhir dengan cap segi empat selebar penuh. Kami menganggap cap segi empat itu sebagai keperluan dalam ketiga-tiga enjin geometri. Meninggalkannya menghapuskan pemotongan serta mekanisme titik hujung di sebalik beberapa kegagalan di atas, jadi kami menerima hujung yang meruncing.

Model yang kami hantar melakukan kurang daripada model sebelumnya. Ia mengekalkan peristiwa tulisan yang diukur, bertindak balas terhadap tekanan selepas penentukuran peranti, dan merender laluan melengkung serta laluan yang bersilang dengan diri sendiri tanpa memerlukan garis luar yang sah secara global. Mata pen berbentuk pahat, cap yang tepat-tepat segi empat dan polilaluan tepat antara sampel mentah ialah ciri yang kami lepaskan untuk mendapatkannya.

Ambang tekanan ialah bahagian yang paling mudah dipindahkan ke projek lain. Nilai 0.005 datang daripada jurang antara dua kelompok dalam input sebenar: penulisan pada 0.01 dan ke atas, dan penjejakan di udara pada 0.002 dan ke bawah. Sapuan yang sama direkodkan menunjukkan tempat setiap pembaikan geometri gagal. Kegagalan itu membawa kami kepada model cop dan dua kos yang ditanggungnya.