Bezier-curves begrijpen aan de hand van interactieve voorbeelden

EN NL


Bezier-curves zijn een van de meest gebruikte tools om vloeiende paden te tekenen in computergraphics, UI-animatie, vectorillustratie en lettertype-rendering. Zelfs wanneer een curve met de hand getekend lijkt, representeren veel systemen die met een kleine set controlepunten en een deterministische vergelijking. Dat maakt Bezier-curves zowel expressief als betrouwbaar: ontwerpers en engineers kunnen beweging en geometrie vormgeven met slechts een paar waarden.

Dit artikel bouwt vanaf de basis een praktisch begrip op. Je start met het kwadratische geval, koppelt handleplaatsing aan raaklijnrichting, vergelijkt direct het gedrag van kwadratische en kubische handles en bekijkt daarna hoe het algoritme van De Casteljau punten op beide soorten curves berekent. Voordat de notatie erbij komt, begin je met het basisgedrag: één beweegbare handle verandert een vloeiende curve tussen twee vaste eindpunten.

Sleep de blauwe handle om de curve te vervormen terwijl de twee donkere eindpunten vast blijven staan. Het gestippelde controlepolygoon toont de rechte hulplijnen die het vloeiende pad sturen. Als je de handle verder van het segment tussen de eindpunten beweegt, ontstaat een sterkere boog; dichter bij dat segment wordt de curve vlakker.

Controlepunten van Bezier-curves

Een Bezier-curve wordt gedefinieerd door controlepunten. De curve begint bij het eerste controlepunt en eindigt bij het laatste controlepunt. De punten ertussen liggen meestal niet op de curve. In plaats daarvan sturen ze de richting en de mate van kromming. Bezier-curves bestaan in meerdere vormen, maar dit artikel focust op de meest voorkomende: polynomiale Bezier-curves. Binnen die familie bepaalt het aantal controlepunten de graad van de curve. Het controlepolygoon is de reeks rechte segmenten die deze punten met elkaar verbindt. Dat is niet de gerenderde curve, maar wel de makkelijkste manier om te lezen hoe de curve uit het startpunt vertrekt, door het binnengebied buigt en bij het eindpunt aankomt.

De meest voorkomende gevallen zijn kwadratische en kubische Bezier-curves. Voor een kwadratische Bezier-curve zijn er drie punten:

  • P0P_0: startpunt
  • P1P_1: controlepunt
  • P2P_2: eindpunt

Voor een kubische Bezier-curve zijn er vier punten:

  • P0P_0: startpunt
  • P1P_1: eerste handle
  • P2P_2: tweede handle
  • P3P_3: eindpunt

Die binnenste controlepunten gedragen zich meestal als handles in plaats van punten waar de curve doorheen moet. Het verplaatsen van een handle verandert de raaklijnrichting en de sterkte van de buiging, terwijl de eindpunten vast blijven staan. Dat is de praktische reden waarom Bezier-curves zo bruikbaar zijn in tekentools, animatiepaden en lettertypes: een kleine set punten geeft voorspelbare vloeiende geometrie.

Kwadratische Bezier-curveformule

Een kwadratische Bezier-curve gebruikt drie controlepunten en één parameter tt. De formule gebruikt een parameter tt van 00 tot 11:

B(t)=(1t)2P0+2(1t)tP1+t2P2B(t) = (1 - t)^2 P_0 + 2(1 - t)t P_1 + t^2 P_2

Je kunt dit lezen als een gewogen combinatie van punten. Bij t=0t = 0 ligt al het gewicht op P0P_0, dus ligt het curvepunt aan het begin. Bij t=1t = 1 ligt al het gewicht op P2P_2, dus ligt het curvepunt aan het einde. Daartussen verschuift het gewicht vloeiend en ontstaat een continu pad.

Die vloeiende beweging komt doordat de gewichten polynomen in tt zijn. Als tt verandert, beweegt het punt op de curve continu in plaats van dat het van de ene plek naar de andere springt.

Kwadratische vorm verkennen

Dezelfde bewerkbare curve is de moeite waard om opnieuw te bekijken nu de puntlabels betekenis hebben. Dit is de eenvoudigste Bezier-vorm: twee vaste eindpunten en één beweegbaar controlepunt. De curve begint bij P0P_0, eindigt bij P2P_2 en buigt richting P1P_1. Terwijl de blauwe P1P_1-handle beweegt, toont het controlepolygoon het rechte hulpskelet en toont de curve het vloeiende resultaat. Als je P1P_1 ver wegtrekt van het segment van P0P_0 naar P2P_2, gaat het pad sterk bogen; breng je P1P_1 terug richting dat segment, dan vlakt de curve af zonder dat de eindpunten verplaatsen.

De curve loopt meestal niet door P1P_1. In plaats daarvan bepalen de twee segmenten die aan P1P_1 vastzitten de richtingen aan het begin en einde van de curve. Door de handle te verplaatsen verander je dus zowel de mate van buiging als de manier waarop de curve uit P0P_0 vertrekt en in P2P_2 aankomt. Daarom zijn Bezier-curves zo bruikbaar: je stuurt de vorm indirect en behoudt vloeiendheid. Diezelfde ideeën leiden ook tot formele eigenschappen zoals convex-hull-containment en affine invariantie, die de constructienotities van Michigan Tech uitgebreider uitleggen.

Kubische Bezier-curveformule

De meeste design- en webtools geven de voorkeur aan kubische Bezier-curves. Een kubische curve heeft vier controlepunten:

  • P0P_0: start
  • P1P_1: eerste handle
  • P2P_2: tweede handle
  • P3P_3: einde

De vergelijking is:

B(t)=(1t)3P0+3(1t)2tP1+3(1t)t2P2+t3P3B(t) = (1 - t)^3 P_0 + 3(1 - t)^2 t P_1 + 3(1 - t)t^2 P_2 + t^3 P_3

Vergeleken met kwadratisch voegt kubisch nog een handle toe en veel meer vormcontrole. Je kunt S-curves, vloeiende overgangen of scherpe bochten maken zonder te vroeg meerdere segmenten aan elkaar te ketenen. Die extra vrijheid introduceert ook gedrag dat kwadratische curves niet kunnen uitdrukken, zoals inflectiepunten en, bij sommige configuraties van controlepunten, cusp-achtige of zelfsnijdende vormen.

De vergelijkingsweergave maakt de extra kubische handle zichtbaar als een verschil in controle, niet alleen als een vergelijking van hogere graad. In het kwadratische paneel verandert de enkele binnenste handle de hele boog en koppelt die de raaklijnrichtingen aan begin en einde. In het kubische paneel verandert P1P_1 vooral het vertrek uit P0P_0, terwijl P2P_2 vooral de aankomst in P3P_3 verandert. De gedeelde Sample position-slider verbindt dat geometrische gedrag met de basisgewichten: bij de kwadratische curve wisselen drie gewichten elkaar af, terwijl bij de kubische curve vier gewichten overlappen en het binnenste van de curve meer vrijheid krijgt.

Als je de twee kubische handles naar tegenoverliggende zijden van de koorde van P0P_0 naar P3P_3 trekt, zie je het praktische verschil. De eindpunten blijven vast, maar de curve kan een S-vorm krijgen omdat de twee handles verschillende delen van het segment sturen. Kwadratische curves zijn eenvoudiger en vaak genoeg voor één gebogen boog, terwijl kubische curves vertrek en aankomst onafhankelijker laten afstellen. Dat lokale handle-gedrag is de reden dat vectoreditors raaklijnhandles bij ankerpunten tonen. Elk segment kan worden afgesteld zonder het volledige pad handmatig opnieuw te tekenen. Als je die kwalitatieve vormveranderingen van kubische curves verder wilt uitdiepen, behandelt Pomax inflecties en classificatie uitgebreider, en laat het Berkeley-rapport over detecting cusps and inflection points in curves zien dat zulke eigenschappen direct uit de afgeleidestructuur volgen. Als je dezelfde curve-idee wilt zien uitgebreid naar ruimte, laat het artikel over het visualiseren van 3D Bezier-curves en de De Casteljau-constructie zien hoe het controlepolygoon, het gesamplede pad en de interpolatieladder zich gedragen onder camerarotatie.

Raaklijnen en bewegingsrichting

Bezier-curves worden vaak gebruikt voor bewegingspaden, niet alleen voor statische tekeningen. De kubische handleweergave hierboven maakt het idee van de raaklijn aan de eindpunten goed zichtbaar. In animatie is de lokale raaklijnrichting belangrijk omdat die aangeeft waar een object op dat moment naartoe beweegt.

Voor een kubische curve is de afgeleide:

B(t)=3(1t)2(P1P0)+6(1t)t(P2P1)+3t2(P3P2)B'(t) = 3(1 - t)^2 (P_1 - P_0) + 6(1 - t)t (P_2 - P_1) + 3t^2 (P_3 - P_2)

Hieruit volgen twee praktische feiten:

  • Bij het begin (t=0t = 0) komt de richting overeen met P1P0P_1 - P_0.
  • Bij het einde (t=1t = 1) komt de richting overeen met P3P2P_3 - P_2.

Daarom verandert het verplaatsen van de twee binnenste controlepunten hoe de curve vertrekt en aankomt bij de eindpunten. In UI-animatietools zie je ditzelfde concept terug als richtingshandles.

Wanneer beweging natuurlijk moet aanvoelen, is alleen de padgeometrie niet genoeg. Je hebt ook een timingfunctie nodig voor hoe tt in de tijd verandert. Een pad kan vloeiend zijn terwijl de snelheid toch abrupt voelt als de parameterprogressie niet wordt geëased.

Het algoritme van De Casteljau

De polynomiale vergelijkingen zijn compact, maar er is ook een andere manier om zowel kwadratische als kubische Bezier-curves te evalueren: het algoritme van De Casteljau. Daarmee bereken je een punt op de curve via herhaalde lineaire interpolatie, wat betekent dat elke stap dezelfde eenvoudige vorm heeft: beweeg een fractie tt van de weg van het ene punt naar het andere. Dat is makkelijker te inspecteren en te debuggen dan een grotere polynomiale uitdrukking, omdat elk tussenpunt een duidelijke geometrische betekenis heeft.

Voor het kwadratische geval bij een gekozen tt:

  1. Interpoleer tussen P0P_0 en P1P_1 om Q0Q_0 te krijgen.
  2. Interpoleer tussen P1P_1 en P2P_2 om Q1Q_1 te krijgen.
  3. Interpoleer tussen Q0Q_0 en Q1Q_1 om B(t)B(t) te krijgen.

Het laatste punt is hetzelfde als de kwadratische formule, omdat lineaire interpolatie zelf een gewogen som is. Als Q0=(1t)P0+tP1Q_0 = (1 - t)P_0 + tP_1 en Q1=(1t)P1+tP2Q_1 = (1 - t)P_1 + tP_2, dan geeft interpoleren tussen die punten:

(1t)Q0+tQ1=(1t)2P0+2(1t)tP1+t2P2(1 - t)Q_0 + tQ_1 = (1 - t)^2 P_0 + 2(1 - t)t P_1 + t^2 P_2

De rechterkant is precies de kwadratische Bezier-vergelijking uit de formulesectie hierboven. Het voordeel is dat deze interpolatieprocedure op natuurlijke wijze uitbreidt naar curves van hogere graad en in veel implementaties numeriek stabiel is. Dat is belangrijk omdat dezelfde geometrische procedure werkt voor zowel de kwadratische curve als de kubische curve.

In Quadratic-modus laat de interpolatieslider zien hoe voor elke waarde van tt één curvepunt wordt opgebouwd. Terwijl tt van 0.00 naar 1.00 beweegt, schuift Q0Q_0 tussen P0P_0 en P1P_1, schuift Q1Q_1 tussen P1P_1 en P2P_2, en volgt het laatste geïnterpoleerde punt de echte curve. Schakelen naar Cubic-modus voegt één extra interpolatieronde toe, maar geen nieuw soort bewerking: elk punt blijft een lineaire menging tussen twee punten uit de vorige ronde.

Deze ladderweergave geeft direct een geometrische reden waarom de curve binnen de convexe regio van de controlepunten blijft. Die laat ook zien waarom De Casteljau nuttig is voor onderverdeling: één Bezier-segment opsplitsen in twee kleinere Bezier-segmenten bij de huidige waarde van tt. De linkerhelft kan worden opgebouwd uit de punten langs de ene kant van de interpolatieladder, en de rechterhelft uit de punten langs de andere kant. Renderingcode gebruikt die splitsing wanneer een curve te sterk gebogen is om nauwkeurig met één recht segment te tekenen: de curve wordt verder opgesplitst totdat elk kleiner stuk vlak genoeg is om te benaderen. Dezelfde bewerking is nuttig bij adaptieve tessellatie en hit-testing. Voor een uitgebreidere visuele behandeling van splitsen, afgeleiden en onderverdeling blijft A Primer on Bezier Curves een van de sterkste praktische referenties.

Stukgewijze Bezier-paden en continuïteit

Echte tekeningen bestaan meestal niet uit één enkele curve. Het zijn ketens van Bezier-segmenten. Bij het verbinden van segmenten is continuïteit de belangrijkste kwaliteitsfactor. Elk segment kan intern vloeiend zijn, maar het gedeelde anker tussen twee buren kan nog steeds een hoek, een snelheidsverandering of een plotselinge buigingsverandering veroorzaken. Het continuïteitslabel beschrijft wat precies op die ene overgang overeenkomt.

Vier nuttige niveaus van continuïteit duiken in de praktijk op:

  • C0C_0-continuiteit: segmenten komen samen in hetzelfde punt.
  • G1G_1-continuiteit: raaklijnrichtingen komen overeen, dus de overgang oogt vloeiend.
  • C1C_1-continuiteit: eerste afgeleiden komen overeen, dus de richting is continu.
  • C2C_2-continuiteit: tweede afgeleiden komen overeen, dus de kromming verandert vloeiend.

Het onderscheid tussen G1G_1 en C1C_1 is makkelijk te missen, omdat beide de zichtbare hoek kunnen wegnemen. Voor een kubisch segment ligt de raaklijn aan het einde op de lijn van de laatste handle naar het eindpunt, en de raaklijn van het volgende segment loopt van het gedeelde eindpunt naar de volgende handle. Als die twee handlelijnen collineair zijn, heeft de overgang een vloeiende richting. Als de handles bovendien in balans zijn zodat de afgeleidevectoren dezelfde grootte hebben, kruist het geparametriseerde pad de overgang zonder sprong in de eerste afgeleide.

De vergelijking gebruikt één gedeelde knoop met een inkomend oranje kubisch segment en een uitgaand blauw kubisch segment. In C0-modus ontmoeten de twee curves elkaar, maar de nabije handles kunnen in willekeurige richtingen wijzen, waardoor de overgang een hoek kan vormen. Als je naar G1 schakelt, klikt de uitgaande nabije handle op dezelfde raaklijn, terwijl de afstand tot de knoop behouden blijft; de hoek verdwijnt, maar de twee raaklijnvectoren kunnen nog steeds verschillende lengtes hebben. In C1-modus wordt de nabije handle gespiegeld over de gedeelde knoop, zodat de uitgaande raaklijnvector in richting én grootte overeenkomt met de inkomende.

De C2-modus legt nog één extra beperking op door de ver uitgaande handle af te leiden uit de handlegeometrie van het inkomende segment. De kleine krommingskammen bij de overgang maken die strengere voorwaarde zichtbaar: raaklijnmatching bepaalt waar de curve heen wijst, terwijl krommingsmatching bepaalt hoe scherp de curve buigt terwijl hij door de knoop gaat. Die extra soepelheid is nuttig voor nette oppervlakken, camerapaden en bewegingspaden waarbij een plotselinge verandering in buiging opvalt. Daar staat tegenover dat je minder vrijheid hebt bij het bewerken, omdat het verplaatsen van één handle nu meer van het naburige segment mee dwingt te bewegen.

In veel UI- en icoonworkflows is G1G_1 of C1C_1 de praktische basis. Als aangrenzende handles collineair rond een gedeeld anker staan, zien overgangen er visueel vloeiend uit, en gebalanceerde handles maken de wiskundige afgeleide ook nog eens gelijk. Voor oppervlakken met hoge precisie en simulatiepaden kunnen strengere continuiteitsvoorwaarden belangrijk zijn, omdat sprongen in de kromming invloed kunnen hebben op uiterlijk, beweging of vervolgberekeningen. Als je het onderscheid tussen algebraische continuïteit en visueel vloeiende overgangen precies wilt uitwerken, is de Berkeley-notitie over geometric continuity of parametric curves een nuttige vervolglezing.

Typische toepassingen

Bezier-curves komen in veel systemen voor, vaak achter gebruiksvriendelijke editors:

Hoewel de interfaces verschillen, blijft het onderliggende concept hetzelfde: controlepunten definiëren vloeiende trajecten met voorspelbaar gedrag bij de eindpunten. De SVG Paths-specificatie is de formele referentie voor hoe kwadratische en kubische padcommando’s in productieformaten worden vastgelegd.

Die productieformaten kunnen compact ogen, maar ze coderen dezelfde geometrie die in dit artikel zichtbaar is gemaakt. Een kwadratisch padcommando bewaart een handle tussen twee eindpunten; een kubisch padcommando bewaart er twee. Wanneer je een SVG-pad inspecteert of bewerkt, bepaal je nog steeds waar de raakrichtingen bij de eindpunten heen wijzen, hoe sterk de handles trekken en hoe aangrenzende segmenten op elkaar aansluiten.

Zodra je het controlepolygoon kunt lezen, voelen Bezier-curves niet meer abstract. De handles laten zien hoe het pad zal buigen, interpolatie verklaart elk punt tussen de eindpunten, en complexe tekeningen worden ketens van kleinere curvebeslissingen die je segment voor segment kunt inspecteren.