Nerding ud med Bezier-kurver

Siden de sidste par dage har jeg forsøgt at skrive mit eget lille JavaScript-animationsbibliotek. Jeg ved, jeg ved, at ingen virkelig interesserer sig for et nyt animationsbibliotek, men hej, pointen er, i den proces, jeg snublede over til Bezier-kurver. Jeg brugte et par timer på at forske og forsøgte at forstå dem, hvor jeg stødte på denne friske artikel - "Matematisk intuition bag Bezier-kurver", som også tilfældigvis er inspirationen til denne artikel. Det er mateligt og tilsyneladende rettet mod hjernefyldte mennesker, derfor havde jeg lidt hårdt med at pakke mit hoved rundt om konceptet. Men heldigvis gjorde jeg det til sidst, og dette førte til at lære en række seje nye ting om Bezier-kurver, som jeg er meget begejstret for at dele med dig.

Hvad du vil lære

Jeg starter med en introduktion til kurver, hvad de er, hvorfor de er seje, deres matematiske repræsentation. Du skal dog ikke bekymre dig om matematikken, hvis jeg skal være ærlig, suger jeg lidt af matematik, så jeg er nødt til at komme med måder at forsøge at forklare det for mig selv, og jeg er sikker på at "måderne" også fungerer for dig :)

Dernæst går vi videre til Bezier-kurver. Hvad de er, og hvad der gør dem forskellige. Deres matematiske formel.

Mod slutningen vil vi bygge vores egen lille Bezier kurvetegningsmotor i JavaScript og SVG. Hvor sejt er det?

Kurver

Jeg behøver ikke at give en formel definition af kurve her, ikke? Alle disse linjer er kurver, se på dem

Kurver er ret søde, de kan repræsentere en række ting. Ligesom for eksempel viser kurven nedenfor antallet af mine Twitter-tilhængere over tid.

Okay, det ser ud som en tilfældig skriblet linje. Lad mig tilføje nogle sammenhænge.

Det skal nu give en bedre idé om, hvad det repræsenterer. På den vandrette akse er antallet af dage siden jeg sluttede mig til Twitter, og på den lodrette akse er antallet af følgere, jeg har fået.

På min første dag på Twitter havde jeg 0 følgere, så steg det langsomt, jeg mistede nogle, fik nogle, så i sidste halvdel, som du kan se, fik jeg et antal nye følgere. Det er ikke den eneste information, vi kan dechiffrere ud af denne kurve. Jeg kan også finde ud af det nøjagtige antal tilhængere, jeg havde på en given dag. Det er bare et spørgsmål om at tegne to linjer.

Lad os sige, at jeg gerne vil vide antallet af tilhængere, jeg havde på den 60. dag.

Jeg tegner en lodret linje fra 60 på den vandrette akse og derefter fra det punkt, hvor denne linje skærer kurven, tegner jeg en vandret linje. Denne vandrette linje skærer den lodrette akse (akse med antallet af tilhængere) på et punkt. Værdien af ​​dette punkt på den lodrette akse giver mig det nøjagtige antal tilhængere, jeg havde på den 60. dag, hvilket er 126.

Nu hvor de to røde linjer krydser hinanden, kaldes det et punkt . På et 2-dimensionelt plot, ligesom vores Twitter-tilhængergraf, identificeres et punkt entydigt af to værdier, dets vandrette koordinat ( x ) og dens lodrette koordinat ( y ). Derfor er skrivning (x, y) alt, hvad der kræves for at repræsentere et punkt. I vores tilfælde kan det røde punkt, hvor de to røde linjer skærer hinanden, skrives som (60, 126).

(60 = x / vandret koordinat, 126 = y / lodret koordinat)

Okay nok til hvad et punkt er, det vidste du allerede. Lad os tale om kurven, som faktisk er en samling af mange sådanne punkter, er det ikke?

Du tager en række data som f.eks. 0 dag 0 følgere, 1. dag 50 følgere ... 10. dag 76 følgere ... 100 dag 500 følgere ... og så videre. Du konverterer disse data til punkter (0, 0) (1, 50)… (10, 76)… (100, 500) ... Du plotter punkterne på grafen, og sammenføj dem, og der har du en kurve.

Så for en kurve har du brug for point og for point har du brug for tilsvarende x- og y-værdier. Derfor skal du nu være meget opmærksom her, en kurve kan repræsenteres entydigt af noget, der kan spytte x- og y-værdier for os. Det ”noget” er det, vi kalder i matematik en funktion.

Der er mange standardfunktioner i matematik. Overvej sinusfunktionen .

I funktioner som denne er valget af x vores. Vi giver det en x , det giver os et y . Og sammen danner vi et punkt (x, y). Vi giver det endnu en x det giver os endnu et y, så og så videre ender vi med en samling af punkter, vi plotter dem og får en unik form.

En funktion kan også repræsenteres i parametrisk form . I parametrisk form behøver vi ikke levere en del af punktets koordinat som vi gjorde (x) i det foregående eksempel. I stedet for leverer vi en parameter / variabel, generelt skrevet som t, og for hver t får vi både x- og y- koordinater, kort fortalt leverer vi a t får vi et punkt.

Du vil gerne vide, hvad parametrisk form er, når vi taler om matematikken bag Bezier-kurver.

Bezier kurver

Bezier-kurver er meget specielle kurver. Matematikken og ideen bag dem sprang mig væk, og du skulle også være klar til at blive sprængt væk.

Da du læser dette, antager jeg, at du er designer eller udvikler og har behandlet Bezier-kurver før, især Cubic Bezier-kurver, vi kommer til, hvad Cubic Bezier-kurver er på et sekund. Nu bruges disse kurver forskellige steder til at skabe vektorgrafik, animationsstier, kurver til animation, kun fordi de er så nemme at kontrollere . Du behøver ikke at kende en hel masse matematik, slet ingen for at bøje disse kurver til dine luner. Tænk, hvis Bezier-kurver ikke eksisterede, og folk var nødt til at komme med unikke matematiske funktioner til kurver, for lad os sige tegne vektorgrafik som skrifttyper for eksempel, et mareridt naturligvis.

Matematik?

Okay, tid til noget matematik. Jeg starter med den generelle formel for Bezier-kurver, det er ret skræmmende ved første øjekast, men vi finder vej igennem.

”Whoa! Whoa! Whoa! Einstein! ”. Hej vent, klik ikke væk. Det er let, se, jeg gjorde det så farverigt?.

Lad os begynde at nedbryde formlen. Du kan springe over de dele, du allerede kender.

B (t)

B fordi det er en B ezier-kurve. Som nævnt tidligere i artiklen om parametrisk form for kurver, er t en parameter. Du tilslutter t og ud kommer x og y , et punkt. Vi ser snart, hvordan det fungerer med ligningen ovenfor. Det vil være godt at nævne her, at for Bezier-kurver skal værdien af t være mellem 0 og 1, begge inkluderet.

Σ / Sigma

Dette symbol, Σ, i matematik kaldes summeringsoperatoren. Den måde, det fungerer på, er sådan her, til højre for dette symbol er et udtryk med en variabel i, og jeg kan kun holde heltalsværdier. På toppen og bunden af ​​symbolet skriver vi grænserne for i. For hver værdi af i evalueres udtrykket til højre og føjes til det samlede antal, indtil jeg når n.

Her er nogle eksempler.

Bare en kortere notation for noget længere.

Okay, det ser ud til, at vi er klare med sigma.

nCi

Denne C her er C fra permutationer og C ombinationer. Lad os have en improviseret kombinationstime, skal vi. Nu, i formlen er denne del det, der kaldes en binomial koefficient. Måden at læse nCi er på denne måde, n Vælg i. Det vil sige givet n emner på hvor mange måder du kan vælge i emner ud af det (n er altid større end eller lig med i). Okay, det har måske ikke givet meget mening, overvej dette eksempel: Jeg har 3 ting en cirkel, en firkant og en trekant. Derfor her, n = 3. På hvor mange måder kan jeg vælge 2 (i = 2) emner ud af 3. På matematikens sprog, der ville blive skrevet som 3C2 (3 Vælg 2). Svaret er 3.

Tilsvarende

Og når jeg er 0, er der kun en måde at vælge 0 emner ud af n, 1, at slet ikke vælge nogen.

I stedet for at tegne skitser og finde ud af svaret på et givet kombinationsudtryk er der denne generaliserede formel.

P sub i

Dette er den vigtige bit. I den generelle formel for Bezier-kurven er der t, i og n. Vi har ikke rigtig rørt ved, hvad n er. n er det, der kaldes graden af ​​Bezier-kurven. n er det, der afgør, om en Bezier-kurve er lineær eller kvadratisk eller kubisk eller noget andet.

Du ser, hvis du har brugt penværktøjet før, klikker du på to forskellige steder for at oprette to forskellige punkter, og derefter styrer du kurven, der dannes mellem de to punkter ved hjælp af håndtag. En Bezier-kurve vil altid have mindst to ankerpunkter, og de resterende er kontrolpunkter, der bruges til at kontrollere formen på kurven. Det, du kalder håndtag, er også kun kontrolpunkterne, der er forbundet med en linje til et forankringspunkt, de er bare der for at give en bedre mental model. Så når du justerer håndtagene, ændrer du i virkeligheden simpelthen koordinaterne for kontrolpunkterne.

Lad os slippe af med alt tilbehør og fokusere på kernen.

Den kurve, du ser på billedet ovenfor, er en kubisk Bezier-kurve, eller med andre ord, graden af ​​Bezier-kurven vist ovenfor er 3, eller i den generelle formel for Bezier-kurver tilslutter du n = 3.

n = 1 giver dig en lineær Bezier-kurve med to ankerpunkter P0 og P1 og ingen kontrolpunkter, så det ender i det væsentlige med at blive en lige linje.

n = 2 giver dig en kvadratisk Bezier-kurve med to ankerpunkter P0 og P2 og et kontrolpunkt P1

og på samme måde giver n = 3 dig en kubisk Bezier-kurve med to ankerpunkter P0 og P3 og to kontrolpunkter P1 og P2. Jo højere n, jo mere komplicerede figurer kan tegnes.

Nu skal vi danne ligningen for den kubiske Bezier-kurve fra den generelle ligning, som involverer at erstatte n = 3 i den generelle formel. Ligningen, vi får, vil være i variablen t, som som nævnt tidligere er en parameter, hvis værdi varierer mellem 0 og 1. For ligningen skal vi også bruge 4 Pis (læs: Pee øjne) P0, P1, P2 og P3. Valget af disse punkter er op til os, når alt kommer til alt, når vi tegner vektorgrafik, siger ved hjælp af penværktøjet vælger vi placeringen af ​​ankerpunkter, og kontrolpunkterne gør vi ikke? Efter ændringerne ser vores ligning til Cubic Bezier-kurven sådan ud.

Vi bruger lidt kortfattethed her, i virkeligheden har hvert punkt (P) to koordinater x og y, og når vi passerer t til den generelle ligning, skal vi få et punkt, der også har x- og y-koordinater. Derfor kan vi skrive ovenstående ligning som

Du er ved at være vidne til noget meget specielt ved disse ligninger.

For at opsummere er den nævnte ligning den parametriske form for Bezier-kurven med parameteren t, som kan indeholde værdier, der varierer mellem 0 og 1. En kurve er en samling af punkter. Hver unikke t, du sender til B, giver et unikt punkt, der bygger hele Bezier-kurven.

Den magiske ting ved ligningen er, at når t = 0, B (0) = P0, og når t = 1, B (1) = P3, giver de ekstreme værdier af t, 0 og 1 derfor de yderste flest punkter i kurve, som naturligvis er ankerpunkterne. Dette gælder ikke kun for kubiske Bezier-kurver, for en kurve med grad n B (0) = P0 og B (1) = Pn.

For enhver anden værdi på t mellem 0 og 1 (f.eks. T = 0,2 i figuren ovenfor) får du et punkt, der bygger kurven op.

Da hele ligningen er afhængig af placeringen af ​​Pis (Pee-øjne), ændrer deres position kurvens form. Og sådan fungerer Bezier-kurver.

Nu hvor vi kender matematikken bag Bezier-kurver, lad os bruge den viden til noget.

Jeg har oprettet et simpelt JavaScript-program, der gengiver en kubisk Bezier-kurve, der er ingen brugergrænseflade til at interagere med det, fordi jeg ikke ønskede, at logikken skulle forsvinde i al brugergrænsefladekoden, og også fordi jeg er doven. Men det betyder ikke, at du ikke kan interagere med det :).

Var det lidt for meget at tage i? Vi startede med at definere, hvad kurver er, derfra flyttede vi til punkter, og hvordan de er byggestenene i en kurve. Derefter gik vi videre til Bezier-kurver og forstod matematikken for at finde punkter, der gør en Bezier-kurve op. Jeg håber, du har lært noget og efterladt denne artikel smartere end da du begyndte at læse den.

Koden til den lille brugerdefinerede Cubic Bezier-motor kan findes i denne GitHub-repo.

Opdatering: Generatoren kan nu generere en Bezier-kurve i enhver grad og ikke kun Cubic Bezier Curves :).

Leder du efter mere? Jeg offentliggør regelmæssigt på min blog på nashvail.me. Vi ses der, har en god!