03b ok Preenchimento - Universidade de Aveiro ›...

24
Preenchimento de Áreas e de Polígonos (Filled-Area Primitives) (Filled-Area Primitives) Antonio L. Bajuelos Departamento de Matemática Universidade de Aveiro

Transcript of 03b ok Preenchimento - Universidade de Aveiro ›...

Preenchimento de Áreas e de Polígonos

(Filled -Area Primitives) (Filled -Area Primitives)

Antonio L. BajuelosDepartamento de Matemática

Universidade de Aveiro

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

PreenchimentoPreenchimento dede áreasáreas éé oo processoprocesso dede coloraçãocoloração dodointeriorinterior dede umauma dadadada áreaárea ouou regiãoregião..

� Ás áreas (ou regiões) podem ser descritas ao nível do:

�� PixelPixel ––� Ao nível do pixel, à área é descrita ou:

� pela totalidade dos pixels que a compreendem ou,� em termos dos pixels-fronteira que a delimitam

2

�� GeométricoGeométrico ––� Uma região é descrita em termos de objectos, tais como segmentos de

recta, polígonos, circunferências, etc.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

� A tarefa de preencher umpolígono pode ser dividida emduas:

�� DecidirDecidir queque pixelspixels pintarpintar parapara preencherpreencher oo polígonopolígono..

�� DecidirDecidir comcom queque valorvalor pintarpintar oo pixelpixel..

� Emgeral, a decisão sobre quaispixelspreencher é feita:

�� varrendovarrendo (scan top-down) linhas sucessivas que

3

�� varrendovarrendo (scan top-down) linhas sucessivas que

interceptama primitiva e,

�� preenchendopreenchendo, da esquerda para a direita, blocos depixels

adjacentes que estão dentro da primitiva que define a

região.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� RectângulosRectângulos

� Iremos assumir que:

� O rectângulo écoerentecoerente nono espaçoespaçoi.e. que mantém a sua figurageométrica (forma), sem alterações internas e que a cor dos seuspixels ao longo da figura não varia.

� Esta propriedade é importante e será explorada no processo depreenchimento de regiões.

� Parapreencherum rectângulocomumaúnicacor, pinta-secadapixel

4

� Parapreencherum rectângulocomumaúnicacor, pinta-secadapixeldentro de uma linha de varrimento da esquerda para a direita com omesmo valor depixel, isto é, pode-se preencher cada "bloco" de xmin axmax.

Para y = ymin até ymax do rectângulo {Por linha de varrimento }Para x = xmin até xmax {Cada pixel dentro do bloco}

write_pixel (x, y, valor)

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� RectângulosRectângulos ((contcont ……))

Consideremos agora dois rectângulos que compartilham um mesmo lado.

� Atenção! Se preenchermos cada rectângulo isoladamente, o lado(aresta) compartilhado pelos dois será gerado duas vezes o que não édesejável.

� Surge entãoo problema de definição de área pertencente a cadaprimitiva , isto é, quais ospixels que pertencem a cada primitiva equaisospixelsquenão.

5

quaisospixelsquenão.

� De forma natural, podemos definir ospixels que matematicamente seencontram no interior de uma área definida pela primitiva, comopertencente a ela.

Mas como podemos definir os Mas como podemos definir os pixelspixels que estãoque estão

no limite da primitiva?no limite da primitiva?

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� RectângulosRectângulos ((contcont ……))

� Uma solução de “compromisso”:

Os pixels que estão sobre os lados (arestas) esquerdo einferior pertencem a primitiva e serão desenhados,porém os lados superior e direito não pertencemaprimitiva e portanto não serão desenhados

6

� Assim, uma aresta vertical compartilhada por dois rectângulospertencem ao lado que está mais a direita.

OsOs blocosblocos dentrodentro dede umum rectângulorectângulo representamrepresentamumum intervalointervalo queque ééfechadofechado aa esquerdaesquerda ee emembaixobaixo ee abertoaberto ememcimacima ee aa direitadireita

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� RectângulosRectângulos ((contcont ……))

� Algumas considerações devem ser feitas sobre esta regra:

� A regra se aplica da mesma forma a polígonos arbitrários e nãosomente a rectângulos.

� O vértice do canto inferior esquerdo ainda continua sendodesenhado duas vezes.

� A regra faz com que em cadablocoesteja faltando o seupixelmaisa direita, e em cadarectângulofique faltandoo seulado (aresta)

7

a direita, e em cadarectângulofique faltandoo seulado (aresta)superior.

OsOs problemasproblemas apresentadosapresentados nasnas consideraçõesconsiderações acimaacimademonstramdemonstramqueque nãonão háhá soluçãosolução perfeitaperfeita parapara oo problemaproblema dedenãonão escreverescrever maismais dede umauma vezvez linhaslinhas queque sejamsejampotencialmentepotencialmente compartilhadascompartilhadas porpor maismais dede umum polígonopolígono..

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimentoPreenchimento porpor GérmenGérmen� Neste tipo de métodos o utilizador

deverá indicar umpixel inicial chamadogérmen(seed). Este gérmen deve estarno interior do polígono.

� A partir do gérmengérmen, o algoritmoinspeccionaos pixels adjacentespara

8

inspeccionaos pixels adjacentesparadeterminar se toda a região já foicoberta.

� O processo é repetido até que todos ospixelsdo interior da região tenhamsidoinspeccionados.

� Este tipo de métodos de preenchimentoé indicado para aplicações interactivas.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

PreenchimentoPreenchimento porpor GérmenGérmen� Existemdois tipos básicosde preenchimento porgérmengérmen:

�� PreenchimentoPreenchimento porpor SaturaçãoSaturação ((FloodFlood--FillFill))� Este método é utilizado quando a fronteira da região é

monocromática. O objectivo é, a partir do gérmen P,determinar a maior região ligada de pontos cujo cor (valor depixel) é igualao valor de P.

9

�� PreenchimentoPreenchimento porpor FronteiraFronteira ((BoundaryBoundary--FillFill))� Este método é usualmente utilizado quando a fronteira da

região pode ser definida por primitivas policromáticas. Nestecaso o objectivo é determinar a maior região ligada de pontoscujo cor (valor de pixel)não é igualao valor da fronteira.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimentoPreenchimento porpor GérmenGérmen� Os algoritmos do tipoFloodFlood--FillFill e do tipoBoundaryBoundary--FillFill

podemser implementados na versões44ou88--connectedconnected

� A versão44--connectedconnectedé maisrápidamasNÃO garantea4 movimentos: N, S , E, W 8 movimentos: N, S , E, W, NE, NW, SE, SW

10

� A versão44--connectedconnectedé maisrápidamasNÃO garanteacobertura de todos os tipos de regiões

� Estes algoritmos sãoaltamente recursivospodendo gerarproblemas destack overflow (utilização excessiva dememória)

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

�� AlgoritmoAlgoritmo BoundaryBoundary--FillFill(Versão 4-connected)

void BoundaryFill4(int x, int y, color newcolor, color edgecolor){

int current;current = ReadPixel(x, y);if(current != edgecolor && current != newcolor)

11

if(current != edgecolor && current != newcolor) {

BoundaryFill4(x+1, y, newcolor, edgecolor);BoundaryFill4(x-1, y, newcolor, edgecolor);BoundaryFill4(x, y+1, newcolor, edgecolor);BoundaryFill4(x, y-1, newcolor, edgecolor);

}}

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

�� AlgoritmoAlgoritmo FloodFlood--FillFill(Versão 4-connected)

void FloodFill4(int x, int y, color newcolor, color oldColor){

if(ReadPixel(x, y) == oldColor) {

FloodFill4(x+1, y, newcolor, oldColor);

12

FloodFill4(x+1, y, newcolor, oldColor);FloodFill4(x-1, y, newcolor, oldColor);FloodFill4(x, y+1, newcolor, oldColor);FloodFill4(x, y-1, newcolor, oldColor);

}}

* Replace a specified interior color (old color) with fill color

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

� O algoritmo que vamos discutir a seguir é válido parapolígonos de forma arbitrário (côncavos e convexos).Inclusive funciona para polígonos comauto-intersecçõese/ou buracos.

� Este algoritmo opera determinandoblocosde pixelsqueestãoentreos ladosmaisà esquerdae maisà direita do

13

estãoentreos ladosmaisà esquerdae maisà direita dopolígono.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

Ideias básicas� Calcula o preenchimento sempre entre as arestas mais à

esquerda e mais à direita� Incrementalmente calcula a intersecção da linha raster

(scan line) com as arestas do polígono, a partir daanteriorlinha raster

14

anteriorlinha raster

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

� Na figura: as intersecções da linha de varrimento 8 com os ladosFAe CD possuem coordenadas inteiras, enquanto as intersecções comos ladosEF eDE possuem coordenadas reais (não inteiras).

� É preciso determinar quepixelsda linha de varrimento estão dentrodo polígono.

� No exemplo da figura: Osblocosparax = 2 até 4 e 9 até 13 comseuvalorapropriado.

15

seuvalorapropriado.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

Algumas observações� Devemos nos preocupar com a definição dos pontos extremos do

polígono, i.e. não podemos desenharpixels que não pertençamverdadeiramente ao interior do polígono, poispodemos estar invadindo odomínio de outro polígono

�� ÉÉ preferívelpreferível traçartraçar apenasapenas osos pixelspixels queque estejamestejam estritamenteestritamente nanaregiãoregião definidadefinida pelopelo polígono,polígono,mesmomesmoqueque umumpixelpixel exteriorexterior estejaesteja

16

regiãoregião definidadefinida pelopelo polígono,polígono,mesmomesmoqueque umumpixelpixel exteriorexterior estejaestejamaismais próximopróximo aa arestaaresta realreal..

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

O processo de preencher os polígonos pode ser dividido emtrês passos:

� Obter a intersecção da linha de varrimento comtodos oslados do polígono.

� Ordenaros pontos de intersecção(por incrementoda

17

� Ordenaros pontos de intersecção(por incrementodacoordenadax).

� Preencher os pixels entre pares de pontos de intersecçãodo polígono que são internos a ele. Para determinarquais os pares que são internos ao polígono, podemosusar aregra de Paridade

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos�� PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

RegraRegra dadaParidadeParidade::� Iniciando compar, sempre que encontra uma intersecção inverte a

paridade.

� O pixelé pintadoquando a paridade éimpar� O pixelNÃO é pintado quando épar.

18

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

� Caso I: Se a intersecção é umvalorfraccionário, como determinar qual opixel que deverá ser tomado para quefique interior ao polígono?

� O valor deverá ser arredondado deforma a que o ponto fique dentro dopolígono. Passosaseguir:

PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

19

polígono. Passosaseguir:� Se estamos dentro do polígono

(paridade ímpar) e atingimos umaintersecção fraccionária pela direita(exemplo, o pontob), arredondamos acoordenada x da intersecção parabaixo.

� Se estamos fora do polígono (paridadepar) arredondamos para cima(exemplo,o ponto c). Isso garante que sempreteremos um ponto dentro do polígono.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

� Caso II: Como tratar o caso deintersecção comcoordenadas inteiras?

� Pode-se utilizar o critério vistoanteriormente, para evitar conflitosentre lados compartilhados emrectângulos. Passos a seguir:

PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

20

� Se a coordenadax de um pixel mais aesquerda de um bloco (span) é inteiraele é definido como interno (exemplo, opontoa).

� Se a coordenadax do pixel mais adireita de um bloco é inteira, ele édefinido como externo ao polígono(exemplo, o pontod).

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

� Caso III: Como tratar o caso II paravértices que são compartilhados por maisde uma aresta do polígono?

Usamos a técnica de paridade. Ou seja:

� Contamos o vértice deymin de um ladopara alterar a paridade, mas não

PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

21

para alterar a paridade, mas nãocontamos o vértice deymax, dessa formao vértice deymax é desenhado somentese ele é o vértice deymin do ladoadjacente.

� Assim ambos os lados e blocos sãotratados como intervalos que sãofechados em seu valor mínimo eabertos em seu valor máximo.

Exemplo: Na figura, o vérticeA é contado uma vez nocálculo de paridade porque éo vértice deymin para o ladoFA, mas é também o vérticedeymaxpara o ladoAB.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

Ilustração do algoritmo:Para a linha de varrimento y = 8:� Os pixels serão preenchidos a partir do ponto

a (coordenadas (2,8)), até o primeiro pixel aesquerda do pontob (coordenadas (4,8));

� E do primeiro pixel a direita do pontoc(coordenadas(9,8)) até o primeiro pixel a

PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

22

(coordenadas(9,8)) até o primeiro pixel aesquerda do pontod (coordenadas (12,8)).

Para a linha de varrimento y = 3:� O vérticeA conta uma vez porque é o vértice

deymin do ladoFA (e é também o vérticeymax

do ladoAB), isto causa paridade ímpar, assimo bloco é desenhado a partir deA até umpixel a esquerda da intersecção com o ladoCB, onde a paridade é estabelecida como pare o bloco é terminado.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

Ilustração do algoritmo (cont…):Para a linha de varrimento y = 1� Ela passa apenas pelo vérticeB, e os ladosAB

e BC tem como vértice deymin o vérticeB, oqual é dessa forma contado como paridade par.

� Este vértice actua como um bloco nulo, pois alinha devarrimentoentrapelovértice,desenha

PreenchimentoPreenchimento dede PolígonosPolígonos ((ScanScan--LineLine AlgorithmAlgorithm ))

23

linha devarrimentoentrapelovértice,desenhao pixel e sai por ele mesmo.

� Assim, o pixel que corresponde ao pontoBnão é pintado.

� Isso acontece com a intersecção da linha devarrimento 9 com o vérticeF, compartilhadopelos ladosFA e EF. Para ambos os lados,F évértice ymax, e dessa forma não afecta aparidade, que continua par.

Preenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de PolígonosPreenchimento de Áreas e de Polígonos

SliversSlivers (tiras)(tiras)� Existe um outro problema com o nosso algoritmo de

conversão matricial: polígonos com lados muitopróximos criam umsliver� Sliver- uma área poligonal tão estreita que seu interior não

contém um bloco de pixels para cada linha de varrimento(ver figura).

� Devidoà regradequesãotraçadosapenasospixelsque

24

� Devidoà regradequesãotraçadosapenasospixelsqueestejam no interior ou sobre arestas inferiores ou aesquerda, podem existir muitas linhas de varrimento comum único pixel, ou sem nenhum.

� Para melhorar a aparência nesses casos, pode-se usartécnicas deantialiasing (se tivermos múltiplos bits porpixel).

� Antialiasing implicaria em "suavizar" nossa regra de"traçar apenas pixels que estejam no interior ou numaaresta inferior ou à esquerda"