A kitöltésről általában

Téglalap kitöltése

Poligon kitöltése

Kör, ellipszis kitöltése

Kitöltés mintával

A kitöltésről általában


területi primitívek: zárt görbék által határolt területek (pl. kör, ellipszis, poligon)

rajzolhatók

a) csak a határvonalat reprezentáló pontok kirajzolásával (kitöltetlen)
b) minden belső pont kirajzolásával (kitöltött)

Alapkérdés: mely képpontok tartoznak a grafikus primitívekhez?

páratlan paritás szabálya:






páros számú metszéspont:
- külső pont


páratlan számú metszéspont:
- belső pont

primitívek kitöltésének az elve:










balról jobbra haladva minden egyes pásztázó (scan) vonalon kirajzoljuk a primitív belső pontjait (egyszerre egy szakaszt kitöltve)

Vissza a lap tetejére

Téglalap kitöltése:







for y from ymin to ymax
  for x from xmin to ymax
    WritePixel(x,y,value)


probléma: egész koordinátájú határpontok hova tartozzanak?
legyen a szabály pl.: egy képpont akkor nem tartozik a primitívhez, ha a rajta áthaladó él és a primitív által meghatározott félsík a képpont alatt vagy attól balra van.
pl.:

vagyis a pásztázó vonalon a kitöltési szakasz balról zárt, jobbról nyitott

megjegyzések:
a) általánosítható poligonokra
b) a bal alsó sarok két helyre tartozhat

c) felső sor és jobb szélső oszlop hiányozhat

Vissza a lap tetejére

Poligon kitöltése

(poligon lehet: konkáv, önmagát metsző, lyukas)

haladjunk a pásztázó egyeneseken és keressük a kitöltési szakaszok végpontjait:

a) a felezőpont algoritmus szerint választjuk a végpontokat (nem számít, hogy a poligonon kívül, vagy belül vannak);


b) a végpontokat a poligonhoz tartozó képpontok közül választjuk


Algoritmus poligonok kitöltésére:

minden pásztázó egyenesre:

1. a pásztázó egyenes és a poligon élei metszéspontjainak a meghatározása;

2. a metszéspontok rendezése növekvő x -koordinátáik szerint;

3. a poligon belsejébe tartozó szakasz(ok) végpontjai közötti képpontok kirajzolása (használjuk a páratlan paritás szabályát: tfh. a bal szélen kívül vagyunk, utána minden egyes metszéspont megváltoztatja a paritást

3.1 Adott x nem egész értékű metszéspont.
Ha kívül vagyunk, akkor legyen a végpont a felkerekített x.
Ha belül vagyunk, akkor legyen a végpont a lefelé kerekített x.

3.2 Adott x egész értékű metszéspont.
Ha ez bal végpont, akkor ez belső pont lesz.
Ha ez jobb végpont, akkor ez külső pont lesz.

3.2.1 A poligon csúcspontjaiban:
ymin csúcspont beszámít a paritásba
ymax csúcspont nem számít a paritásba
(tehát ymax csúcspont csak akkor lesz kirajzolva, ha az a szomszédos él ymin pontja is).

3.2.2 Vízszintes él esetén:
alsó élt rajzolunk, felsőt nem ( = ilyen élek csúcspontjai nem számítanak a paritásba).

Példák poligon kitöltésére


Megjegyzés:

a) diszjunkt poligonoknak lehet közös képpontjuk;

b) szilánkok: olyan poligon-területek, amelyek belsejében nincs kitöltendő szakasz = hiányzó képpontok

Implementáció:

nem kell minden egyes pásztázó vonalra újra kiszámolni minden metszéspontot, mert

a) általában csak néhány metszéspont érdekes

b) az i-dikről az i+1-dik pásztázó vonalra átlépve

egész értékű aritmetika használható:

tfh.: m > 1 és bal határ


ha a tört rész = 0, akkor (x,y)-t rajzolni (vonalon van)
ha a tört rész 0, akkor felkerekíteni x -et (belső pont)
amikor a tört rész > 1, akkor x = x+1 és tört rész = tört rész -1 (1 képponttal jobbra)
törtrész helyett számláló és nevező tárolása

procedure LeftEdgeScan
            (xmin,ymin,xmax,ymax,value : integer);
var x,y,numerator,denominator,increment : integer;
begin
    x := xmin;
    numerator := xmax-xmin;
    denimonator := ymax-ymin;
    increment := denominator;
    for y := ymin to ymax do
      begin
        WritePixel (x,y,value);
        increment := increment+numerator;
        if increment > denominator then
           begin
             x := x+1;
             increment := increment-denominator
           end;
      end
end; 
    

Adatstruktúrák:

ÉT: (Élek Táblázata)


az összes élt tartalmazza kisebbik y értékük szerint rendezve.
(megj.: vízszintes élek kimaradnak)

annyi lista, ahány pásztázó vonal, minden listában az élek az alsó végpont x koordinátája szerint rendezettek


AÉT: (Aktív Élek Táblázata)

azokat az éleket tartalmazza rendezve, amelyeknek a metszéspontjai kitöltési szakaszokat határoznak meg az aktuális pásztázó vonalon
ez is lista


Algoritmus poligon kitöltésére

0. ÉT kialakítása

1. y legyen az ÉT-ben levő nem üres listák közül a legkisebb y

2. AÉT inicializálása (üres)

3. Addig ismételjük, amíg AÉT és ÉT üres lesz:

3.1 ÉT-ből y listákat AÉT-ba, és ott rendezzük x szerint

3.2 A kitöltési szakaszok pontjainak a megjelenítése

3.3 AÉT-ből kivesszük azokat az éleket, amelyekre ymax = y
(a köv. pásztázó egyenessel nincs közös részük)

3.4 y = y+1

3.5 Minden AÉT-beli élben módosítjuk x -et


Megjegyzés: háromszögekre, trapézokra egyszerűsíthető, mert a pásztázó egyeneseknek max 2 metszéspontja lehet a primitívvel

példa C -ben:


    void far fillpoly
                (int numpoints, int far * polypoints[]);
    

        numpoint számú pontból álló poligon kitöltése;
        pontok koordinátái polypointsban


Vissza a lap tetejére

Kör, ellipszis kitöltése

hasonló algoritmussal számíthatók a kitöltési szakaszok

itt: P belül van, ha F(P) < 0, de most is használható a felezéspont módszer
(nem kell ÉT - csak 2 metszéspont lehet)

példa C -ben:


    void far fillellipse
                (int x, int y, int xradius, int yradius)
    

  az aktuális színnel / mintával kitölti az ellipszist



Vissza a lap tetejére

Kitöltés mintával

általában: terület kitöltése szabályosan ismétlődő grafikus elemekkel

képmátrixok (raszter) esetében a cella egy (kisméretű) mátrix

példa C -ben:




8 * 8 -as

    void far setfillpattern(char far * upattern, int color)

lehet a kitöltés "átlátszó" is: nem minden képpontot írunk felül, csak azokat, ahol a minta nem 0

Fajtái:

1. válasszunk egy pontot a primitívben (pl. bal felsőt), egy pontot a mintában (pl. bal felsőt), illesszük azokat egymásra, a többi pont már meghatározható

2. válasszunk egy pontot a képernyőn (pl. bal felsőt), egy pontot a mintában (pl. bal felsőt), illesszük azokat egymásra, a többi pont már meghatározható
(a mintázat a képernyőhöz van rögzítve)

legyen: minta M * N -es mátrix
           minta [0,0] képernyő [0,0]
ekkor

1. módszer: pásztázás soronként

if minta [x mod M, Y mod N] then
   WritePixel(x,y,érték)
("átlátszó")

gyorsabb: több képpont (sor) egyszerre történő másolásával (esetleg maszkolás is szükséges a sor elején vagy végén)

2. módszer: téglalap írás

csak akkor érdemes használni, ha a primitívet sokszor kell használni
pl. karakterek megjelenítése

a téglalap írás kitöltés kombinálható képek közötti műveletekkel (pl. xor), így bonyolult ábrák készíthetők:




Vissza a lap tetejére