Cohen – Sutherlandův algoritmus - Cohen–Sutherland algorithm
The Cohen – Sutherlandův algoritmus je počítačová grafika použitý algoritmus pro oříznutí čáry. Algoritmus rozděluje dvourozměrný prostor na 9 oblastí a poté efektivně určuje čáry a části čar, které jsou viditelné v centrální oblasti zájmu (výřez).
Algoritmus byl vyvinut v roce 1967 během práce letového simulátoru Danny Cohen a Ivan Sutherland.[1]
Algoritmus
Algoritmus zahrnuje, vylučuje nebo částečně zahrnuje řádek na základě toho, zda:
- Oba koncové body jsou v oblasti výřezu (bitové NEBO koncových bodů = 00): triviální přijmout.
- Oba koncové body sdílejí alespoň jednu neviditelnou oblast, což znamená, že čára nepřekračuje viditelnou oblast. (bitové AND koncových bodů ≠ 0): triviální odmítnutí.
- Oba koncové body jsou v různých oblastech: v případě této netriviální situace algoritmus najde jeden ze dvou bodů, které jsou mimo oblast výřezu (mimo něj bude alespoň jeden bod). Poté se vypočítá průsečík bodu a prodloužené hranice výřezu (tj. S parametrickou rovnicí pro čáru) a tento nový bod nahradí bod. Algoritmus se opakuje, dokud nedojde k triviálnímu přijetí nebo odmítnutí.
Čísla na obrázku níže jsou volána kódů. Outcode se vypočítá pro každý ze dvou bodů v řádku. Outcode bude mít 4 bity pro dvourozměrné ořezávání nebo 6 bitů v trojrozměrném případě. První bod je nastaven na 1, pokud je bod nad výřezem. Bity v 2D outcode představují: nahoře, dole, vpravo, vlevo. Například outcode 1010 představuje bod, který je v pravém horním rohu výřezu.
vlevo, odjet centrální že jo horní 1001 1000 1010 centrální 0001 0000 0010 dno 0101 0100 0110
Všimněte si, že kódy pro koncové body musí přepočítat při každé iteraci poté, co dojde k oříznutí.
Algoritmus Cohen-Sutherland lze použít pouze na obdélníkový klip okno.
Příklad implementace C / C ++
typedef int OutCode;konst int UVNITŘ = 0; // 0000konst int VLEVO, ODJET = 1; // 0001konst int ŽE JO = 2; // 0010konst int DNO = 4; // 0100konst int HORNÍ = 8; // 1000// Vypočítejte bitový kód bodu (x, y) pomocí klipu// ohraničeno úhlopříčně (xmin, ymin) a (xmax, ymax)// PŘEDPOKLÁDEJTE, ŽE xmax, xmin, ymax a ymin jsou globální konstanty.OutCode ComputeOutCode(dvojnásobek X, dvojnásobek y){ OutCode kód; kód = UVNITŘ; // inicializováno jako uvnitř [[okno klipu]] -li (X < xmin) // nalevo od okna klipu kód |= VLEVO, ODJET; jiný -li (X > xmax) // napravo od okna klipu kód |= ŽE JO; -li (y < ymin) // pod oknem klipu kód |= DNO; jiný -li (y > ymax) // nad oknem klipu kód |= HORNÍ; vrátit se kód;}// Cohen – Sutherlandův algoritmus oříznutí ořízne řádek z// P0 = (x0, y0) až P1 = (x1, y1) proti obdélníku s // úhlopříčka od (xmin, ymin) do (xmax, ymax).prázdnota CohenSutherlandLineClipAndDraw(dvojnásobek x0, dvojnásobek y0, dvojnásobek x1, dvojnásobek y1){ // spočítá kódy pro P0, P1 a jakýkoli bod leží mimo obdélník klipu OutCode outcode0 = ComputeOutCode(x0, y0); OutCode outcode1 = ComputeOutCode(x1, y1); bool akceptovat = Nepravdivé; zatímco (skutečný) { -li (!(outcode0 | outcode1)) { // bitový OR je 0: oba body uvnitř okna; triviálně přijmout a opustit smyčku akceptovat = skutečný; přestávka; } jiný -li (outcode0 & outcode1) { // bitové AND není 0: oba body sdílejí vnější zónu (LEFT, RIGHT, TOP, // nebo BOTTOM), takže oba musí být mimo okno; výstupní smyčka (přijmout je nepravdivé) přestávka; } jiný { // selhaly oba testy, takže vypočítejte úsečku, kterou chcete oříznout // z vnějšího bodu do průsečíku s hranou klipu dvojnásobek X, y; // Alespoň jeden koncový bod je mimo obdélník klipu; vyberte to. OutCode outcodeOut = outcode1 > outcode0 ? outcode1 : outcode0; // Nyní najděte průsečík; // použití vzorců: // sklon = (y1 - y0) / (x1 - x0) // x = x0 + (1 / sklon) * (ym - y0), kde ym je ymin nebo ymax // y = y0 + sklon * (xm - x0), kde xm je xmin nebo xmax // Není třeba se obávat dělení na nulu, protože v každém případě // testovaný bit outcode zaručuje, že jmenovatel je nenulový -li (outcodeOut & HORNÍ) { // bod je nad oknem klipu X = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0); y = ymax; } jiný -li (outcodeOut & DNO) { // bod je pod oknem klipu X = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0); y = ymin; } jiný -li (outcodeOut & ŽE JO) { // bod je napravo od okna klipu y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0); X = xmax; } jiný -li (outcodeOut & VLEVO, ODJET) { // bod je nalevo od okna klipu y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0); X = xmin; } // Nyní přesuneme vnější bod do průsečíku a ořízneme jej // a připravte se na další průchod. -li (outcodeOut == outcode0) { x0 = X; y0 = y; outcode0 = ComputeOutCode(x0, y0); } jiný { x1 = X; y1 = y; outcode1 = ComputeOutCode(x1, y1); } } }}
Poznámky
- ^ Principy interaktivní počítačové grafiky, str. 124, 252, podle Bob Sproull a William M. Newman, 1973, McGraw-Hill Education, mezinárodní vydání, ISBN 0-07-085535-8.
Viz také
Algoritmy použité pro stejný účel:
Reference
- James D. Foley. Počítačová grafika: principy a praxe. Addison-Wesley Professional, 1996. str. 113.