Nerviranje s Bezierovim krivuljama

Od posljednjih nekoliko dana pokušavam napisati vlastitu malu JavaScript animacijsku knjižnicu. Znam da znam da nikoga zapravo nije briga za novu biblioteku animacija, ali hej, poanta je u tome da sam u procesu naletio na Bezierove krivulje. Proveo sam nekoliko sati istražujući, pokušavajući ih razumjeti, tijekom čega sam naišao na ovaj svježi članak - "Matematička intuicija iza Bezierovih krivulja", koji je također inspiracija za ovaj članak. To je matematika i naizgled je usmjerena na pametne ljude, pa mi je bilo nekako teško zamotati glavu oko koncepta. Ali, na sreću, na kraju jesam i to je dovelo do saznanja niza cool novih stvari o Bezierovim krivuljama koje sam vrlo rado podijeliti s vama.

Što ćete učiti

Započet ću s uvodom u krivulje, koje su, zašto su cool, njihov matematički prikaz. Ne brinite se zbog matematike, iskreno, nekako sam sranje iz matematike, pa moram doći s načinima kako to objasniti sebi i siguran sam da će "načini" funkcionirati i za vas :).

Dalje ćemo prijeći na Bezierove krivulje. Što su, i što ih čini drugačijima. Njihova matematička formula.

Pred kraj ćemo izgraditi vlastiti mali Bezierov mehanizam za crtanje krivulja u JavaScript-u i SVG-u. Kako je to cool?

Obline

Ne trebam ovdje dati formalnu definiciju krivulje, zar ne? Sve su ove linije krivulje, pogledajte ih

Obline su prilično slatke, mogu predstavljati brojne stvari. Kao na primjer, krivulja u nastavku prikazuje broj mojih sljedbenika na Twitteru tijekom vremena.

U redu, to izgleda kao nasumično črčkana linija. Dopustite mi da dodam malo konteksta.

Sada bi trebao dati bolju predodžbu o tome što predstavlja. Na vodoravnoj osi je broj dana otkad sam se pridružio Twitteru, a na okomitoj osi broj sljedbenika koje sam stekao.

Prvog dana na Twitteru imao sam 0 sljedbenika, a zatim se polako povećavao, neke sam izgubio, neke stekao, a zatim u drugoj polovici, kao što vidite, stekao niz novih sljedbenika. To nije jedina informacija koju možemo dešifrirati iz ove krivulje. Također mogu saznati točan broj sljedbenika koje sam imao bilo kojeg dana. Stvar je samo u crtanju dviju crta.

Recimo da bih želio znati broj sljedbenika koje sam imao 60. dana.

Crtam okomitu crtu od 60 na vodoravnoj osi, a zatim od točke gdje ta crta presijeca krivulju crtam vodoravnu crtu. Ova vodoravna crta siječe okomitu os (os s brojem sljedbenika) u točki. Vrijednost te točke na okomitoj osi daje mi točan broj sljedbenika koje sam imao 60. dana, a to je 126.

Sada, gdje se dvije crvene crte sijeku, nalazi se ono što se naziva točkom . Na dvodimenzionalnoj plohi, poput grafikona naših sljedbenika na Twitteru, točka se jedinstveno identificira s dvije vrijednosti, vodoravnom koordinatom ( x ) i vertikalnom koordinatom ( y ). Stoga je pisanje (x, y) sve što je potrebno za predstavljanje točke. U našem slučaju, crvena točka, gdje se dvije crvene crte sijeku, može se zapisati kao (60, 126).

(60 = x / vodoravna koordinata, 126 = y / vertikalna koordinata)

Dovoljno dobro koliko je poanta, to ste već znali. Razgovarajmo o krivulji, što zapravo je skup više takvih točaka zar ne?

Uzimate niz podataka poput 0 sljedbenika 0-og dana, 1-og dana 50 sljedbenika ... 10-tog dana 76 sljedbenika ... 100-og dana 500 sljedbenika ... i tako dalje. Pretvorite ove podatke u točke (0, 0) (1, 50) ... (10, 76) ... (100, 500) ... Nacrtate točke na grafikonu da ih spoje i eto, imate krivulju.

Dakle, za krivulju su vam potrebne točke, a za točke odgovarajuće vrijednosti x i y. Stoga, sada obratite pažnju ovdje, krivulja može biti jedinstveno predstavljena nečim što za nas može ispljunuti vrijednosti x i ili y. To „nešto“ je ono što u matematici nazivamo funkcijom.

Mnogo je standardnih funkcija u matematici. Razmotrimo funkciju sinusa .

U ovakvim funkcijama izbor x je naš. Dajemo mu x , daje nam y . I zajedno oblikujemo točku (x, y). Dajemo mu još jedan x daje nam još jedan y, pa tako i tako na kraju imamo skup bodova, ucrtavamo ih i dobivamo jedinstveni oblik.

Funkcija se također može predstaviti u parametarskom obliku . U parametarskom obliku ne trebamo dati dio koordinate točke kao što smo to učinili (x) u prethodnom primjeru. Umjesto toga dostavljamo parametar / varijablu, općenito zapisanu kao t, a za svako t dobivamo i koordinate x i y , ukratko dostavljamo t dobivamo točku.

Morat ćete znati što je parametarski oblik kada govorimo o Matematiki iza Bezierovih krivulja.

Bezierove krivulje

Bezierove krivulje vrlo su posebne krivulje. Matematika i ideja koja stoji iza njih oduševili su me i vi biste se trebali pripremiti za oduševljenje.

Budući da ovo čitate, pretpostavljam da ste dizajner ili programer i već ste se bavili Bezierovim krivuljama, posebno Cubic Bezier krivuljama, u sekundi ćemo doći do onoga što su Cubic Bezier krivulje. Sada se ove krivulje koriste na raznim mjestima za stvaranje vektorske grafike, staze animacije, krivulje za ublažavanje animacije itd. Samo zato što ih je tako lako kontrolirati . Ne trebate znati puno matematike, nimalo da biste savili ove krivulje prema svojim željama. Pomislite da Bezierove krivulje nisu postojale i da su ljudi morali smisliti jedinstvene matematičke funkcije za krivulje, recimo za crtanje vektorske grafike poput fontova, na primjer, noćna mora naravno.

Matematika?

U redu, vrijeme je za malo matematike. Počet ću s općenitom formulom za Bezierove krivulje, na prvi je pogled poprilično zastrašujuće, ali proći ćemo kroz to.

“Joj! Joj! Joj! Einsteina! ”. Hej, čekaj, ne klikni dalje. Lako je, vidi, napravio sam ga tako živopisnim?

Počnimo s razbijanjem formule. Možete preskočiti dijelove koje već znate.

B (t)

B jer je to B ezierova krivulja. Kao što je ranije spomenuto u članku o parametarskom obliku krivulja, t je parametar. Priključite t i izlazi x i y , točka. Uskoro ćemo vidjeti kako to funkcionira s gornjom jednadžbom. Ovdje će biti dobro spomenuti da bi za Bezierove krivulje vrijednost t trebala biti između 0 i 1, uključujući obje.

Σ / Sigma

Ovaj se simbol, Σ, u matematici naziva operator zbrajanja. Način rada je ovako, s desne strane ovog simbola nalazi se izraz s varijablom i, a mogu sadržavati samo cjelobrojne vrijednosti. Na vrhu i dnu simbola ispisujemo granice i. Za svaku vrijednost i vrednuje se izraz udesno i dodaje se zbroju dok i ne dosegne n.

Evo nekoliko primjera.

Samo kraći zapis za nešto duže.

U redu, izgleda da smo sa sigmom jasni.

nCi

Ovo C ovdje je C iz Permutacija i C ombinacija. Idemo na improviziranu lekciju iz kombinacija. Sada je u formuli ovaj dio ono što se naziva binomni koeficijent. Način čitanja nCi je ovakav, n Izaberite i. Što će reći s obzirom na n stavki na koliko načina možete izabrati i stavke iz njega (n je uvijek veće od ili jednako i). Dobro, to možda i nije imalo puno smisla, razmotrite ovaj primjer: Imam 3 predmeta krug, kvadrat i trokut. Stoga je ovdje n = 3. Na koliko načina mogu odabrati 2 (i = 2) predmeta od 3. Na jeziku matematike koji bi se napisao kao 3C2 (3 odaberite 2). Odgovor je 3.

Slično tome,

A kad je 0, postoji samo jedan način da odaberem 0 stavki od n, 1, da ne odaberem nijednu.

Umjesto crtanja skica i odgovora na zadani Kombinirani izraz, postoji ova generalizirana formula.

P pod i

Ovo je važan dio. U općoj formuli za Bezierovu krivulju postoje t, i i n. Nismo se dotakli što je n. n je ono što se naziva stupnjem Bezierove krivulje. n je ono što odlučuje je li Bezierova krivulja linearna ili kvadratna ili kubična ili nešto drugo.

Vidite, ako ste već koristili alat olovke, kliknete na dva različita mjesta kako biste stvorili dvije različite točke, a zatim kontrolirate krivulju koja se formira između dviju točaka pomoću ručki. Bezierova krivulja uvijek će imati najmanje dvije sidrišne točke, a preostale su kontrolne točke koje se koriste za kontrolu oblika krivulje. Također, ono što vi nazivate ručkama su samo kontrolne točke povezane linijom sa sidrištem, one su tu samo da pruže bolji mentalni model. Dakle, kada prilagodite ručke, u stvarnosti jednostavno mijenjate koordinate kontrolnih točaka.

Riješimo se svih dodataka i usredotočimo se na jezgru.

Krivulja koju vidite na gornjoj slici je Kubična Bezierova krivulja, ili drugim riječima, stupanj Bezierove krivulje prikazane gore je 3, ili u opću formulu za Bezierove krivulje priključujete n = 3.

n = 1 daje vam linearnu Bezierovu krivulju s dvije sidrišne točke P0 i P1 i bez kontrolnih točaka, pa u osnovi završava ravnom crtom.

n = 2 daje vam kvadratnu Bezierovu krivulju s dvije sidrišne točke P0 i P2 i jednom kontrolnom točkom P1

i slično n = 3 daje vam kubnu Bezierovu krivulju s dvije sidrišne točke P0 i P3 i dvije kontrolne točke P1 i P2. Što je veći n, to se mogu crtati složeniji oblici.

Sada ćemo iz opće jednadžbe oblikovati jednadžbu za Cubic Bezierovu krivulju koja uključuje zamjenu n = 3 u općoj formuli. Jednadžba koju ćemo dobiti bit će u varijabli t koja je, kao što je ranije spomenuto, parametar čija vrijednost varira između 0 i 1. Također, za jednadžbu trebat će nam 4 Pis (čitaj: Pee eyes) P0, P1, P2 i P3. Izbor ovih točaka ovisi o nama, uostalom kad crtamo vektorske grafike recimo da pomoću alata olovke biramo položaj sidrišta, a kontrolne točke zar ne? Nakon promjena naša jednadžba za kubnu Bezierovu krivulju izgleda otprilike ovako.

Ovdje koristimo malo kratkoće, u stvarnosti svaka točka (P) ima dvije koordinate x i y, a također pri prelasku t na opću jednadžbu trebali bismo dobiti točku koja također ima x i y koordinate. Stoga gornju jednadžbu možemo zapisati kao

Upravo ćete svjedočiti nečemu vrlo posebnom u vezi s tim jednadžbama.

Da rezimiramo, spomenuta je jednadžba parametarski oblik Bezierove krivulje s parametrom t koji može sadržavati vrijednosti koje variraju između 0 i 1. Krivulja je skup bodova. Svako jedinstveno t koje prenesete u B daje jedinstvenu točku koja gradi cijelu Bezierovu krivulju.

Čarobna stvar jednadžbe je da kada je t = 0, B (0) = P0 i kada je t = 1, B (1) = P3, dakle, ekstremne vrijednosti t, 0 i 1 daju krajnje najviše točaka krivulja koje su naravno sidrišta. To ne vrijedi samo za kubične Bezierove krivulje, za krivulju stupnja n B (0) = P0 i B (1) = Pn.

Za bilo koju drugu vrijednost t između 0 i 1 (npr. T = 0,2 na gornjoj slici) dobivate točku koja gradi krivulju.

Budući da cijela jednadžba ovisi o položaju Pis-a (Pee eyes), promjena njihovog položaja mijenja oblik krivulje. I tako djeluju Bezierove krivulje.

Sad kad znamo matematiku iza Bezierovih krivulja, iskoristimo to znanje.

Stvorio sam jednostavan JavaScript program koji generira kubičnu Bezierovu krivulju, ne postoji korisničko sučelje za interakciju s njom, jer nisam htio da logika nestane u cijelom UI kodu, a također i zato što sam lijen. Ali to ne znači da s njom ne možete komunicirati :).

Je li to bilo malo previše za uzeti? Počeli smo s definiranjem krivulja, odatle smo prešli na točke i kako su oni blokovi krivulje. Zatim smo nastavili do Bezierovih krivulja i razumjeli Matematiku kako bismo pronašli točke koje čine Bezierovu krivulju. Nadam se da ste nešto naučili i ovaj članak ostavili pametnijim nego kad ste ga počeli čitati.

Kôd malog prilagođenog Cubic Bezier motora može se naći u ovom GitHub repo-u.

Ažuriranje: Generator sada može generirati Bezierovu krivulju bilo kojeg stupnja, a ne samo kubne Bezierove krivulje :).

Tražite više? Redovito objavljujem na svom blogu na nashvail.me. Vidimo se tamo, poželite dobar!