Lulucat

Miten Kimi K3 rakensi digitaalisen täytekynän vedon

Gaoge ZhangGaoge Zhang

Halusimme Freeformin suuntaa noudattavan täytekynän Lulucat Notesiin. Määrittely oli käsinkirjoituksesta otettu kuvakaappaus. Kahden mallin, yhden ratkaisevan kysymyksen ja elliptisen terän jälkeen vesikynä kirjoittaa niin kuin pitääkin. Kimi K3 teki Fireworksissa tutkimuksen, koodin ja validoinnin.

Päivitetty

Käsin kirjoitettua englanninkielistä kaunokirjoitusta, jossa lukee ”fountain pen”, kiinalaisen kalligrafiarivin yläpuolella. Teksti on piirretty elliptisellä täytekynänterällä kermanväriselle paperille: paksuna pystysuorissa vedoissa ja ohuena vaakasuorissa.

Renderöity Lulucat Notesin Metal-putkella, josta tässä kirjoituksessa kerrotaan.

Lulucat Notesissa on tavallinen kynä ja korostuskynä. Seuraavana työkaluna etenemissuunnitelmassa oli vesikynä — Apple Notesista ja Freeformista tuttu suunnan mukaan käyttäytyvä täytekynä, jolla pystysuorat vedot ovat paksuja ja vaakasuorat ohuita. Työkalun määrittely ei ollut dokumentti. Se oli kuvakaappaus: kolme riviä käsinkirjoitusta, sanat ”pencilkit”, ”无边记” ja ”这种有方向的水笔能力” — tämä suunnan mukaan käyttäytyvä vesikynäominaisuus.

Kuten aiemmassa Metal-putkessa, työn teki Kimi K3, Fireworksissa ajettava Moonshotin avoin malli: mittaukset, mallinnus, koodi ja validointi. Ihminen toimitti kuvakaappauksen, vastasi yhteen kysymykseen ja arvioi tuntumaa oikealla iPadilla.

Määrittely on kuvakaappaus

Staattinen kuva ei voi kertoa, miksi veto on ohut. Se voi kertoa vain, kuinka ohut se on ja missä. Siksi ensimmäinen vaihe oli mittaaminen. Skannasimme kuvakaappauksen rivi riviltä ja sarake sarakkeelta, seurasimme jokaisen vedon keskilinjan siirtymää sen suunnan selvittämiseksi ja muutimme sitten skannausleveyden todelliseksi leveydeksi kulman sinin avulla:

VetoSuuntaTodellinen leveys
”l”:n nousuosa, ”pencilkit”≈ 78°27.3 px
”k”:n varsi, ”pencilkit”≈ 90°28 px
Merkin 力 vasemmalle laskeutuva pyyhkäisy≈ 66°25.7 px
Kursiivin yhdysvedot≈ 8°11 px
Kiinalaiset vaakavedot (横)≈ 0°6–11 px

Paksun ja ohuen vedon suhde on ≈ 2.5. Kun sovitetaan 66°:n pisteeseen, saadaan — riippuvuus on lähes lineaarinen muuttujasta , ja huippu osuu pystyakselille. Käytännössä kyse on kallistetusta terästä: vaakasuorasta raosta, jota vaakasuora kirjoitus ei koskaan avaa.

Versio yksi: leveys suunnasta

Ensimmäinen malli oli ilmeinen. Jokaiselle syötepisteelle lasketaan suunta, muunnetaan suunta leveydeksi sovitetun käyrän avulla ja leivotaan tulos pisteen säteeseen kaappaushetkellä. Suunta arvioitiin kausaalisesti — viimeisten kaaripisteiden eksponentiaalisesti vaimenevana painotettuna keskiarvona, joka laskettiin kaksinkertaisen kulman avaruudessa, jotta kulkusuunnan vaihtuminen ei kumoaisi arviota. Käytössä ovat vain aiemmat pisteet, joten reaaliaikainen ja vahvistettu veto täsmäävät tavu tavulta.

Rakentaja läpäisi yksikkötarkistuksensa: synteettiset vaaka-, pysty-, 45°- ja suunnanvaihtopolut tuottivat teoreettiset leveydet — 0.99, 2.52, 2.00 ja 0.99 pistettä. Renderöinti ei vaatinut lainkaan uutta koodia: valmiiksi leivotulla säteellä piirretty veto on vain ketju pyöreitä leimoja, ja point-sprite-putkemme osasi piirtää ne jo.

iPadilla ihmiseltä kesti noin kymmenen sekuntia hylätä malli: ”tämä on taidekynä, ei vesikynä”.

Yksi kuva, kaksi mahdollista selitystä

Miksi se tuntui väärältä? Mahdollisia selityksiä oli kaksi, eikä kuvakaappaus pystynyt erottamaan niitä:

  • Suunnan lukitus. Terän geometria pakottaa vaakavedot ohuiksi ja pystyvedot paksuiksi riippumatta siitä, mitä käsi tekee. Juuri tämän versio yksi toteutti.
  • Paine ja nopeus. Kynä on paineohjattu, ja näytteen kuvio on vain käsinkirjoituksen dynamiikkaa: alasvedot ovat luonnostaan painettuja, yhdysvedot luonnostaan nopeita ja kevyitä.

Molemmat tuottavat kuvakaappauksen, jossa vaakavedot ovat ohuita ja pystyvedot paksuja. Ero näkyy siinä, mitä tapahtuu, kun vaakavetoa painetaan kovaa. Versio yksi pitää sen ohuena. Paineeseen reagoiva kynä tekee siitä paksun. Esitimme siis ihmiselle yhden kysymyksen: pitäisikö voimakkaasti painetun vaakavedon paksuuntua?

”Ei. Vaakavedot pysyvät ohuina.”

Suunnan lukitus varmistui. Silti jokin muu oli pielessä, sillä myös versio yksi oli lukittu suuntaan.

Vastaus oli vetojen päissä

Seuraava vihje löytyi nousuosien yläpäästä. Näytteen ”l”- ja ”k”-varsien suurennos paljasti kaksi asiaa: suora veto säilyttää saman leveyden alusta loppuun, ja vedon päät ovat litteitä diagonaalisia leikkauksia — talttaterän muoto sen noustessa pinnasta. Ei pyöreitä pisteitä. Ei paineen aiheuttamia kapenemisia.

Lähikuva näytteen kahdesta käsin kirjoitetusta nousuvarresta: kumpikin päättyy ylhäällä litteään diagonaaliseen leikkaukseen, ja varren paksuus pysyy tasaisena koko matkan.

Tätä ”taidekynän tuntuma” todella tarkoitti. Versio yksi mallinsi näytteen ulkonäön — leveyden arvioidun suunnan funktiona — mutta ei kynää. Suunnan arvioija on anturi: kohinainen syöte saa sen värisemään, kulmissa se laahaa perässä, ja se pyöristää jokaisen vedon pään ympyräksi. Oikealla terällä ei ole näitä ongelmia, koska se ei laske mitään. Leveys on geometriaa.

Versio kaksi: elliptinen terä

Lopullisessa mallissa ei ole lainkaan suunnan arvioijaa. Terä on suunnattu ellipsi: pitkä akseli on vaakasuora ja lyhyt akseli kiinteä. Ellipsin leimoja asetetaan tiheästi vedon reitille, ja kaikki muu seuraa geometriasta:

  • Vaakaveto kulkee avointa reunaa pitkin, joten sen leveys on aina — vakio ohut viiva paineesta riippumatta. Täsmälleen vahvistettu määrittely.

  • Pystyveto ylittää koko pitkän akselin: , paksu pää.

  • Diagonaalinen veto ottaa ellipsin jänteen leveyden kulkusuuntaan nähden kohtisuorassa,

  • Vedon päät ovat elliptisiä leikkauksia — näytteen litteät, terän muotoiset päät syntyvät ilman lisätyötä.

  • Paine skaalaa vain pitkää akselia, , joten se lisää mustemäärää alasvetoihin eikä voi koskaan paksuntaa vaakavetoa.

Näytteen mittausten perusteella pidimme arvot pt ja pt, eli saman 2.5-suhteen. Leimat ovat 0.5 pisteen päässä toisistaan kaaren suunnassa. Kun lyhyt säde on 0.55 pistettä, pahimman tapauksen reunaväreilyksi saadaan noin kymmenesosa pikseliä.

Renderöinti vaati yhden uuden fragment shaderin eikä mitään muuta. Vertex-muoto — sijainti, halkaisija ja väri — sisälsi jo kaiken: halkaisija on pitkä akseli ja lyhyt akseli on passikohtainen uniform. Shader laskee ellipsin SDF:n samalla puolen pikselin peittävyyden rampilla kuin pyöreät leimamme, joten tulos on pikselitasolla verrattavissa Core Graphicsin viitetoteutukseen (fillEllipse leimaa kohden). Validointi kulki tavallisen tarkistuksen läpi: kahdesta täytekynänvedosta koostuva synteettinen korpus renderöitiin molemmilla tavoilla ja verrattiin pikseli pikseliltä — rakenteellisia eroja oli nolla, ja satunnaisesti tarkistettu vaakaveto oli molemmissa renderöijissä 12 px.

Kaksi renderöintiä samasta käsin kirjoitetusta sanasta ”fountain” rinnakkain: vasemmalla suunnan mukaan skaalatun halkaisijan pyöreät leimat, jotka tuottavat pyöristetyt päät, ja oikealla elliptiset leimat, jotka tuottavat litteät teräleikatut päät ja tasaisemman leveyden.

Versio yksi vasemmalla, versio kaksi oikealla. Sama käsinkirjoitettu syöte, sama putki. Päät kertovat tarinan.

iPadilla uusi kynä läpäisi testin heti: ”好,很好” — Hyvä. Erittäin hyvä.

Epäonnistumisen säilyttäminen

Versio yksi ei joutunut roskiin. Se on kiinnostava sivellin — se ei vain ole vesikynä. Siksi se julkaistiin uuden kokeellisten siveltimien valikon ensimmäisenä vaihtoehtona ihmisen sille antamalla nimellä: 漏水的圆珠笔, vuotava kuulakärkikynä. Työkaluriville lisättiin pullopainike, joka avaa kokeilujen tekstiluettelon; seuraavan kokeilun lisääminen maksaa yhden rivin rekisterissä. Hylätty malli ei ole hukkaan heitettyä työtä, jos sen voi julkaista selvästi nimettynä kokeiluna.

Yksi ilta iterointia

Koko kaari — mittaa, mallinna, rakenna, testaa laitteella, kysy, mallinna uudelleen, rakenna uudelleen, validoi — vei yhden illan. Kimi K3 Fireworksissa hoiti silmukan koko teknisen puolen: suunnitteli mittausskannaukset, ehdotti ratkaisevaa kysymystä sen sijaan että olisi arvannut toisen kerran, poisti oman suunnan arvioijansa kun näyttö kääntyi ja laajensi pikselierojen testikehikkoa ennen kuin koski sovellukseen. Fireworksin päättelynopeus piti silmukan vuorovaikutteisena — pitkät Metal- ja Swift-diffit, pikselianalyysiskriptit ja korpustyökalut saapuivat tarpeeksi nopeasti, jotta jäljelle jäävä pullonkaula oli ihmisen arvio.

Yhteistyömalli oli sama kuin Metal-putkea käsitelleessä kirjoituksessa, ja se toimi taas: malli on nopea ja täsmällinen; ihminen vastaa mausta ja päästä päähän ulottuvasta varmennuksesta. Yksi tuntumaan perustuva palaute — ”taidekynä, ei vesikynä” — riitti siihen, että malli löysi täsmällisen mallinnusvirheen ja korvasi sen yksinkertaisemmalla suunnittelulla.

Oikea malli osoittautui väärää pienemmäksi. Versio kaksi julkaistiin vähemmillä liikkuvilla osilla kuin versio yksi — ei arvioijaa, ei tasoitusikkunaa, ei sovitettua eksponenttia. Terä ei laske leveyttä. Terä on leveys.