Krivulje in ploskve v računalniški geometriji, II. Posebni in splošni primeri

Do sedaj smo razpravljali o tem, kako narisati krivuljo skozi dano množico točk. Obravnavane metode v mnogih primerih dajejo odlične rezultate in so še posebej priročni pri opisovanju oblike, katere osnova je pridobljena s poskusi ali matematičnimi izračuni. To so na primer krilo letala, sestavni deli motorja, mehanski in strukturni deli. Obstaja pa še en razred problemov, kjer je rešitev odvisna tako od funkcionalnih kot estetskih zahtev, na primer od oblikovanja površine avtomobila, trupa letala, oblike ladje, pohištva ali posode. Poleg kvantitativnih kriterijev je treba upoštevati praktične izkušnje, zato je pogosto potrebno interaktivno posredovanje razvijalca.

Zgoraj obravnavane metode, zlasti kubični zlepki, so neprijetne za interaktivno delo. Smer in velikost tangent ne zagotavljata potrebnega intuitivnega razumevanja krivulje, saj povezava med nizom števil in obliko ustrezne krivulje ni očitna.

Pierre Bézier je predlagal drugo metodo za ustvarjanje krivulj in površin katere koli oblike. Bézier je matematično osnovo svoje metode izpeljal iz geometrijskih premislekov - vendar se je v njegovih delih pokazalo, da je njegov rezultat enakovreden Bernsteinovi bazi ali polinomski aproksimacijski funkciji.

riž. 5-25 Bezierova krivulja in njene določujoče točke.

Bezierjeva krivulja je definirana s poligonom, kot je prikazano na sl. 5-25. Ker je Bezierjeva osnova Bernstein, so nekatere lastnosti Bezierovih krivulj takoj znane. Na primer:

Osnovne funkcije so realne.

Stopnja polinoma, ki določa odsek krivulje, je za eno manjša od števila točk ustreznega poligona.

Osnova oblike krivulje sledi obrisu mnogokotnika.

Prva in zadnja točka krivulje sovpadata z ustreznima točkama definirajočega poligona.

Tangentni vektorji na koncih krivulje sovpadajo v smeri s prvo in zadnjo stranjo mnogokotnika.

Krivulja leži znotraj konveksne lupine poligona, to je znotraj največjega mnogokotnika, zgrajenega po danih točk. Na sl. 5-25 je konveksna lupina označena s črtkanimi in tankimi črtami.

Krivulja ima lastnost zmanjševanja variacije. To pomeni, da krivulja seka katero koli ravno črto največkrat kot določajoči poligon. Krivulja je invariantna glede na afine transformacije.

Na sl. Slika 5-26 prikazuje več štiritočkovnih Bezierjevih poligonov in ustreznih krivulj. Na podlagi zgoraj navedenih lastnosti se lahko enostavno naučite napovedati obliko krivulje na podlagi oblike mnogokotnika.

Matematična parametrična predstavitev Bezierjeve krivulje je

, , (5-62)

kjer je Bezierjeva ali Bernsteinova baza ali aproksimacijska funkcija

(5-63)

(5-64)

To je Bernsteinova osnovna funkcija reda.

riž. 5-26 Bezierjevi poligoni za kubične krivulje.

Tu je vrstni red definirajoče funkcije Bernsteinove baze - in s tem segmenta polinomske krivulje, za eno manjši od števila točk definirajočega mnogokotnika. Kot je prikazano na sl. 5-25 so oglišča Bezierjevega mnogokotnika oštevilčena od 0 do . Zato in.

Na sl. 5-27 prikazuje aproksimativne funkcije za različne pomene. Upoštevajte, da so funkcije simetrične. Vsaka funkcija ima vrstni red, na primer vse štiri funkcije na sl. 5-27b za kubične. Maksimum vsake funkcije je dosežen pri in je enak (5-14)

. (5-65)

riž. 5-27 Bezier/Bernsteinove utežne funkcije. (a) Trikotnik, ; (b) iz štirih točk, ; (c) iz petih točk, ; (d) iz šestih točk, .

Na primer za kubično krivuljo. Maksimum in je dosežen pri oz. in ima vrednosti

Slika 5-27b prikazuje ta primer.

Razmislite o enačbah (5-62) in (5-64) za prvo točko na krivulji, tj. pri

, ,

, .

,

prva točka krivulje sovpada s prvo točko poligona.

Podobno velja za zadnjo točko krivulje, tj

, ,

, .

in zadnja točka na Bezierjevi krivulji sovpada z zadnjo točko definirajočega poligona.

Oglejmo si Bezierjevo konstrukcijsko metodo na primeru.

Primer 5-7 Bezierjeva krivulja

Naj so podana oglišča Bezierovega mnogokotnika: , , in . Poiščite sedem točk, ki ležijo na Bezierjevi krivulji.

Upoštevajte enačbe (5-62) - (5-64):

,

.

V našem primeru, ker so to štiri oglišča. Od tukaj

,

,

Tabela 5-4 Koeficienti za Bezierovo krivuljo

riž. 5-28 Segment Bezierjeve krivulje, primer 5-7.

Vrednosti za različne pomene so podane v tabeli. 5-4.

Točke na krivulji:

,

.

Te točke so prikazane na definirajočem poligonu na sliki. 5-28.

Enačbo Bezierjeve krivulje lahko zapišemo v matrična oblika, tako kot enačbe za kubični zlepki in parabolična interpolacija (glej enačbi 5-27 in 5-44):

Tukaj in .

Posebej zanimive so matrične oblike za majhne vrednosti. Za poligon s štirimi točkami izgleda Bezierova krivulja

.

Če združimo koeficiente, dobimo

. (5-68)

Podobno, Bezierjeva krivulja četrtega reda, podana s poligonom iz petih točk:

. (5-69)

Delo ponuja splošno predstavitev:

,

,

. (5-70)

Matrica je spet tu . Posamezni člani matrike so:

.

Enačbo (5-70) lahko zapišemo v bolj priročni obliki

,

.

Enačbe (5-70) ali (5-71) so primernejše za izračun, ko velike vrednosti. Upoštevajte, da je pri vseh matrika simetrična glede na glavno diagonalo in spodnji desni kot je sestavljen iz ničel.

Za vsako posamezno Bezierovo krivuljo ni treba poznati tangentnih vektorjev na njenih koncih, če pa je treba ohraniti kontinuiteto ukrivljenosti in naklona na stičiščih krivulj, izračunati normale na površino za osvetlitev, izračunati lokalne ukrivljenosti, potem je potrebno poznati tako prvi kot drugi odvod Bezierjeve krivulje.

Iz enačbe (5-62) je prvi derivat Bezierjeve krivulje:

. (5-72)

Drugi derivat je:

. (5-73)

Formalno diferenciramo enačbo (5-63) in dobimo odvode baznih funkcij

. (5-74)

Podobno imajo drugi derivati ​​obliko:

. (5-75)

Na začetku in koncu Bezierjeve krivulje, tj. pri in je numerični izračun enačb (5-74) in (5-75) težak.

Drug način za izračun th derivata pri:

(5-76)

. (5-77)

Zato bodo prve izpeljanke na koncih

(5-78)

. (5-79)

To kaže, da so tangente na Bezierovo krivuljo v prvem in zadnje točke vzporedni z ustreznimi stranicami mnogokotnika. Podobno so druge izpeljanke na koncih:

Druge odvodnice na koncih so odvisne od dveh najbližjih stranic, torej od treh najbližjih oglišč. Na splošno je -ti odvod na začetni in končni točki odvisen od teh točk in najbližjih oglišč mnogokotnika.

Oglejmo si to podrobneje na primeru.

Primer 5-8 Izpeljanke Bezierjevih krivulj

Razmislite o Bezierjevem mnogokotniku s štirimi točkami, na primer, kot je prikazano na sl. 5-26 in 5-28. Spomnimo se predstavitve krivulje

Od tod prva izpeljanka

Spomnimo se primera 5-7 in neposredno razlikujemo bazne funkcije

Zamenjajmo:

Zamenjava daje

Zato smer tangente na začetku krivulje sovpada s prvo stranico mnogokotnika (glej sliko 5-28).

Na koncu ovinka in

Podobno daje zamenjava

in smer tangentnega vektorja na koncu krivulje sovpada z zadnjo stranjo poligona.

Za izračun derivatov vzdolž krivulje uporabljamo osnovne funkcije in enačbe (5-74) in (5-75):

,

,

.

Rezultate je enostavno izračunati za oba. Če nadomestimo v enačbo (5-72), dobimo prvi odvod na kateri koli točki krivulje. Na primer, ko imamo

Rezultat za točke , , , iz primera 5-7 je prikazan na sl. 5-29.

riž. 5-29 Bezierova krivulja in njeni derivati: ;

; .

,

,

,

.

Podobno imajo drugi derivati ​​obliko:

Enačba (5-73) daje

Ilustracija je prikazana tudi na sl.

,

5-29. Upoštevajte, da vektor od izhodišča do katere koli točke na vsaki od krivulj predstavlja smer in velikost vektorja radija in približno ukrivljenost na tej točki na krivulji.

Pogoj za kontinuiteto sosednjih Bezierjevih krivulj je formuliran zelo preprosto. Naj bo Bezierjeva stopenjska krivulja določena z oglišči in sosednja Bezierjeva stopenjska krivulja določena z oglišči. Potem je zveznost prvega odvoda v vezni točki izražena z relacijo

kje je skalar.

.

riž. 5-30 Zveznost prvega odvoda za kubične Bezierove krivulje.

.

Z uporabo enačb (5-78) in (5-79) dobimo

Iz kontinuitete krivulje sledi, da

Zato smeri tangent na stičišču sovpadajo, če so tri oglišča , , kolinearne, tj. mora ležati na črti med in .

Če vrednosti tangentnih vektorjev tudi sovpadajo, potem je središče odseka od do:

Oblikovati mora konveksni poligon ali ležati na ravni črti, da se ohrani kontinuiteta na stičišču.

riž. 5-31 Zveznost drugega odvoda za Bézierove krivulje četrte stopnje. Za kubične Bezierjeve krivulje ima ta pogoj obliko Nekaj ​​skic s svinčnikom na papirju bo to pokazalo to zahtevo znatno omejuje niz krivulj; Zato je v praksi, da se ohrani kontinuiteta drugih odvodov, polinomske krivulje več kot

,

visokega reda . Na sl. Slika 5-31 prikazuje primer kontinuitete drugih odvodov za dve pettočkovni Bezierjevi krivulji. Tukaj lahko uspešno uporabite tehniko iz dela. V mejnem primeru poligon konvergira v krivuljo. Dodatno fleksibilnost krivulje lahko dosežemo tudi tako, da Bezierovo krivuljo razdelimo na dve novi, tako da skupaj sovpadata z izvirno krivuljo. Barskyjevo delo je pokazalo, da je mogoče katero koli Bezierovo krivuljo razdeliti s poljubnim parametrom v območju . Najenostavnejši primer- to je srednja točka, tj. (cm.). Ko ga razdelite na sredino, dobite dva

posebne vrste

kubične Bezierjeve krivulje. Kubična Bezierjeva krivulja (glejte vaje 5-7) je podana kot

Dobljeno z enačenjem radijskih vektorjev in tangentnih vektorjev pri

Bikubične površine Koons zagotavljajo prilagodljivo in zmogljivo orodje za oblikovanje površin. Vendar je njihova praktična uporaba, tako kot pri kubičnih krivuljah zlepka, ovirana zaradi potrebe po podajanju natančnih, intuitivno neočitnih matematičnih informacij, kot so koordinate točk, tangentni vektorji in torzijski vektorji.

riž. 6-36 Nečetverokotni kosi. (a) peterokotna; (b) trikotne.

Težave, ki se pojavljajo, so prikazane na slikah 6-33-6-35. Večino teh težav je mogoče premagati z razširitvijo konceptov Bezierjevih krivulj na površine.

Kartezični ali tenzorski produkt Bézierove površine je podan kot

, (6-58)

kjer sta in sta Bernsteinovi bazični funkciji v parametričnih smereh in (glej enačbi 5-63 in 5-64). Zaradi priročnosti tukaj ponavljamo definicijo, podano prej v razdelku. 5-8

, (5-63)

,

. (6-64)

Tu so elementi oglišča definirajoče poligonalne mreže, kot je prikazano na sl. 6-37. Indeksa in sta za eno manjša od števila oglišč poliedra v smereh oz. Za štiristranske kose površin mora biti definirajoča poligonalna mreža topološko pravokotna, kar pomeni, da mora imeti enako število oglišč v vsaki "vrstici".

Spet, tako kot pri Bezierjevih krivuljah, ker mešalne funkcije uporabljajo Bernsteinovo osnovo, so znane številne lastnosti površine. Na primer:

Stopnja površine v vsaki parametrični smeri na enoto manjše število oglišča referenčnega poliedra v tej smeri.

riž. 6-37 Bezierova ploskev in oglišča karakterističnega poliedra.

riž. 6-38 Shema definirajoče poligonalne mreže za Bezierjevo površino.

Gladkost ploskve v vsaki parametrični smeri je za dve enoti manjša od števila oglišč definirajočega poliedra v tej smeri. Površina se prikaže v splošni pogled obliko definirajoče poligonalne mreže. Sovpadajo le kotne točke določajoče poligonalne mreže in površine.

Površina je vsebovana v konveksni lupini definirajoče poligonske mreže.

Površina ne kaže lastnosti dušenja sprememb. Ta lastnost je nedefinirana in neznana za površine dveh spremenljivk.

Površina je invariantna glede na afino transformacijo.

Vsaka mejna krivulja Bezierove ploskve je Bezierova krivulja. Zapomnimo si to dejstvo in razmislimo o definirajoči poligonalni mreži za bikubično Bezierjevo površino velikosti, ki je shematično prikazana na sl. 6-38. Preprosto je videti, da sta smer in velikost tangentnih vektorjev na kotnih točkah kosa nadzorovani s položajem sosednjih točk vzdolž stranic mreže. Namreč, tangentne vektorje v smereh v točki kontrolirajo oglišča poligonske mreže oz. Podobno oglišča poligonske mreže , , in nadzorujejo tangentne vektorje v kotnih točkah. Štiri notranja oglišča poligonalne mreže, , , in vplivajo na smer in velikost torzijskih vektorjev v kotnih točkah kosa površine. Posledično lahko uporabnik nadzoruje obliko kosa površine, ne da bi poznal specifične vrednosti tangentnih in torzijskih vektorjev.

Na sl. Slika 6-39 prikazuje več bikubičnih Bezierjevih površin in njihove poligonske mreže. Osnovna poligonska mreža ima velikost in središče okoli izhodišča z vogalnimi točkami na , . Komponenta v ogliščih vogalov je nič. Za vsa druga vozlišča je ta komponenta enaka pet. Osnovna poligonalna mreža in njena ustrezna Bezierjeva površina sta prikazani na sl. 6-39a. Na sl. Točka 6-39 je vrh levega kota in vrh desnega kota. Upoštevajte, da osrednja oglišča mreže osnovnega mnogokotnika tvorijo ploščat križ (prikazano zasenčeno). Posledično je središče nastale površine minimalno ukrivljeno, čeprav ni ravno.

Na sl. Slika 6-39b ponazarja učinek podvojitve magnitude tangentnega vektorja v točki v obeh parametričnih smereh in s premikanjem točk in . Torzijski vektor se ne spremeni. Opazimo povečanje ukrivljenosti mejnih krivulj, ki ustreza vrednostim parametrov in , ter ustrezno spremembo v notranjosti površine.

Na sl. Slika 6-39c prikazuje učinek spreminjanja smeri tangentnih vektorjev v točki v obeh parametričnih smereh in s premikanjem točk in . Opazimo spremembo predznaka ukrivljenosti mejne krivulje v bližini točke in oblike notranjega dela površine v primerjavi z osnovno površino.

Na sl. Slika 6-39d ponazarja rezultat podvojitve magnitude torzijskega vektorja v točki brez spreminjanja njegove smeri. V tem primeru se premakne samo točka. Učinek te spremembe je subtilen, a vseeno pomemben za oblikovanje. Previdna primerjava z osnovno površino na sl. 6-39a to kaže parametrične črte blizu točke imajo večjo ukrivljenost. Ta učinek sega približno do središča površine.

V matrični obliki je kartezični produkt Bézierove površine podan z izrazom

,

,

,

matrike pa so podane z enačbo (5-70) ali (5-71).

riž. 6-39 Bikubične Bezierjeve površine. (a) glavna površina; (b) učinek spreminjanja velikosti obeh tangentnih vektorjev v ; (c) učinek spremembe smeri tangentnega vektorja v ; (d) učinek spreminjanja velikosti torzijskega vektorja v .

Za poseben primer bikubične Bezierjeve površine velikosti se enačba (6-59) zmanjša na

. (6-60)

Ni nujno, da je Bezierjeva površina kvadratna. Za velikost mreže postane enačba (6-59).

. (6-61)

Bezierjeva površina velikosti je sestavljena iz polinomskih krivulj četrte stopnje v parametrični smeri in kvadratnih polinomskih krivulj v smeri. Primer takšne Bezierjeve površine je prikazan na sl. 6-40. IN v tem primeru, kot je prikazano na sl. 6-40b, spreminjanje osrednjega oglišča stranice mreže s petimi oglišči ne vpliva na tangentne vektorje v kotnih točkah.

riž. 6-40 Bezierjeva velikost površine. (a) glavna površina; (b) učinek spremembe osrednjega oglišča mejne poličnije s petimi oglišči.

Izpeljane Bezierjeve površine dobimo s formalno diferenciacijo enačbe (6-58) ali (6-59). Če uporabimo enačbo (6-58), bosta prvi in ​​drugi parametrični derivat

, (6-62)

, (6-63)

, (6-64)

, (6-65)

, (6-66)

kjer praštevilo označuje diferenciacijo glede na parametrično spremenljivko. Izpeljanke Bernsteinovih baznih funkcij , , in so podane v enačbah (5-74) in (5-75).

Z lahkoto je najti razmerje med bikubičnimi Bezierjevimi in Koonsovimi površinami. Z enačenjem enačb (6-52) in (6-59) dobimo

kjer je podana z enačbo (5-76) in - z enačbo (5-70). Zato je geometrijska matrika bikubične Koonsove ploskve definirana v smislu poligonalne mreže Bezierjeve ploskve, kot sledi

. (6-67)

Preiskava spodnje desne podmatrike velikosti v enačbi (6-67) potrjuje, da štiri osrednje točke definirajoče poligonalne mreže vplivajo na torzijo v kotnih točkah kosa bikubične Bezierjeve ploskve. Vendar pa torzijo v kotnih točkah ne nadzirajo samo osrednja oglišča, temveč tudi sosednji tangentni vektorji. Dejansko je torzija na kotni točki nadzorovana z obliko neravninskega štirikotnika, ki ga tvorijo kotna točka, dve sosednji mejni točki in sosednja središčna točka.

Iz enačb (6-62)-(6-64) sledi, da

. (6-68)

Podobno je inverzna zveza med matricami in , ki izražajo oglišča Bezierjeve poligonalne mreže v smislu parametrov Koonsove bikubične površine, enaka

. (6-69)

Koncept Bezierjeve površine je podrobneje prikazan v naslednjem primeru.

Primer 6-14 Bezierjeva površina

Za tisto, prikazano na sl. 6-39a Bezierjeve ploskve za vrednosti parametrov, določite koordinate točke na ploskvi in ​​prve odvodnice v in smeri. Poiščite tudi koordinate točke in odvode za modificirano površino, prikazano na sl. 6-39d. Primerjajte rezultate. Oglišča poliedra Bezierjeve ploskve so:. Nov pomen produkta: in sta še vedno pravokotna, vendar sta njuni velikosti in smeri različni. Ti rezultati kažejo, da ima torzijski vektor na eni kotni točki subtilen, a pomemben učinek na obliko celotne površine.

Zgornja razprava o Bezierjevih površinah je govorila o definiciji in značilnostih enega kosa površine. Da bi dobili bolj zapletene površine, morate združiti več kosov Bezierjeve površine. Podrobna razprava o tem vprašanju presega obseg te knjige. Zainteresiranega bralca napotimo na in. Težave, ki nastanejo pri kombiniranju kosov Bezierjeve površine ob zagotavljanju gladkosti vzdolž strani, ki se dotikajo, so prikazane na sl. 6-41 z uporabo primera združevanja dveh kosov bikubične Bezierjeve površine vzdolž ene strani.

Za zagotovitev neprekinjenosti oziroma gladkosti vzdolž meje je potrebno, da dve mejni krivulji sovpadata in s tem dve mejni lomljeni črti vzdolž roba ploskve. Da bi zagotovili kontinuiteto vektorjev naklona ali tangente ali gladkost vzdolž meje kosa, mora biti smer normale površine vzdolž mejne krivulje enaka za oba kosa. Če želite to narediti, lahko uporabite dva pogoja. Prvi zahteva, da so štirje segmenti poligonske mreže, ki se srečajo in sekajo mejo, kolinearni, kot je prikazano s poudarjenimi črtami na sliki 1. 6-41a. Drugi, manj strogi pogoj zahteva, da so samo trije robovi poligonske mreže, ki se srečajo na končnih točkah mejne krivulje, koplanarni, kot je prikazano s poudarjenimi črtami na sliki 2. 6-41b.

Preprosta in jasna izvedba slavnih Bezierjevih krivulj v C#.

Uvod

Bezierjeve krivulje so najbolj temeljne krivulje, ki se uporabljajo predvsem v računalniška grafika in obdelava slik. Te krivulje se uporabljajo predvsem pri interpolaciji, aproksimaciji, risanju krivulj in risbah predmetov. Ta članek na zelo preprost in jasen način prikazuje, kako lahko zgradite in uporabite te krivulje.

Kratka informacija

Bezierjeve krivulje so parametrične krivulje, ki so zelo prilagodljive in gladke ter dobro delujejo pri mnogih nalogah. Ime so dobili po Pierru Bézierju, francoski matematik in inženir, ki je razvil ta metoda računalniško risanje konec leta 1960 med delom pri proizvajalcu avtomobilov Renault. Rečeno je, da je istočasno prišlo do enakega razvoja med Fordovo raziskavo. Še vedno ni jasno, kdo jih je prvi ustvaril.

Članek se osredotoča predvsem na interpolacijo in risanje krivulj. Pri interpolaciji morate najti neznane tokove z uporabo znane vrednosti. Niz diskretnih točk je mogoče predstaviti kot neprekinjeno strukturo, kar ima za posledico strogo definirano krivuljo za manjkajoče točke. Krivulja se inicializira z določenimi osnovnimi točkami in poskuša ustvariti nove točke, ki približajo (ali interpolirajo) stare vrednosti.

Algoritem za izdelavo Bezierove krivulje

Upoštevajte n +1 točk P 0 ,…,P n in povežite točke prekinjena črta, v nadaljevanju kontrolno območje.

Glede na točke P i, i = 0,...,n, je naša naloga določiti krivuljo g (t) za vse vrednosti t? . Ideja je prikazana spodaj:

O glavni algoritem

Tu je cilj najti točke na sredini med dvema sosednjima točkama in to ponavljati, dokler ne zmanjka vseh ponovitev. Nove vrednosti točk bodo ustvarile krivuljo. Znana enačba Bezier je natančna formulacija te ideje. Tukaj je algoritem:

1. korak: izberite vrednost t? . Ta vrednost se v vseh drugih korakih ne spremeni.

2. korak: Nastavite P i (t) = P i, za i = 0,...,n.

3. korak: Za j = 0,...,n nastavite za i = j,...,n.

4. korak: g(t) = Pn(t)

Zasebno in splošnih primerih

Tukaj bodo podane formule za splošne in posebne primere, uporabne v določenih aplikacijah. Koda v članku ne prikazuje nobenega od teh, vendar uporablja splošno formulo. Začnimo s splošno formulo:

Zaradi preprostosti in dogovora, uporabljenega v tem članku in kodi, je bolje, da to formulo predstavite takole:

Ta enačba je samo formulacija zgornjega algoritma (iteracija sredinske točke). Pomembno je, da je celoten algoritem mogoče zreducirati na formulo, neposredna implementacija pa lahko da pravilne rezultate. Tukaj n označuje število točk in P označuje same točke. Faktorski koeficienti točk se imenujejo Bernsteinove bazične funkcije, poimenovane po njihovem ustvarjalcu.

Tukaj so posebni primeri:

Linearni Bezier:

Kvadratni Bezier:

Bezier tretja stopnja:

Razlaga in uporaba kode

To je funkcija, ki opravi vse delo. Je zelo kratek in zelo preprost. Ker imamo opravka samo z 2D krivuljami, imajo točke le koordinate X in Y. Funkcija izračunava Bezierjeve točke.

Javni void Bezier2D(double b, int cpts, double p)
{
int npts = (b.Dolžina) / 2;
int icount, jcount;
dvojni korak, t;

// Izračunajte točke na krivulji

Icount = 0;
t = 0;
korak = (dvojni)1,0 / (cpts - 1);

Za (int i1 = 0; i1 != cpts; i1++)
{
če ((1,0 - t)< 5e-6)
t = 1,0;

Jcount = 0;
p = 0,0;
p = 0,0;
za (int i = 0; i != npts; i++)
{
dvojna osnova = Bernstein(npts - 1, i, t);
p += osnova * b;
p += osnova * b;
jcount = jcount +2;
}

Icount += 2;
t += korak;
}
}

Preostale funkcije so le pomožne funkcije, vključene v faktorske izračune in izračuni baznih funkcij, ki so precej trivialni . Za pravilno uporabo te funkcije posredujte mu nabor točk v obliki: XYXYXYXYXYXYXYXYXY.... koordinate in koliko točk morate izračunati na krivulji. Funkcija bo napolnila matriko p s točkami trajektorije.

Zaradi omejitev faktorskih izračunov koda izračuna samo krivulje do 32 točk. Bolj zapletene zasnove so običajno predstavljene s kombinacijo podatkov o krivuljah (kot v orodju poti Adobe Photoshop, Illustrator in Flash).

Čeprav ima GDI (Graphics Device Interface) vgrajeno funkcijo za izračun Bezierjeve krivulje, za usposabljanje ni priporočljivo uporabljati vgrajenih knjižnic. GDI ne bo vedno opravil dela namesto vas! Nekje, nekoč ga boste morda morali implementirati in do takrat bi morali imeti približno predstavo o tem, kako te krivulje delujejo.

Vsi vemo, kaj je krivulja. Tukaj je nekaj primerov.

Bezierjeve krivulje so zelo enostavne za uporabo in lahko opišejo številne oblike. Bezierjeve krivulje se pogosto uporabljajo za predstavitev znakov v pisavah in oblikah dizajnov. vozila. Bezierjeve krivulje se uporabljajo tudi v urejevalnikih vektorske grafike za predstavitev različnih krivulj in v orodjih za 3D animacijo za predstavitev animacijskih krivulj.

V igrah so Bezierjeve krivulje včasih uporabne za opisovanje poti: dirkalne poti na stezi v dirkalni igri ali črt v igrah risanja črt, kot je npr. Kontrola letenja, ali zankasta pot metulja, ki lebdi v zraku, ki živi v svetu RPG.

Bezierjeve krivulje so tako priljubljene, ker so matematične opise zelo kompakten, intuitiven in eleganten. So enostavni za izračun, enostavni za uporabo v več visoke dimenzije(3D in več) in jih je mogoče povezati skupaj, da predstavljajo poljubno obliko, ki si jo zamislite.

V tej vadnici vam bom dal navodila, ki jih potrebujete za implementacijo algoritmov, da boste lahko uporabljali Bezierjeve krivulje v svojih igrah.

Matematični opis

Začnimo z matematiko. Matematično lahko Bezierovo krivuljo opišemo z funkcijo. Funkcija sprejme parameter. Vrednost funkcije je točka na krivulji; odvisno je od parametra in od niza klicanih točk nadzorne točke. Prva in zadnja kontrolna točka sta konca krivulje. Običajno krivulja ne poteka skozi druge kontrolne točke.

Vrednost se lahko giblje od 0 do 1. Vrednost 0 ustreza izhodišče krivulja, vrednost 1 ustreza končni točki krivulje. Vrednosti vmes ustrezajo preostalim točkam na krivulji.

Tukaj je primer najpreprostejše vrste Bezierjeve krivulje, segmenta:

Tukaj je skrajšani zapis za dve enačbi, ki dajeta ločeni koordinati:

Točke so kontrolne točke. ko , desna stran enačba je enaka prvi kontrolni točki - začetku segmenta. Ko , dobimo točko , je druga kontrolna točka konec segmenta.

Za bolj zanimive oblike potrebujemo več kontrolnih točk. Število kontrolnih točk določa stopnja ukrivljen. Dve kontrolni točki sta potrebni za linearne (prve stopnje) krivulje, kot je odsek črte zgoraj. Za drugo stopnjo, oz kvadratni krivulje, potrebujemo tri kontrolne točke.

Tukaj je formula:

Kubične krivulje(ali krivulje tretje stopnje) se najpogosteje uporabljajo, zato bomo o njih razpravljali v tem vodniku kubične krivulje. Za izdelavo potrebujejo štiri kontrolne točke in morda ste že dobro seznanjeni z njihovo uporabo v vektorskih grafičnih paketih (da, isti krogi, ki se uporabljajo za spreminjanje oblike krivulj v Freehand ali Inkscape, so naše kontrolne točke).

Rumene črte segajo v isto smer kot tangente na koncih krivulje. Bolj kot so ti rumeni segmenti oddaljeni, bolj je krivulja "raztegnjena" v smeri tangent.

Formula za kubične Bezierjeve krivulje:

Malo je verjetno, da boste potrebovali višje stopnje krivulje. Če je tako, potem je formula preprosta, vendar zahteva nekaj znanja binomski koeficienti. Podrobnosti najdete v enem od virov na koncu članka.

Primeri

V geometriji vedno bo več težav kot bi si sprva mislili, kar lahko povzroči dolgotrajno iskanje napak.

Tukaj so pravilne 2D Bezierjeve krivulje:

Vse končne točke na enaki razdalji drug od drugega. 1. Krivulja brez ovinka, gube ali zanke. 2. Krivulja s pregibom, brez gub ali zank. 3. Krivulja z gubo. 4. Krivulja z zanko. 5. Ravna črta. (Na prevojni točki krivulja spremeni smer pregiba)

Degeneriran primer 5 je najtežje. Na voljo so lahko naslednje možnosti:

  • brez prekrivanja
  • krivulja se dvakrat zlomi na enem ali obeh koncih
  • krivulja se nekje med koncema trikrat trikrat upogne

Obstaja šesti primer, ko vse štiri kontrolne točke sovpadajo: posledično se krivulja degenerira v eno točko. Upoštevajte, da se krivulja ne degenerira v točko, če se ujemajo samo končne točke - vse štiri kontrolne točke se morajo ujemati. Tisti, ki jih zanimajo tehnične podrobnosti, lahko preberejo Geometric Characterization of Parametric Cubic Curves (1,6 MB PDF) avtorjev Stone in De Rose. Članek Prevojne točke kubičnega Bezierja pojasnjuje, kako izračunati prevojne točke, ponuja pa tudi interaktivne programčke Java za vizualno ponazoritev.

V 3D zagotavljajo zanke in zlomi manj težav, saj se pojavijo le v primeru, ko vse točke ležijo v isti ravnini. V 3D lahko vedno spremenite smer črte (zlasti za primere, kot so 2, 4 in 5).

Pri izvajanju algoritmov Bezierjeve krivulje skrbno premislite o primernosti uporabe te vrste krivulje za določen primer in vedno preverite, ali algoritem deluje pravilno. Bodite še posebej previdni pri kontrolnih točkah - če sovpadajo, lahko pride do normalizacije situacije ničelni vektor, kar lahko privede do sesutja programa.

Izvedba

Matematično formulo je enostavno prevesti v kodo. Spodaj je implementacija algoritma, v kateri je že narejenih nekaj optimizacije s shranjevanjem in ponovno uporabo vmesni rezultati.

Koda je v C#, vendar njeno prevajanje v Javo, C++ in večino drugih jezikov ne bi smelo predstavljati težav.

(Naslednje funkcije bodo delovale tudi v 2D, če Vector3 zamenjate z Vector2.)

Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) ( float u = 1 – t; float tt = t* t; float uu = u* u; float uuu = uu * u; float ttt = tt * t; p = uuu * p0; // prvi člen p += 3 * u * p1; // četrti člen p)

Risanje Bezierovih krivulj

Zdaj imamo način za izračun točke na Bezierjevi krivulji, potrebujemo način za risanje krivulje.

Za slike je najpreprostejši pristop uporaba iteracije za izračun zahtevanih točk:

za (int i = 0; i<= SEGMENT_COUNT; ++ i) { t = i / (float ) SEGMENT_COUNT; Vector3 pixel = CalculateBezierPoint(t, p0, p1, p2, p3) ; DrawPixel(pixel) ; //predpostavimo, da ta funkcija lahko obravnava Vector3 }

Ta pristop ima naslednje težave:

Naprednejši algoritmi uporabljajo prilagodljivo ojačenje za premagovanje teh težav. Antialiasing krivulje bo na splošno dal odličen rezultat, tako da bo krivulja zelo gladka in jasna. Dober vir za risanje krivulj (in kup drugih uporabnih tem) je računalniška grafika in računalniško modeliranje Davida Salomona.

Preprostejša alternativa je risanje črt namesto slikovnih pik. Ta metoda je primernejša tudi za risanje krivulj z uporabo grafične strojne opreme.

q0 = Izračunaj BezierPoint(0, p0, p1, p2, p3) ;<= SEGMENT_COUNT; ++ i) { t = 1 / (float ) SEGMENT_COUNT; q1 = CalculateBezierPoint(t, p0, p1, p2, p3) ; DrawLine(q0, q1) ; q0 = q1; }

za (int i = 1; i

Ker nam zdaj ni treba skrbeti za manjkajoče slikovne pike, lahko izberemo večji korak in zmanjšamo obremenitev upodabljanja. Še vedno pa je težko pravilno izbrati prirastek.

Obstaja še en algoritem, ki uporablja rekurzivne particije. Običajno proizvede manj točk upodabljanja za enako raven natančnosti kot prejšnji algoritem. Vendar pa ne obravnava pravilno vseh krivulj z zavoji ali zankami in se ga ne sme uporabljati, če je verjetno, da se bodo takšni primeri zgodili.

Tukaj je algoritem:

1. Spodnja slika prikazuje delujoč primer. Začnimo z dvema končnima točkama in točko med njima. Preverimo kot med dvema segmentoma. 2. Dovolj je majhen, da bomo mednje dodali točko upodabljanja.Nato naredimo enako za levo stran krivulje. 3. V tem primeru je kot dovolj velik, da ne dodajamo točke in delimo naprej. Enako naredimo za desno stran krivulje. 4. V tem primeru je kot dovolj majhen, zato dodamo nove točke za risanje in razvoj segmenta. 5. IN Enako naredimo za obe polovici v prejšnjem koraku. 6. Končni niz točk se uporabi za risanje krivulje.

Spodaj je koda za rekurzivni algoritem. Trik je v tem, da točke vstavite na pravo mesto na seznamu, tako da ostanejo v pravilnem vrstnem redu za risanje. Preverimo pikčasti produkt normaliziranih segmentov, namesto da neposredno preverimo kot. Zato se > uporablja za primerjavo namesto< как если бы мы проверяли углы напрямую.

//vrne število dodanih točk. int FindDrawingPoints(float t0, float t1, int insertionIndex, List pointList) ( tMid = (t0 + t1) / 2 ; p0 = bezierCurve(t0) ; p1 = bezierCurve(t1) ; if (p0 – p1. sqrMagnitude< MINIMUM_SQR_DISTANCE) { return 0 ; } pMid = bezierCurve(tMid) ; leftDirection = (p0 – pMid) . Normalised ; rightDirection = (p1 – mMid) . Normalised ; if (Dot(leftDirection, rightDirection) >prag) ( int pointsAddedCount = 0 ; pointsAdded += FindDrawingPoints(t0, tMid, insertionIndex, pointList) pointList. insert (insertionIndex + pointsAdded, pMid) ; pointsAdded++; pointsAdded += FindDrawingPoints(tMid, t1, insertionIndex + pointsAdded, pointList) ; vrni točkeDodano) return 0;

)

Naslednja funkcija prikazuje rekurzivni klic funkcije:

void FindPoints() ( List pointList = new List() ; p0 = bezierCurve(0) ; p1 = bezierCurve(1) ; pointList. Add (p0) ; pointList. Add (p1) ; int pointsAdded = FindPoints(0, 1, 1 , seznam točk) ; assert(pointsAdded + 2 == pointsList. Count ) ; //preverjanje razumnosti )

  • Nekaj ​​opomb:
  • Preverjanje najmanjše razdalje je potrebno za preprečitev težav z normalizacijo zelo kratkih vektorjev. Prav tako preprečuje nepotrebne izračune.
  • Mejna vrednost je presenetljivo blizu -1. Dobro mesto za začetek je -0,99.

Algoritem ne deluje zelo dobro za krivulje, ki vsebujejo pregibe ali zanke. Spodaj je primer, kaj se lahko zgodi, če ga uporabite za krivuljo z ovinkom. Primer, v katerem bo algoritem dal slab rezultat. V tem primeru kot presega sprejemljivo mejo, zato ne bo prišlo do razcepov.

Rezultat ni zelo podoben želeni krivulji.

Lepljenje krivulj skupaj: Bezierjeve poti

  • Ko želimo izrisati kompleksno krivuljo, imamo dve možnosti:
  • uporabite eno Bezierovo krivuljo z visoko stopnjo;

razdelite krivuljo na manjše segmente in za vsak segment uporabite Bezierove krivulje nizke stopnje. Zadnja vrsta krivulje se imenujenačine Bezier. Bezierjeve poti so na splošno enostavnejše in učinkovitejše za uporabo kot krivulje visoka stopnja

Tukaj prikazana izvedba je le ena od mnogih možnih. Definirali bomo razred, ki ustvari seznam kontrolnih točk Bezierjeve krivulje, ki sestavljajo Bezierjevo pot. Ker so segmenti povezani od konca do konca, sta začetna in končna točka sosednjih krivulj enaki, tako da se lahko izognemo podvojenim točkam. Slika prikazuje primer Bezierjeve poti, sestavljene iz štirih Bezierjevih krivulj. V tem primeru seznam vsebuje 13 točk, kot prikazuje slika na levi.

Če se odločimo za konstrukcijo krivulje s segmenti, potem dobra odločitev bo predpomnil končne točke segmentov in jih posodobil, ko se krivulja spremeni. Naslednji algoritem izračuna vse točke risanja (končne točke segmentov).

class BezierPath ( List controlPoints; Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) ( ... ) List GetDrawingPoints() ( List drawingPoints = new List() ; for (int i = 0 ; i< controlPoints. Count - 3 ; i+= 3 ) { Vector3 p0 = controlPoints[ i] ; Vector3 p1 = controlPoints[ i + 1 ] ; Vector3 p2 = controlPoints[ i + 2 ] ; Vector3 p3 = controlPoints[ i + 3 ] ; if (i == 0 ) //Naredi samo to za prva končna točka. //Ko je i != 0, to sovpada s koncem //točka prejšnjega segmenta( drawingPoints. Add (CalculateBezierPoint(0 , p0, p1, p2, p3) ) ; ) for (int j = 1 ; j<= SEGMENTS_PER_CURVE; j++ ) { float t = j / (float ) SEGMENTS_PER_CURVE; drawingPoints. Add (CalculateBezierPoint(t, p0, p1, p2, p3) ) ; } } return drawingPoints; } }

Ta rekurzivni algoritem je enostavno prilagojen za pridobivanje vmesnih točk. Primer najdete v kodi, priloženi članku.

Pri izvajanju Bezierjevih poti si lahko močno olajšate življenje z naslednjim:

  • Omogoči načine odpravljanja napak za risanje kontrolnih točk, Bezierjevih končnih točk, risalnih točk in tangent.
  • Prikažite število točk upodabljanja in kontrolnih točk: zahvaljujoč temu lahko vedno preverite, koliko točk ustvari algoritem, in pravilnost te številke.

In končno – Bezierjeve krivulje so zelo kul, vendar jih ne bi smeli uporabljati povsod, še posebej za predstavljanje kratkih, skoraj ravnih črt.

  • Večina motorjev 3D zahteva uporabo kratkih ravnih črt za upodabljanje krivulj, zato morate biti jasni glede vrednosti izvajanja upodabljanja Bezierjeve krivulje.
  • Ko gibanje nadzoruje fizika, nenadnih sprememb hitrosti in smeri praktično ni. Predmeti se običajno premikajo s spreminjanjem sile, ki deluje na predmet, in zaradi tega se njihova hitrost ne more spremeniti v trenutku. Na ta način se vsak premik samodejno zgladi: kateri koli predmet, ki sledi vzdolž povezanih ravnih črt, bo samodejno sledil zglajeni poti - Bezierjeve krivulje niso potrebne.

Prenos

  • Bezierjeve krivulje (64 KB, projekt Unity 3D, stisnjeno)
  • BezierPath.cs (datoteka izvorne kode C#)

Članek je prevod, povezava do vira - Bezier Curves for your Games: A Tutorial.
Če opazite kakršne koli netočnosti v prevodu, vas prosimo, da to sporočite s pismom na naslov, ki je naveden na dnu strani.

B-krivulja radij-vektorja

    Popravimo t. Predpostavimo torej, da obstaja samo eden takšen kje

    Za zgoraj definiran indeks, če izračunamo edino neničelno vrednost nenormaliziranega zlepka B prve ravni (m=1):

    Spomnimo, kaj je bilo izbrano v prvem koraku, tako da Še več, zaradi pogoja, imenovalca in zaradi pogoja imamo Zato za indeks, ki je zunaj nabora, vrednost ni izračunana.

    Z uporabo Cox-de Boerjevih razmerij izračunamo vse neničelne neničelne zlepke th reda pri :


    zlasti

    (6.6)

    kjer Z vstavitvijo (6.6) dobimo

    Lema 6.5. Obstaja razmerje:

  1. Za vsakega izračunamo normalizirane zlepke po formuli (hkrati).

  2. Na koncu izračunamo po formuli

De Boerjev algoritem za izračun vektorja radija B-krivulje

Izrek 6.4. Vektor polmera r(t) B-krivulje:

se lahko izračuna z naslednjim algoritmom:

Ta algoritem je ponazorjen z naslednjim diagramom ( ):

Površine, določene s kontrolnimi točkami in matricami teže

Bezierjeve površine

Opredelitev 6.2.1. Naj bo podanih (m +1) * (n+1) točk v prostoru, ki tvorijo pravokotno matriko (Bézierjevo mrežo):

Bezierjev površinski red m * n, se ustrezna mreža imenuje površina

(6.7)

kjer je E operater premika naprej pri prvem indeksu, F je operater premika naprej pri drugem indeksu:

Operatorja E in F očitno komutirata drug z drugim: torej je formula (6.7) konsistentna.

Opredelitev 6.2.2. Racionalna Bezierjeva površina, zgrajena iz točk z utežmi, je definirana na naslednji način:

(6.8)

Formula (6.8) pomeni, da zgradimo Bezierovo površino točko za točko in nato uporabimo transformacijo

Problem 6.2.1. Vizualno preučite vpliv kontrolnih točk in njihovih uteži na racionalno Bezierjevo ploskev s spreminjanjem začetnih podatkovnih točk (kontrolne točke) in (njihove uteži) v naslednjem programu. Utežna matrika vsebuje dvodimenzionalne vektorje, vendar je uporabljena le njihova prva komponenta. Druga komponenta je fiksna. To je posledica nezmožnosti Mathematice, da uporabi Bezierjevo funkcijo za matrike iz skalarjev.

Primer 6.2.1. Racionalna Bezierjeva površina z možnostjo neposrednega nadzora uteži z uporabo drsnikov.

In: = DynamicModule [ (pts, a, w0, pw, w, g, f, w6, w7, wl0, wll, i, j, out, ins, u, v, n, pts0), točke = ((( 0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 3, 0)), ((1, 0, 0), (1, 1, 1), ( 1, 2, 1), (1, 3, 0)), ((2, 0, 0), (2, 1, 1), (2, 2, 1), (2, 3, 0)), ((3, 0, 0), (3, 1, 0), (3, 2, 0) , (3, 3, 0))); pts0 = Splošči;


n = dolžina;

Vrstica [ (Manipuliraj ], (i, 1, 4), (j, 1, 4)]; pw = tabela ] točke [ ], (i, 1, 4) , ( j, 1, 4) ]; g = BezierFunction; f = BezierFunction; Show[(Graphics3D[(PointSize, Red, Map, Green, pts0[[#]] + (0.01, 0.04, 0.04)] & /@ Range[n])], Graphics3D[( Siva, črtkana, črta, črta])], ParametrioPlot3D / g , (u, 0, 1), (v, 0, 1), PlotStyle -> FaceForm ] )], Stolpec[(Control[((ins, Green, "Notranja barva"), zelena)], nadzor [((zunaj, rdeča, "zunanja barva"), rdeča)]), desno], ((w5, 10), 1, 100), ((w6, 10) , 1, 100), ((w9, 10), 1, 100), ((wl0, 10), 1, 100)] MatrixForm ) , " " ], Inicializacija: -> (točke = (((0, 0) , 0), (0, 1, 0), (0, 2, 0), (0, 3, 0)), ((1, 0, 0), (1, 1, 1), (1, 2) , 1), (1, 3, 0)), ((2, 0, 0), (2, 1, 1), (2, 2, 1), (2, 3, 0)), ((3 , 0, 0), (3, 1, 0), (3, 2, 0), (3, 3, 0))); n = Dolžina)]

Geometrijski pomen Bezierove ploskve

Bezierjevo površino je mogoče dobiti na naslednji način:

(6.9)

(6.10)

V tem primeru je ustrezen operator prehoda od referenčne točke, vzete na krivulji, do naslednje referenčne točke, vzete na krivulji v smislu vozlišč mreže pij, opisan z operatorjem premika F z drugim indeksom. torej kjer sta m in n število korakov vzdolž prvega oziroma drugega indeksa, začenši od kotne točke Bezierjeve mreže, 00 je indeks te kotne točke, od katere začnemo oblikovati vsa druga vozlišča mreže z operaterji premika E in F. Imamo Tukaj so označeni skozi štirikotne bezierjeve plošče, zgrajeno iz točk p ij, vzetih kot

kotne točke

, podobno formuli (6.9). lahko dobite z naslednjim algoritmom:

Dobljena točka bo točka s parametri na racionalni Bezierjevi ploskvi, izdelani z uporabo ne da bi spremenil svojo obliko. S to delitvijo dobimo dve Bezierjevi ploskvi (ki skupaj sestavljata prvotno ploskev) in ustrezni dve matriki Bezierjevih kontrolnih točk, od katerih ima vsaka enak vrstni red kot prvotna matrika: in Nato mora biti vsaka od nastalih dveh Bezierjevih ploskev razdeljen na parametrični točki (z uporabo delitve Bezierjevih krivulj, zgrajenih iz vrstic ustreznih matrik). Kot rezultat boste dobili štiri Bezierjeve površine in ustrezne štiri matrike kontrolnih točk: in Te štiri Bezierjeve ploskve bodo ležale na prvotni Bezierjevi ploskvi, jo razdelile na štiri dele in skupaj sestavljale izvirno ploskev.

Nova omrežja nadzornih točk in jih pridobi iz prvotnega omrežja naslednje formule, podobno formulam (5.26):




Vam je bil članek všeč? Delite s prijatelji!