Na FreeHostingu Endora běží desítky tisíc webů. Přidejte se ještě dnes!

Vytvořit web zdarma

Na FreeHostingu Endora běží desítky tisíc webů. Přidejte se ještě dnes!

Vytvořit web zdarma

int21h

Plechovka turbo aneb Floodfill po dcch

Tento text voln navazuje na minul lnek popisujc tu nejjednodu variantu vyplovacho algoritmu. Nyn se podvme na jeho vylepenou formu, kter potebuje cca tisckrt mn pamti a navc je rychlej.

Vtip je v tom, e msto abychom danou oblast vyplovali pixel po pixelu a do zsobnku ukldali vechny pixely okolo, kreslme po dcch a ukldme si jen urit "dleit" pixely, kterch je mnohonsobn mn.

Budeme potebovat pln stejn zsobnk jako minule: njak pole nebo cokoli, do kterho budeme strkat souadnice pixel na obrazovce (nap. array[...] of record x,y:integer end) a pak je z nj stylem LIFO (posledn vloen jde ven prvn) zase vyndavat. Teoreticky by to vlastn LIFO zsobnk bt nemusel, fungovalo by to i s FIFO frontou, ale LIFO je jednodu na naprogramovn a lp se s nm pracuje.

Vlastn algoritmus pak vypad takhle:

  1. Nkam si ulome barvu vchozho bodu, nazvme si ji VB (kde tato barva kon, tam kon vyplovan oblast).
  2. Pokud je tato barva rovna barv, jakou chceme oblast vybarvit, konme, protoe u je hotovo.
  3. Ulome na zsobnk souadnice vchozho bodu.
  4. Cyklus:
    1. Vyjmeme ze zsobnku jeden bod (eknme P):
    2. Od tohoto bodu postupujeme doleva, dokud nenarazme na okraj oblasti:
    3. Od bodu P postupujeme doprava, dokud nenarazme na okraj oblasti:
    4. Cel takto nalezen dek vybarvme:

    5. Nastavme se na bod nad bodem P (nazvme ho teba Q). Pokud jet je uvnit vybarvovan oblasti, ulome tento bod na zsobnk:
    6. Od tohoto bodu postupujeme doprava a ke konci vybarvenho dku pod nm. Kdykoli narazme na pechod zven dovnit vybarvovan oblasti (jeden pixel m barvu jinou ne VB a nsledujc ji m rovnou VB), ulome si jeho souadnice na zsobnk (ukldme souadnice toho pixelu s barvou VB):

    7. Od bodu Q postupujeme obdobnm zpsobem doleva a k levmu konci vybarvenho dku:

    8. Nastavme se na bod pod bodem P (teba R). Pokud jet je ve vybarvovan oblasti, ulome tento bod na zsobnk:
    9. Postupujeme doprava a doleva obdobn jako ped chvl (u bodu Q):


    10. To cel opakujeme tak dlouho, dokud nen zsobnk pln przdn:






      ...

A to je ve, ptel.

P.S.: je samozejm pln jedno, jestli budete testovat nejdve levou stranu a pak pravou nebo naopak. Ve uveden poad bylo zvoleno nhodn.

P.P.S.: je dobr slouit cykly pro nalezen konce aktulnho dku a testovn dk nahoe a dole do jednoho (maj stejn index).

P.P.P.S.: kdy se podmnka "le pixel uvnit oblasti a m se vybarvit?" zmn z tvaru (barva=pvodn_barva_oblasti) na tvar (barva<>barva_hranice)and(barva<>barva_kterou_vybarvujeme), zmn se tak Plechovka z Paintbrushe na Floodfill z Graph.tpu - barva se pelije pes jakkoli pozad a zastav se jedin o zadanou barvu okraje (nebo o barvu, kterou vybarvujeme, aby nevznikla nekonen smyka).

Jak je na tom tento algoritmus s rychlost? O nco lpe ne dve uveden varianta "bod po bodu do vech stran", protoe kresl cel dky najednou. Hlavn ale spotebovv o nkolik d mn pamti: ukld obvykle mn ne 10 bod na jeden dek, zatmco pedchoz algoritmus by jich poteboval nkolik stovek.

Rychlost ale pod jet nen zrovna pikov. Hlavn proto, e musme testovat spoustu pixel (na jednom dku doleva, doprava a pak to sam o dek nahoe i dole). Prvn urychlovac zlepovk, kter m napadl, byl pout msto Getpixelu Getimage, dky si nast do pamti cel a testovat je a tam (normln pam se te mnohem rychleji ne grafick). Jene zrychlen nen moc vrazn a hlavn se tm vrazn zpomal vyplovn malch oblast - devadest Getpixel je pod jet rychlej ne jeden Getimage pes celou ku obrazovky.

2007-10-10 | Mircosoft