10.08.2013 Views

Algoritmus pro ořezávání 2D polygonů

Algoritmus pro ořezávání 2D polygonů

Algoritmus pro ořezávání 2D polygonů

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Algoritmy <strong>pro</strong> <strong>ořezávání</strong><br />

<strong>2D</strong> <strong>polygonů</strong>


Využití <strong>ořezávání</strong> v praxi<br />

odstranění částí<br />

obrazu<br />

nacházejících se<br />

mimo zobrazitelnou<br />

oblast výstupního<br />

zařízení


Využití <strong>ořezávání</strong> v praxi<br />

Vyplňování 3D objektů<br />

Vytvoření vysoce kvalitního povrchu<br />

zobrazovaných objektů pomocí<br />

zkoumání odrazů, odlesků a lomů<br />

paprsků světla<br />

Přidělování objektů scény<br />

multi<strong>pro</strong>cesorovým systémům


Polygon<br />

Uspořádaný<br />

seznam bodů<br />

/vrcholů/, kde<br />

první a poslední<br />

bod je identický


<strong>Algoritmus</strong><br />

Cohen-Sutherland<br />

<strong>Algoritmus</strong> slouží k<br />

<strong>ořezávání</strong> čar vůči<br />

obdélníku.<br />

Hlavní výhodou algoritmu je<br />

jednoduché a rychlé<br />

zakódování jednotlivých<br />

případů pozice úsečky vůči<br />

obdélníku.<br />

Po zakódování pozic<br />

můžeme snadno vynechat<br />

úsečky, které leží zcela<br />

mimo nebo uvnitř<br />

obdélníku.


<strong>Algoritmus</strong><br />

Cohen-Sutherland<br />

Hodnota 1 v kódu znamená hodnotu true true a<br />

kód je tvořen podle následujících pravidel (bity<br />

počítáme zprava):<br />

– bit 0 - bod bod je vlevo od obdélníka obdélníka<br />

– bit 1 - bod bod je vpravo od obdélníka<br />

– bit 2 - bod bod je pod obdélníkem<br />

– bit 3 - bod je nad obdélníkem<br />

Po zakódování mohou nastat následující<br />

případy:<br />

– kód oblasti je roven roven nule <strong>pro</strong> <strong>pro</strong> oba oba koncové koncové body body<br />

úsečky - přímka leží leží uvnitř oblasti,<br />

– kódy obou koncových bodů mají stejný bit bit<br />

nenulový nenulový - přímka přímka leží mimo obdélník,<br />

– u ostatních možností přímka <strong>pro</strong>chází hranou<br />

obdélníka.


Průsečíky s ořezávacím<br />

oknem<br />

Výpočet průsečíku s příslušnou hranou obdélníka se spočítá následovně:<br />

– je-li bod vlevo: (xmin, k*(xmin-x1)+y1)<br />

– je-li bod vpravo: (xmax,k*(x1-xmax)+y1)<br />

– je-li bod nad: (q*(y1-ymax)+x1,ymax)<br />

– je-li bod pod: (q*(ymin-y1)+x1,ymin)<br />

kde<br />

k = (y2-y1)/(x2-x1) <strong>pro</strong> x1 != X2, X2,<br />

q = (x2-x1)/(y2-y1) <strong>pro</strong> y1 != y2


<strong>Algoritmus</strong><br />

Cohen-Sutherland


<strong>Algoritmus</strong> Cyrus-Beck<br />

Tento algoritmus slouží k<br />

<strong>ořezávání</strong> úseček vůči<br />

konvexnímu n-úhelníku.<br />

<strong>Algoritmus</strong> je založen na<br />

znalosti normál hran<br />

konvexního n-úhelníka,<br />

podle kterého úsečky<br />

ořezáváme.<br />

Přímka může <strong>pro</strong>tínat tento<br />

n-úhelník nejvýše ve dvou<br />

bodech, pokud pomineme<br />

speciální případ, kdy úsečka<br />

leží na některé hraně.


Cyrus-Beck algoritmus


<strong>Algoritmus</strong><br />

Weiler-Atherton<br />

<strong>Algoritmus</strong> slouží k <strong>ořezávání</strong><br />

obecného nekonvexních n-<br />

úhelníku jiným obecným<br />

nekonvexním n-úhelníkem<br />

Oba n-úhelníky mohou<br />

obsahovat i díry.<br />

Po oříznutí nám může<br />

vzniknout i několik<br />

samostatných n-úhelníků.


Weiler-Atherton


<strong>Algoritmus</strong><br />

Greiner - Hormannův<br />

Günther Greiner<br />

Kai Hormann<br />

Friedrich Alexander University Erlangen, Německo


Vstup<br />

Uspořádané posloupnosti<br />

vrcholů ořezávaného a<br />

ořezávacího polygonu


Výstup<br />

Množina<br />

všech bodů<br />

ležících v<br />

S && C<br />

Polygon<br />

Seznam<br />

vzniklých<br />

<strong>polygonů</strong>


Sebe<strong>pro</strong>tínající polygon<br />

Oblasti, patřící do<br />

výsledku určíme<br />

pomocí tzv.<br />

WINDING NUMBER<br />

Je–li WN liché, lich , pak<br />

náleží výsledku


Winding Number<br />

double isLeft(Point P0, P0, Point P1, Point P2)<br />

{<br />

return((P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y)); P0.y));<br />

}<br />

int WindingNumber(Point WindingNumber(Point P, Point * V, int n)<br />

{<br />

}<br />

int WN WN = 0;<br />

//smyčka přes přes všechny všechny hrany hrany polygonu polygonu<br />

for (int i=0; iP.y)<br />

if(isLeft(V[i],V[i+1],P)>0<br />

++wn; ++wn;<br />

}<br />

else{ // V[i].y> V[i].y> P.y P.y<br />

if(V[i+1].y if(V[i+1].y


Vlastnosti<br />

Winding Number<br />

Při ři pohybu bodu P nebo hrany E, E,<br />

zůstává zůstává<br />

WN konstantní, konstantní,<br />

dokud<br />

P zůstane v kladné vzdálenosti od hrany E.<br />

Pro křivku ω je WN konstantní v pod<strong>pro</strong>storu R x R – ω. . Leží-li<br />

bod P v neohraničené komponentě, pak má WN = 0<br />

Při překřížení paprsku a hrany se WN změní o +/-1.<br />

+/-1


První fáze algoritmu<br />

Určení všech průsečíků hran C a S polygonu<br />

– Složitost minimálně m*n *n /m = # vrcholů vrcholů<br />

S, S,<br />

n = # vrcholů vrcholů<br />

C/ C<br />

– Všechny tyto průsečíky budou vrcholy ve výsledku<br />

– Ukládáme si ukazatele na stejný průsečík v seznamu druhého polygonu<br />

Jejich následné zařazení do seznamu vrcholů obou <strong>polygonů</strong><br />

– K tomu je zapotřebí spočítat tzv. α parametr, parametr,<br />

z kterého lze určit<br />

vzdálenost průsečíku od počátečního vrcholu hrany a zařadit tak správně<br />

všechny průsečíky na jedné hraně<br />

Platí<br />

– 0 < α < 1<br />

– P.x .x = V[i].x + α * V[i+1].x<br />

– P.y = V[i].y + α * V[i+1].y


Zvláštní případy<br />

Leží-li nám bod, či<br />

hrana na hraně<br />

druhého polygonu,<br />

je nutné jej<br />

posunout o<br />

nejmenší možný<br />

úsek, výsledek<br />

zůstane stejný


Druhá fáze algoritmu<br />

V fázi dvě <strong>pro</strong>cházíme všechny<br />

průsečíky a přiřazujeme jim I/O atribut<br />

Ten určuje, zda v daném průsečíku vstupujeme dovnitř<br />

polygonu nebo jej opouštíme.<br />

Stejný průsečík může mít rozdílné atributy v rámci <strong>polygonů</strong><br />

Vezmeme libovolný vrchol polygonu, zjistíme pomocí WN,<br />

zda je uvnitř či vně a jdeme po seznamu vrcholů, vždy, když<br />

narazíme na průsečík, změníme atribut a uložíme jej k<br />

danému průsečíku<br />

Toto <strong>pro</strong>vedeme <strong>pro</strong> oba polygony


Třetí fáze algoritmu


Zdroje<br />

Greiner, G. and Hormann, K. 1998. Efficient clipping of arbitrary polygons. ACM ACM Trans. Trans.<br />

Graph. Graph. 17, 2 (Apr. 1998), 71-83. DOI= http://doi.acm.org/10.1145/274363.274364<br />

Vatti, B. R. 1992. A generic solution to polygon clipping. Commun. ACM ACM 35, 7 (Jul.<br />

1992), 56-63. DOI= http://doi.acm.org/10.1145/129902.129906<br />

<br />

http://notorola.sh.cvut.cz/~bruxy/Algoritmy_pocitacove_grafiky.doc<br />

http://herakles.zcu.cz/education/ZPG/cviceni.php?no=9

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!