Você está na página 1de 47

Geometria Computacional

Cristina G. Fernandes, Jos Coelho de Pina 24 de outubro de 2011


Resumo Introduzimos geometria computacional por meio de problemas clssicos: proximidade, fecho convexo, interseo de segmentos e diviso de polgono. O problema de proximidade que consideramos consiste em, dados pontos no plano, determinar um par mais prximo destes pontos. Apresentamos um elegante algoritmo de diviso e conquista para este problema. Existem vrios algoritmos que, dados pontos no plano, determinam o fecho convexo destes pontos. Apresentamos quatro deles: um algoritmo incremental, o embrulho de presente, o de Graham e o Quickhull. Estes algoritmos usam-se de tcnicas bem diferentes, e mostram como um problema fundamental pode ser atacado de diversas maneiras. O bem sucedido mtodo da linha de varredura apresentado usando dois problemas: interseo de segmentos e diviso de polgono.

Introduo

A procura por algoritmos para resolver problemas geomtricos vem desde a poca da antiguidade. Algumas motivaes prticas para a busca por tais algoritmos foram os impostos sobre o uso da terra e construes de edicaes. So bem-conhecidas as construes geomtricas de Euclides, que usavam como instrumentos rgua e compasso e consistiam de algumas operaes primitivas que podiam ser realizadas com esses instrumentos. Um problema algortmico se pede como resposta um algoritmo que resolva um determinado problema. Em geometria clssica, esses so conhecidos como Problemas de Construes Geomtricas. Um destes problemas o chamado Problema de Apollonius (cerca de 200 A.C.), no qual trs circunferncias arbitrrias no plano eram dadas e pedia-se uma quarta circunferncia que fosse tangente s trs circunferncias dadas. Euclides apresentou um algoritmo que resolve este problema. Dentre todos os problemas algortmicos em geometria (usando construes geomtricas de Euclides), um que atraiu grande ateno foi o problema da construo de um polgono regular de n lados. Para n = 3, 4, 5, 6, a soluo conhecida desde a antiguidade. Entretanto, para heptgonos regulares, n = 7, o problema no tem soluo: aos 17 anos, Carl Friedrich Gauss (1777-1855) mostrou que no existe um algoritmo que, usando somente as operaes primitivas de Euclides, constri um heptgono regular. Na realidade Gauss mostrou 1

mais que isso. Ele mostrou que existe um algoritmo para construir um polgono regular com p lados, p primo, se e somente se p da forma 22n + 1. Em 1902, Emile Lemoine introduziu uma medida de simplicidade para os algoritmos que usam as construes de Euclides. Esta medida baseada no nmero de operaes primitivas realizadas pelo algoritmo. Para Lemoine, o algoritmo mais simples aquele que faz menos operaes primitivas. A soluo de Euclides para o Problema de Apollonius requer 508 dessas operaes enquanto que um algoritmo proposto por Lemoine requer menos de duzentas. Estava portanto introduzido em geometria um conceito que , pelo menos em essncia, o que hoje chamamos de complexidade de um algoritmo. Em geometria computacional estamos interessados em projetar algoritmos ecientes para resolver problemas geomtricos. Pelo que foi exposto acima, vemos que no algo novo. A diferena que as operaes primitivas usam um instrumento diferente da rgua e do compasso: usam um computador. Um pouco mais precisamente, em geometria computacional, estamos interessados em encontrar algoritmos ecientes, ou procedimentos computacionais, para resolver problemas geomtricos. Muitos desses problemas tm sua origem em outras reas, como computao grca, robtica, computer-aided design e processamento de imagens. No projeto de tais algoritmos, so comumente utilizados resultados de geometria euclidiana, combinatria, teoria dos grafos, estruturas de dados e anlise de algoritmos. Geometria computacional um termo usado por diversos grupos. Entretanto, o termo tem sido mais utilizado para descrever a subrea da teoria de algoritmos que trata do projeto e anlise de algoritmos ecientes para problemas envolvendo objetos geomtricos, principalmente, em espaos de dimenso 2, 3 ou, de uma maneira mais geral, de dimenso xa. As entradas para os problemas so primordialmente objetos simples: pontos, retas, segmentos de retas, polgonos, planos e poliedros. neste sentido que empregamos o termo geometria computacional neste curso. Se a tese de doutorado de Michael Ian Shamos (1978) for aceita como o incio da geometria computacional, pelo menos da maneira como ela ser tratada aqui, ento a rea tem apenas cerca de 30 anos. Apesar disso, existem pelo menos 8 livros na rea (dois deles em portugus), 4 revistas e vrias conferncias internacionais na rea. Esta rea desenvolveu-se rapidamente nos anos 70, 80 e 90, e continua a se desenvolver. Por causa da rea a partir da qual cresceu (desenvolvimento de algoritmos discretos), geometria computacional tem sempre enfatizado problemas de natureza matemtica discreta. Na maioria dos problemas em geometria computacional, as instncias so um conjunto nito de pontos e/ou de outros objetos geomtricos, e a sada exigida algum tipo de estrutura descrita por um conjunto nito de pontos ou segmentos de retas. De acordo com Joseph ORourke (1993), nem todos os problemas em aberto em geometria computacional so necessariamente difceis; alguns esto simplesmente esperando a devida ateno [ORourke 1993]. Este pode ser um bom motivo para brincarmos com problemas desta rea. Na Seo 2, apresentamos o problema do par mais prximo, e alguns algorit2

mos para ele. Na Seo 3, apresentamos o clssico problema do fecho convexo de um conjunto de pontos no plano, e vrios algoritmos para resolv-lo. Na Seo 4, apresentamos o mtodo da linha de varredura, clssica ferramenta para resoluo de problemas em geometria computacional, e o aplicamos a um problema de interseo de segmentos. Na ltima seo, apresentamos um algoritmo para o problema de diviso de um polgono em polgonos montonos, que tambm usa o mtodo da linha de varredura. Os problemas e algoritmos discutidos neste texto so tratados em vrios livros [Cormen et al. 2001, de Berg et al. 1997, Kleinberg and Tardos 2006, Laszlo 1996, ORourke 1993, Preparata and Shamos 1985], alguns por autores brasileiros [Figueiredo and Carvalho 1991, de Resende and Stol 1994].

Problema do par mais prximo


Esta seo estuda alguns algoritmos para um problema de proximidade. Trata-se do problema do par mais prximo (closest pair problem), onde queremos encontrar dois pontos de uma coleo dada tais que a distncia entre eles seja a menor possvel. Uma aplicao prtica deste problema, na sua verso cintica, em controle de trfego areo: os dois avies que esto em maior perigo de coliso so aqueles que esto mais prximos.

2.1

O problema

Os pontos dados podem estar em um espao de dimenso arbitrria, mas neste texto discutiremos o caso em que os pontos esto no plano e a distncia entre eles a euclideana. Assim, se (x, y) e (x , y ) so (as coordenadas de) dois pontos do plano, a distncia entre eles, denotada por Dist(x, y, x , y ), o nmero 1/2 (x x )2 + (y y )2 . Problema do par mais prximo. Dada uma coleo P de pontos do plano, encontrar dois pontos (distintos) de P tais que a distncia entre eles seja a menor possvel. Para simplicar a exposio, os algoritmos descritos devolvem apenas a menor distncia entre dois pontos de P . Se |P | = 1, convencionamos que essa distncia innita. Uma coleo de n pontos do plano representada por dois vetores de nmeros, X[1 . . n] e Y [1 . . n]. Especicamente, os pontos da coleo so (X[1], Y [1]), . . . , (X[n], Y [n]).

2.2

Algoritmo elementar

A primeira idia para a resoluo do problema do par mais prximo simplesmente calcularmos a distncia entre cada par de pontos, enquanto mantemos a menor distncia encontrada at o momento. O algoritmo abaixo, que implementa essa idia, recebe dois vetores X[1 . . n] e Y [1 . . n] e devolve a menor distncia entre dois pontos da coleo representada por X[1 . . n], Y [1 . . n]. Elementar(X, Y, n) 1 d + 2 para i 2 at n faa 3 para j 1 at i 1 faa 4 se Dist(X[i], Y [i], X[j], Y [j]) < d 5 ento d Dist(X[i], Y [i], X[j], Y [j]) 6 devolva d O algoritmo est correto. Para mostrar que o algoritmo est correto, basta vericar que a cada passagem pela linha 2, imediatamente antes da comparao de i com n, d a menor distncia entre dois pontos da coleo representada por X[1 . . i1], Y [1 . . i1]. Este invariante mostra que o algoritmo est correto, pois na ltima passagem pela linha 2 temos i = n + 1. Consumo de tempo. Observe que o nmero de vezes que a linha 4 executada n1 n n(n 1) i = (i 1) = 2 i=1 i=2 e esta funo est em (n2 ). J a linha 5 executada O(n2 ) vezes. Assim sendo, o algoritmo consome tempo (n2 ). possvel projetar um algoritmo mais eciente que este? Uma idia que algumas vezes funciona em geometria computacional considerar o problema em um espao de dimenso menor e encontrar um algoritmo mais rpido que possa ser estendido para espaos de dimenso maior. Vamos ento fazer um desvio, e pensar no problema quando os pontos dados esto em uma reta.

2.3

Par mais prximo na reta

Quando os pontos dados esto numa reta, podemos pensar neles simplesmente como uma coleo de nmeros. Observe que, na reta, a distncia entre dois nmeros x e x |x x |. Neste caso, h um algoritmo muito simples que determina a menor distncia entre dois nmeros da coleo. Basta ordenar os nmeros dados e determinar a menor distncia entre dois consecutivos. O algoritmo a seguir recebe um vetor X[1 . . n], representando uma coleo de pontos da reta, e devolve a menor distncia entre dois deles. 4

ElementarReta(X, n) 1 MergeSort(X, 1, n) 2 d + 3 para i 2 at n faa 4 se X[i] X[i1] < d 5 ento d X[i] X[i1] 6 devolva d O algoritmo est correto. Veja o Exerccio 3. Consumo de tempo. Pela Seo Ordenao de Vetor do Captulo Anlise de Algoritmos deste livro, o consumo de tempo da linha 1 (n lg n). O nmero de vezes que o bloco de linhas 4-5 executado n1. Logo, o consumo de tempo do algoritmo ElementarReta (n lg n), que substancialmente menor que o consumo do algoritmo Elementar. Infelizmente no sabemos estender a idia deste algoritmo para o plano. A seguir aplicamos a estratgia de diviso e conquista para resolver o problema do par mais prximo na reta, obtendo um algoritmo que tambm consome tempo (n lg n). O algoritmo obtido um pouco mais complicado que o anterior, porm pode ser estendido para resolver o problema no plano. O algoritmo DistnciaRetaRec-SH, mostrado mais abaixo, recursivo. Ele recebe como entrada um vetor crescente X[p . . r], com p r, e devolve a menor distncia entre dois nmeros em X[p . . r]. Assim, antes de invoc-lo, necessrio ordenar o vetor X: DistnciaReta-SH(X, n) 1 MergeSort(X, 1, n) 2 devolva DistnciaRetaRec-SH(X, 1, n) A estratgia dividir o vetor X[p . . r] ao meio, uma metade com os nmeros mais esquerda e a outra com os nmeros mais direita, resolver o problema recursivamente para os dois vetores resultantes e, de posse das solues para estes vetores, determinar a soluo para o vetor X[p . . r].
dE X[q] X[p . . q] dED X[q+1] X[q+1 . . r] dD

DistnciaRetaRec-SH(X, p, r) 1 se r = p 2 ento devolva + 3 seno se r = p + 1 4 ento devolva X[r] X[p] 5 seno q (p + r)/2 6 dE DistnciaRetaRec-SH(X, p, q) 7 dD DistnciaRetaRec-SH(X, q + 1, r) 8 d min{dE , dD , X[q+1] X[q]} 9 devolva d O algoritmo est correto. A menor distncia entre dois nmeros em X[p . . r] a menor das distncias entre dois nmeros em X[p . . q], ou entre dois nmeros em X[q+1 . . r], ou entre um nmero em X[p . . q] e um em X[q+1 . . r]. Como X[p . . q] crescente, a menor das distncias entre um nmero em X[p . . q] e um em X[q+1 . . r] X[q+1] X[q]. Desse argumento indutivo segue que o algoritmo est correto. Consumo de tempo. O consumo de tempo de DistnciaRetaRec-SH medido em relao ao tamanho n := r p + 1 do vetor X[p . . r]. Seja T (n) o tempo consumido pelo algoritmo DistnciaRetaRec-SH quando aplicado a um vetor X de tamanho n. O tempo consumido pelas linhas 5, 8 e 9 independe de n, ou seja, esse consumo de tempo (1). Portanto, T (n) = T ( n ) + T ( n ) + (1). 2 2 (1)

O termo T ( n ) corresponde ao consumo de tempo da linha 6 e o termo T ( n ), 2 2 ao consumo da linha 7. A funo T (n) est em (n) (Exerccio 4). O algoritmo DistnciaRetaRec-SH consome ento tempo (n). Como o MergeSort consome tempo (n lg n) quando aplicado a um vetor de tamanho n, temos que o consumo de tempo do algoritmo DistnciaReta-SH (n lg n).

2.4

Algoritmo de Shamos e Hoey

O algoritmo aqui descrito uma generalizao do algoritmo anterior para pontos do plano [Shamos and Hoey 1975]. Aqui ele denominado de Distncia-SH e, como o anterior, uma mera casca para o algoritmo que faz o verdadeiro servio, o DistnciaRec-SH. O algoritmo DistnciaRec-SH recebe X[p . . r] e Y [p . . r], representando uma coleo de pontos do plano. Analogamente ao DistnciaRetaRec-SH, o vetor X crescente. Com isso, temos uma representao dos pontos ordenados em relao s suas coordenadas X, da esquerda para a direita. Em uma de suas fases, DistnciaRec-SH necessita acessar os pontos em ordem de suas coordenadas Y . Por isso ele tambm recebe como entrada um vetor a[p . . r] com uma permutao de [p . . r] tal que Y [a[p]] Y [a[p+1]] Y [a[r]]. Isso nos fornece uma representao dos pontos ordenados em relao s suas coordenadas Y , de baixo para cima:

(3, 4) (0, 3) (4, 2)


X Y a 2 0 1 3 4

1
1

2
3

3
2

4
4

5
2

1
3

2
1

3
5

4
2

5
4

(2, 1)

(1, 2)

Dizemos que X, Y, a uma representao ordenada de pontos. J que DistnciaRec-SH(X, Y, a, p, r) recebe uma representao ordenada X[p . . r], Y [p . . r], a[p . . r] de pontos, ento as linhas 1-4 de Distncia-SH meramente rearranjam os vetores X e Y e criam o vetor a para que X, Y, a seja uma tal representao. Distncia-SH(X, Y, n) 1 MergeSort(X, Y, 1, n) ordena X rearranjando 2 para i 1 at n faa 3 a[i] i 4 MergeSortInd(Y, 1, n, a) ordenao indireta 5 devolva DistnciaRec-SH(X, Y, a, 1, n)
Y simultaneamente

Passamos a descrever o algoritmo DistnciaRec-SH, que recursivo. Se r p + 2 ento o problema resolvido diretamente. Caso contrrio, a idia , em cada nvel da recurso, executar as trs fases a seguir: Dividir: Seja q := (p + r)/2. Obtenha um vetor b[p . . r] tal que X[p . . q], Y [p . . q], b[p . . q] seja uma representao ordenada dos pontos mais esquerda e X[q+1 . . r], Y [q+1 . . r], b[q+1 . . r], uma representao ordenada dos pontos mais direita. Conquistar: Determine, recursivamente, a menor distncia dE entre dois pontos da esquerda e a menor distncia dD entre dois pontos da direita. Combinar: Devolva o mnimo entre dE , dD e a menor distncia dED entre um ponto da esquerda e um ponto da direita.

(X[q], Y [q]) dE dED

dD

X[p . . q], Y [p . . q], b[p . . q]

X[q+1 . . r], Y [q+1 . . r], b[q+1 . . r]

Veja o pseudocdigo a seguir. Nele, so usados dois algoritmos: Divida e Combine. O algoritmo Divida recebe uma representao ordenada X[p . . r], 7

Y [p . . r], a[p . . r] de pontos e devolve um vetor b[p . . r] como na descrio da fase dividir acima. O algoritmo Combine recebe X[p . . r], Y [p . . r], a[p . . r] e as distncias dE e dD , e devolve a menor distncia entre dois pontos da coleo representada por X[p . . r], Y [p . . r], a[p . . r]. DistnciaRec-SH(X, Y, a, p, r) 1 se r p + 2 2 ento resolva o problema diretamente 3 seno q (p + r)/2 4 b Divida(X, Y, a, p, r) 5 dE DistnciaRec-SH(X, Y, b, p, q) 6 dD DistnciaRec-SH(X, Y, b, q + 1, r) 7 devolva Combine(X, Y, a, p, r, dE , dD ) O algoritmo est correto. Desde que Divida e Combine estejam corretamente implementados, DistnciaRec-SH est correto, e portanto Distncia-SH tambm. Consumo de tempo. O consumo de tempo de DistnciaRetaRec-SH medido em relao ao nmero de pontos n := r p + 1. Este consumo depende de Divida e Combine. O consumo de tempo da implementao destes exibida frente (n). Assim, se T (n) o consumo de DistnciaRetaRec-SH, ento T (n) = T ( n ) + T ( n ) + (n). 2 2 As parcelas T ( n ) e T ( n ) correspondem s linhas 5 e 6 respectivamente. 2 2 Da Seo Soluo de Recorrncias do Captulo Anlise de Algoritmos deste livro, a funo T est em (n lg n). Portanto DistnciaRec-SH consome tempo (n lg n). No algoritmo Distncia-SH, as linhas 1, 4 e 5 consomem tempo (n lg n) e as linhas 2 e 3 consomem (n). Assim o seu consumo de tempo (n lg n). A seguir est uma implementao do algoritmo Divida que, por simplicidade, supe que na coleo no h dois pontos com a mesma coordenada X. Divida(X, Y, a, p, r) 1 q (p + r)/2 2 ip1 j q 3 para k p at r faa 4 se X[a[k]] X[q] (X[a[k]], Y [a[k]]) est esquerda 5 ento i i + 1 6 b[i] a[k] 7 seno j j + 1 8 b[j] a[k] 9 devolva b

da reta x = X[q]?

O algoritmo Divida est correto. Como X crescente e no h pontos com a mesma coordenada X, ento o nmero de pontos com coordenada X menor ou igual a X[q] exatamente q p + 1. Assim, ao nal do Divida, i=q 8

e j=r. Alm disso, pelo teste da linha 4, os ndices de a[p . . r] de pontos da esquerda esto sendo colocados em b[p . . q], em ordem crescente de suas coordenadas Y . Similarmente os ndices de pontos da direita esto sendo colocados em b[p . . q], tambm em ordem crescente de suas coordenadas Y . Portanto, ao nal, X[p . . q], Y [p . . q], b[p . . q] e X[q+1 . . r], Y [q+1 . . r], b[q+1 . . r] so representaes ordenadas dos pontos esquerda e direita respectivamente. Consumo de tempo do algoritmo Divida. fcil ver que o Divida consome tempo (n), onde n := r p + 1. O algoritmo Combine o corao do DistnciaRec-SH. Uma implementao ingnua dele consumiria tempo quadrtico: calcule a distncia entre cada ponto da coleo representada por X[p . . q], Y [p . . q], a[p . . q] e cada ponto da coleo representada por X[q+1 . . r], Y [q+1 . . r], a[p . . r], determine dED , que a menor destas distncias, e devolva a menor entre dED , dE e dD . preciso fazer algo mais renado que isso. A primeira observao importante que no necessrio que Combine calcule a distncia entre pontos que esto sabidamente a uma distncia maior que d := min{dE , dD }. Com isso, Combine precisa considerar apenas pontos que esto a uma distncia menor que d da reta vertical x = X[q].
d d (X[q], Y [q]) dE

dD

fcil determinar quais pontos da coleo esto a uma distncia menor que d da reta x = X[q]. Isso feito pelo algoritmo Candidatos, que recebe como parmetros X[p . . r], a[p . . r], parte de uma representao ordenada X, Y, a, e recebe tambm um nmero positivo d. O algoritmo Candidatos devolve um vetor f [1 . . t] indicando os pontos da coleo representada por X, Y, a que esto a uma distncia menor que d da reta x = X[q] em ordem de suas coordenadas Y . Candidatos (X, a, p, r, d) 1 q (p + r)/2 t 0 2 para k p at r faa 3 se |X[a[k]] X[q]| < d 4 ento t t + 1 f [t] a[k] 5 devolva (f, t) Chamemos de F a coleo dos pontos indicados pelo vetor f . Quantos pontos h em F ? No pior caso, h n pontos em F . Logo, se calcularmos a distncia entre quaisquer dois pontos de F , no pior caso calcularamos (n2 ) distncias nesta fase. Isso resultaria de novo em um consumo de tempo de (n2 ) para o Combine, o que no suciente. 9

A segunda observao crucial que qualquer quadrado de lado d totalmente contido em um dos lados da reta x = X[q] contm no mximo 4 pontos da coleo. Do contrrio, haveria um par de pontos em um dos lados a uma distncia menor que d. Para cada ponto em F , ou seja, para cada i com 1 i t, considere a reta horizontal y = Y [f [i]] que passa pelo ponto (X[f [i]], Y [f [i]]). Considere os dois quadrados de lado d que tm sua base nesta reta: um com seu lado direito na reta x = X[q] e o outro com seu lado esquerdo na reta x = X[q].
d d

dE y = Y [f [i]] (X[f [i]], Y [f [i]]) dD

H no mximo 8 pontos da coleo nestes quadrados, incluindo o ponto (X[f [i]], Y [f [i]]). Dentre os pontos de F acima da reta y = Y [f [i]], apenas pontos nestes quadrados tm chance de estar a uma distncia de (X[f [i]], Y [f [i]]) menor do que d. Assim basta comparar (X[f [i]], Y [f [i]]) com os 7 prximos pontos de F , em ordem de suas coordenadas Y . Combine (X, Y, a, p, r, dE , dD ) 1 d min{dE , dD } 2 (f, t) Candidatos (X, a, p, r, d) 3 para i 1 at t 1 faa 4 para j i + 1 at min{i + 7, t} faa 5 d Dist(X[f [i]], Y [f [i]], X[f [j]], Y [f [j]]) 6 se d < d 7 ento d d 8 devolva d O algoritmo Combine est correto. Conforme discusso prvia, os pares de pontos para os quais a distncia no foi calculada na linha 5 esto distncia pelo menos min{dE , dD }. Consumo de tempo do algoritmo Combine. O consumo de tempo do algoritmo Combine tambm medido em relao ao nmero n := r p + 1 de pontos. Candidatos consome tempo (n) e o bloco de linhas 5-7 executado no mais do que 7n vezes. Portanto o consumo de tempo do Combine (n).

10

Exerccios
1. Considere o espao euclideano 3-dimensional (o R3 , com a distncia denida da maneira usual). Este espao usualmente denotado por E3 . Ajuste o algoritmo Elementar para que ele aceite como dados uma coleo de pontos do E3 . 2. Modique os algoritmos Elementar e Distncia-SH para que eles devolvam as coordenadas de dois pontos da coleo tais que a distncia entre eles seja a menor possvel. 3. Encontre um invariante apropriado que torne evidente a correo do algoritmo ElementarReta. 4. Seja F a funo denida sobre os inteiros positivos satisfazendo F (1) = 1 e F (n) = F ( n ) + F ( n ) + 1. 2 2 Demonstre por induo em n que n 1 F (n) 2n 1. Conclua que o consumo de tempo do DistnciaRetaRec-SH, dado pela funo T (n) que satisfaz (1), est em (n). 5. Simule a execuo do algoritmo Divida para a representao ordenada X, Y, a dada como exemplo na pgina 7. 6. Modique o algoritmo Divida para que ele funcione quando a coleo dada tem pontos com mesma coordenada X. 7. possvel trocar o nmero 7 na linha 8 do algoritmo Combine por um valor menor? Qual? Encontre um exemplo que mostra que o nmero que voc escolheu no pode ser diminudo 8. A construo do vetor f necessria no Combine? O algoritmo CombineEsperto abaixo, que promete fazer o mesmo servio que Combine, evita essa construo. D um exemplo que mostra que CombineEsperto est errado. CombineEsperto (X, Y, a, p, r, dE , dD ) 1 d min{dE , dD } 2 para i p at r 1 faa 3 para j i + 1 at min{i + 7, r} faa 4 d Dist(X[a[i]], Y [a[i]], X[a[j]], Y [a[j]]) 5 se d < d 6 ento d d 7 devolva d

11

Fecho convexo de um conjunto de pontos

Dados pontos no plano, queremos encontrar o fecho convexo desses pontos. Uma aplicao deste problema se encontra em robtica. Se o fecho convexo de um rob no colide com obstculos ento o rob tambm no colide. Nos anos 60 uma aplicao da Bell Labs necessitava computar o fecho convexo de aproximadamente 10.000 pontos no plano e o consumo de tempo dos algoritmos disponveis era O(n2 ), onde n o nmero de pontos dados. Tendo esse problema como motivao, foi projetado o primeiro algoritmo com consumo de tempo O(n lg n) [Graham 1972]. Aqui esto descritos vrios algoritmos para esse problema.

3.1

O problema

Uma combinao convexa de uma coleo de pontos do plano representada por X[1 . . n], Y [1 . . n] uma soma da forma 1 (X[1], Y [1]) + + n (X[n], Y [n]), com i 0, para i = 1, . . . , k, e 1 + + n =1. O fecho convexo de uma coleo P de pontos do plano representada por X[1 . . n], Y [1 . . n] so os pontos do plano que so combinao convexa de pontos de P , ou seja,
conv(P ) := {1 (X[1], Y [1])+ +n (X[n], Y [n]) : 1 + +n = 1, e i 0 (i = 1, . . . , n)}.

Problema do fecho convexo. Dada uma coleo P de pontos do plano, determinar o fecho convexo de P . O prximo passo denir como representar nos algoritmos o fecho convexo de uma coleo de pontos. A representao natural pela coleo dos pontos extremos do fecho convexo. Seja P uma coleo de pontos do plano. Um ponto (x, y) de P extremo se (x, y) no combinao convexa de pontos de P {(x, y)}. Os pontos extremos da coleo P so os mesmos que os de conv(P ). Os algoritmos que apresentamos a seguir recebem X[1 . . n] e Y [1 . . n], representando uma coleo de pontos do plano, e devolvem um vetor H[1 . . h] com os ndices dos pontos extremos do fecho convexo da coleo na ordem em que aparecem na fronteira do fecho convexo quando a percorremos no sentido antihorrio. O vetor H[1 . . h] uma descrio combinatria do fecho convexo da coleo representada por X[1 . . n], Y [1 . . n].

12

(3, 4) (0, 3) (2, 2) (1, 1) (2, 0)


Os pontos de ndice 2, 4, 5, 7 e 8 so extremos.
X 1
1

3
2

2 2
3 4

1
5

2
6

4
7

0
8

(4, 2)

Y H

1
1

4
2

0 1 2
3 4 5

2
6

2
7

3
8

2
1

8
2

4
3

5
4

7
5

(2, 1)

(1, 2)

Uma coleo de pontos est em posio geral se ela no possui trs pontos colineares. Para simplicar, os algoritmos apresentados supem que a coleo de pontos dada est em posio geral.

3.2

Predicados geomtricos

Dados dois pontos (x1 , y1 ) e (x2 , y2 ), chamamos de reta orientada determinada por (x1 , y1 ) e (x2 , y2 ) a reta que passa por (x1 , y1 ) e (x2 , y2 ) e tem a orientao de (x1 , y1 ) para (x2 , y2 ). (x1 , y1 ) (x2 , y2 )

Os predicados geomtricos usados nos algoritmos desta seo so o Esquerda e o Direita. Dados trs pontos (x1 , y1 ), (x2 , y2 ) e (x3 , y3 ), o predicado Esquerda devolve verdadeiro se (x3 , y3 ) est esquerda da reta orientada determinada por (x1 , y1 ) e (x2 , y2 ), e falso caso contrrio. J o predicado Direita devolve verdadeiro se (x3 , y3 ) est direita da reta orientada determinada por (x1 , y1 ) e (x2 , y2 ), e falso caso contrrio. (3, 4) (0, 3) (4, 2)
Esquerda(1, 2, 3, 4, 0, 3) = verdadeiro Esquerda(1, 2, 3, 4, 4, 2) = falso Esquerda(3, 4, 1, 2, 4, 2) = verdadeiro Direita(1, 2, 3, 4, 0, 3) = falso Direita(1, 2, 3, 4, 4, 2) = verdadeiro

(2, 1)

(1, 2)

Direita(3, 4, 1, 2, 4, 2) = falso

O valor de Esquerda(x1 , y1 , x2 , y2 , x3 , y3 ) e Direita(x1 , y1 , x2 , y2 , x3 , y3 ) dado pelo sinal do determinante x1 x2 x3 y1 y2 y3 13 1 1 1 .

O valor deste determinante denotado por Det(x1 , y1 , x2 , y2 , x3 , y3 ) e seu valor absoluto duas vezes a rea do tringulo de pontas (x1 , y1 ), (x2 , y2 ) e (x3 , y3 ). Esquerda(x1 , y1 , x2 , y2 , x3 , y3 ) verdadeiro se e somente se esse determinante positivo, e Direita(x1 , y1 , x2 , y2 , x3 , y3 ) verdadeiro se e somente se ele negativo [Laszlo 1996]. Note que Det, Esquerda e Direita consomem tempo (1). Para que a apresentao seja mais leve, usamos uma variante do algoritmo Esquerda, que denotamos por Esq, que recebe uma coleo de pontos do plano representada por X[1 . . n], Y [1 . . n] e trs ndices, i, j e k entre 1 e n. Da mesma forma, temos um algoritmo Dir. Esq(X, Y, i, j, k) 1 devolva Esquerda(X[i], Y [i], X[j], Y [j], X[k], Y [k]) Dir(X, Y, i, j, k) 1 devolva Direita(X[i], Y [i], X[j], Y [j], X[k], Y [k])

3.3

Um algoritmo incremental

Este primeiro algoritmo iterativo e examina um ponto da coleo aps o outro. Ele mantm o fecho convexo dos pontos j examinados. A cada iterao, de posse do fecho convexo corrente, ele constri o fecho convexo incluindo o prximo ponto da coleo. O pseudocdigo a seguir, que implementa essa idia, recebe X[1 . . n] e Y [1 . . n], representando uma coleo de pelo menos trs pontos em posio geral, e devolve uma descrio combinatria H[1 . . h] do fecho convexo da coleo. As linhas de 1-3 do algoritmo Incremental constroem o fecho convexo dos trs primeiros pontos da coleo. O algoritmo Pertence recebe a descrio combinatria H[1 . . h] do fecho convexo de um subconjunto da coleo de pontos representada por X, Y e um ponto (x, y), e devolve verdadeiro se (x, y) est neste fecho e falso caso contrrio. O algoritmo InserePonto recebe a descrio combinatria H[1 . . h] do fecho convexo da coleo representada por X[1 . . k1], Y [1 . . k1] e devolve o fecho convexo da coleo representada por X[1 . . k], Y [1 . . k]. Incremental(X, Y, n) 1 se Esq(X, Y, 1, 2, 3) 2 ento H[1] 1 H[2] 2 H[3] 3 h 3 3 seno H[1] 1 H[2] 3 H[3] 2 h 3 4 para k 4 at n faa 5 se no Pertence(H, h, X, Y, X[k], Y [k]) 6 ento (H, h) InserePonto(H, h, X, Y, k) 7 devolva (H, h)

14

Abaixo est uma simulao das primeiras iteraes do algoritmo.


2 8 6 7

4 5

3 X Y H 2 8 6 7 1 3 4 5 H 3
1

1
1

3
2

2 2
3 4

1
5

2
6

4
7

0
8

1
1

4
2

0 1 2
3 4 5

2
6

2
7

3
8

1
1

3
2

2
3

2 8 6 7 1 3 4 5

2
2

4
3

3
1

2
2

4
3

5
4

O algoritmo est correto. Desde que Pertence e InserePonto estejam corretamente implementados, na linha 4, imediatamente antes de k ser comparado com n, H[1 . . h] uma descrio combinatria do fecho convexo da coleo representada por X[1 . . k1], Y [1 . . k1]. Portanto Incremental est correto. Consumo de tempo. O consumo de tempo do Incremental depende de Pertence e InserePonto. As implementaes destes que apresentamos frente consomem tempo (n) e O(h) respectivamente. Como h n, temos que Incremental consome tempo O(n2 ). Se todos os n pontos so extremos do fecho convexo, Incremental consome tempo (n2 ). A seguir, est uma implementao do algoritmo Pertence. Pertence(H, h, X, Y, x, y) 1 H[h+1] H[1] sentinela 2 para i 1 at h faa 3 se Direita(X[H[i]], Y [H[i]], X[H[i+1]], Y [H[i+1]], x, y) 4 ento devolva falso 5 devolva verdadeiro

15

2 8 6 1 3 5

X Y H

1
1

3
2

2 2
3 4

1
5

2
6

4
7

0
8

1
1

4
2

0 1 2
3 4 5

2
6

2
7

3
8

3
1

2
2

4
3

5
4

Pertence(H, 4, X, Y, 2, 2) = verdadeiro Pertence(H, 4, X, Y, 4, 2) = falso

O algoritmo Pertence est correto. A correo do algoritmo devida convexidade. Se um ponto no pertence ao fecho convexo, ento ele est direita de alguma de suas arestas. Consumo de tempo do Pertence. Este consumo (h). Agora, passemos descrio do algoritmo InserePonto. Como (X[k], Y [k]) no pertence ao fecho corrente, ele ponto extremo do prximo fecho. Ento, para atualizar o vetor H, precisamos determinar o sucessor e o predecessor de (X[k], Y [k]) na fronteira do prximo fecho. Considere que H[0] = H[h] e H[h+1] = H[1]. Seja i entre 1 e h tal que (X[k], Y [k]) ca direita do vetor que vai do ponto indicado por H[i1] para o indicado por H[i] e esquerda do vetor que vai do ponto indicado por H[i] para o ponto indicado por H[i+1]. O ponto de ndice H[i] o sucessor de (X[k], Y [k]). Seja j denido similarmente com esquerda e direita trocadas. O ponto de ndice H[j] o predecessor de (X[k], Y [k]). Com isso, o resultado de InserePonto(H, h, X, Y, k) o vetor F com o trecho de H de i at j circularmente, acrescido de k.

2 = H[i] 8 6 7 1

X Y H

1
1

3
2

2 2
3 4

1
5

2
6

4
7

0
8

1
1

4
2

0 1 2
3 4 5

2
6

2
7

3
8

3
1

2
2

4
3

5
4

3 4 5 = H[j] i = 2 e j = 4 na linha 9. Ao nal F 2


1

4
2

5
3

7
4

No bloco de linhas 1-8 do algoritmo InserePonto, determinamos os ndices i e j. No bloco de linhas 9-12, transcrevemos para F o trecho do fecho H[i . . j] circularmente e acrescentamos k.

16

InserePonto(H, h, X, Y, k) 1 H[0] H[h] H[h+1] H[1] sentinelas 2 i1 3 enquanto Esq(X, Y, H[i1], H[i], k) = Esq(X, Y, H[i], H[i+1], k) faa 4 i i+1 5 j i+1 6 enquanto Esq(X, Y, H[j1], H[j], k) = Esq(X, Y, H[j], H[j+1], k) faa 7 j j+1 8 se Esq(X, Y, H[i1], H[i], k) ento i j 9 t1 10 enquanto i = j faa 11 F [t] H[i] t t + 1 i (i mod h) + 1 12 F [t] H[i] t t + 1 F [t] k 13 devolva (F, t) O algoritmo est correto. O ponto (X[k], Y [k]) no est no fecho e os pontos esto em posio geral. Assim, existem exatamente dois ndices tais que 1 h e Esquerda(X, Y, H[1], H[], k) = Esquerda(X, Y, H[], H[+1], k). Estes ndices so o i e o j mencionados anteriormente, e so determinados pelo bloco de linhas 1-8. A linha 8 garante que H[i] o sucessor de k no sentido anti-horrio na fronteira do novo fecho. Consumo de tempo. O nmero de vezes que a linha 4 e a linha 7 so executadas no total no mximo h. Tambm a linha 11 executada no mximo h vezes. Assim o consumo de tempo do InserePonto O(h).

3.4

Algoritmo do embrulho de presente

Este algoritmo a verso para o plano de um mtodo que determina o fecho convexo para pontos em um espao de dimenso arbitrria [Chand and Kapur 1970, Jarvis 1973]. Intuitivamente, o algoritmo simula o enrolar da coleo de pontos por um barbante. A idia , a partir de um ponto extremo do fecho convexo, encontrar o prximo ponto extremo no sentido anti-horrio. Ela se baseia no fato de que em uma descrio combinatria do fecho convexo temos os ndices dos pontos extremos da coleo na ordem em que aparecem na fronteira do fecho convexo quando a percorremos no sentido anti-horrio.
2 8 6 1 3 4 5 Dir(X, Y, 5, 7, j) = falso para j = 1, . . . , 8 7 Y H X 1
1

3
2

2 2
3 4

1
5

2
6

4
7

0
8

1
1

4
2

0 1 2
3 4 5

2
6

2
7

3
8

4
1

5
2

?
3 4

...

17

Considere a descrio combinatria H[1 . . h] do fecho convexo de uma coleo de pontos X[1 . . n] e Y [1 . . n]. Para cada k entre 1 e h 1, temos que Dir(X, Y, H[k], H[k+1], j) = falso para j = 1, . . . , n. Este fato nos fornece uma maneira para, a partir do ponto extremo (X[H[k]], Y [H[k]]), determinar o ponto (X[H[k+1]], Y [H[k+1]]). O algoritmo Embrulho a seguir, que se apia nesta observao, recebe X[1 . . n] e Y [1 . . n], representando uma coleo de pelo menos dois pontos em posio geral, e devolve uma descrio combinatria H[1 . . h] do fecho convexo da coleo. Embrulho(X, Y, n) 1 h0 2 H[0] min{i [1 . . n] : X[i] X[j], 1 j n} 3 repita 4 i (H[h] mod h) + 1 qualquer ponto distinto de H[h] 5 para j 1 at n faa 6 se Dir(X, Y, H[h], i, j) ento i j 7 hh+1 8 H[h] i 9 at que i = H[0] fechou o polgono 10 devolva (H, h) O algoritmo est correto. Como os pontos esto em posio geral, H[0] calculado na linha 2 o ndice de um ponto extremo da coleo. Na linha 9, vale que H[1 . . h] so os h primeiros ndices que sucedem H[0] numa descrio combinatria do fecho convexo de X[1 . . n], Y [1 . . n]. Nas linhas 4-6, o algoritmo determina o sucessor do ponto de ndice H[h] na fronteira do fecho convexo no sentindo anti-horrio. Quando este sucessor o ponto de ndice H[0], signica que H[1 . . h] est completo. Consumo de tempo. Se h o nmero de pontos extremos do fecho convexo dos pontos X[1 . . n], Y [1 . . n], ento o bloco de linhas 4-8 executado h vezes. Para cada uma dessas h execues, a linha 6 executada n vezes. Portanto, o consumo de tempo do algoritmo (hn). Note que o consumo de tempo deste algoritmo depende no somente do nmero n de pontos dados, mas tambm do nmero de pontos h na descrio combinatria do fecho devolvida. Diz-se que um algoritmo como Embrulho para o qual o consumo de tempo depende do tamanho da resposta produzida output-sensitive. A seguir mostramos as duas prximas iteraes de Embrulho.

18

2 8 6 1 3 4 5 4 5 7 6 1 3 8

4
1

5
2

7
3

?
4

...
5

4
1

5
2

7
3

2
4

?
5

...
6

3.5

Algoritmo de Graham

Talvez o primeiro artigo em geometria computacional tenha sido o de Graham que apresenta um algoritmo O(n lg n) para encontrar o fecho convexo de um conjunto de n pontos no plano [Graham 1972, ORourke 1993]. O algoritmo de Graham faz um certo pr-processamento e posteriormente semelhante ao Incremental. Ele iterativo, examinando um ponto da coleo aps o outro, mantendo o fecho convexo dos pontos j examinados. O pr-processamento ordena os pontos de maneira que, em cada iterao, o ponto sendo examinado seja ponto extremo do novo fecho. Isso elimina a necessidade do Pertence. Com isso, a tarefa de cada iterao se restringe ao InserePonto. Alm disso, devido ao pr-processamento, o sucessor do ponto examinado sempre o primeiro ponto que o algoritmo examinou. O pr-processamento consiste no seguinte. Ordena-G(X, Y, n) 1 i min{i [1 . . n] : Y [i] Y [j], 1 j n} 2 (X[1], Y [1]) (X[i], Y [i]) 3 MergeSort-G(X, Y, 2, n) Depois da linha 2, o ponto (X[1], Y [1]) extremo. Considere uma ordem total dos pontos (X[2], Y [2]), . . . , (X[n], Y [n]) em que (X[i], Y [i]) (X[j], Y [j]) se o ponto (X[i], Y [i]) est direita da reta orientada determinada por (X[1], Y [1]) e (X[j], Y [j]). O MergeSort-G rearranja os vetores X[2 . . n] e Y [2 . . n] de modo que (X[2], Y [2]) (X[n], Y [n]). Ele pode ser implementado com o MergeSort usando como funo de comparao a seguinte rotina, que recebe X, Y e dois ndices i e j entre 2 e n, e devolve verdadeiro se o ponto (X[i], Y [i]) considerado menor que (X[j], Y [j]): Menor-G(X, Y, i, j) 1 devolva Dir(X, Y, 1, j, i)

19

3 7 5 6 4 8 1 Y 2 X 1
1

3
2

2 2
3 4

2
5

1
6

4 1
7 8

1
1

4
2

0 1 2
3 4 5

2
6

2
7

3
8

Menor-G(X, Y, 2, j) = verdadeiro para j = 3, . . . , 8

O algoritmo Graham recebe X[1 . . n] e Y [1 . . n], representando uma coleo de pelo menos trs pontos do plano em posio geral, e devolve uma descrio combinatria H[1 . . h] do fecho convexo da coleo. Graham(X, Y, n) 1 Ordena-G(X, Y, n) 2 H[1] 1 H[2] 2 H[3] 3 h 3 3 para k 4 at n faa 4 jh 5 enquanto Esq(X, Y, H[j], H[j1], k) faa 6 j j1 7 h j + 1 H[h] k 8 devolva (H, h) A seguir esto as primeiras iteraes de Graham para o exemplo anterior.
3 7 5 6 4 4 8 1 H 1
1

3 7 2 5 6 2

8 1 H 3 7 5 6 4 2 7 5 6 4 8 1 1 H 1
1

2
2

3
3

1
1

2
2

3
3

4
4

1
1

2
2

3
3

5
4

2
2

3
3

5
4

6
5

20

3 7 5 6

Esq(X, Y, 6, 5, 7) = verdadeiro H 2 1
1

2
2

3
3

5
4

\ 6
5

Esq(X, Y, 5, 3, 7) = verdadeiro 4 H 1
1

2
2

3
3

\ 5
4

8 1 Esq(X, Y, 3, 2, 7) = falso H 1
1

2
2

3
3

7
4

O algoritmo est correto. Note que o Graham uma implementao mais esperta do Incremental. Para mostrar que ele est correto, basta vericar que a cada passagem pela linha 3, imediatamente antes da comparao de k com n, H[1 . . h] uma descrio combinatria do fecho convexo da coleo representada por X[1 . . k1], Y [1 . . k1]. Este invariante mostra que Graham est correto, pois na ltima passagem pela linha 3 temos k = n + 1. O invariante vale pela seguinte razo. Primeiro, H[1 . . 3] uma descrio combinatria do fecho dos trs primeiros pontos, j que estes esto ordenados conforme o pr-processamento. Agora suponha que H[1 . . h] seja a descrio combinatria do fecho convexo de X[1 . . k1], Y [1 . . k1] para k n. Devido a Ordena-G e hiptese da coleo estar em posio geral, (X[k], Y [k]) ponto extremo do novo fecho e (X[1], Y [1]) o seu sucessor na fronteira do novo fecho convexo no sentindo anti-horrio. O ndice k adicionado na posio correta de H na linha 7. Devido a Ordena-G e hiptese da coleo estar em posio geral, sabemos que Esq(X, Y, 1, H[h], k) = verdadeiro. Assim, adaptando as linhas 3-8 do Incremental, o predecessor dado pelo maior j tal que Esq(X, Y, H[j], H[j1], k) = falso. A tarefa de determinar esse j feita pelas linhas 4-6. Consumo de tempo. A linha 1 consome tempo (n lg n). Na linha 3 do algoritmo, h 3. A linha 6 executada n 3 vezes. Assim, o nmero de vezes que h decrementado na linha 5 no superior a n 3. Portanto o bloco de linhas 2-7 consome tempo (n), e o consumo de tempo do Graham dominado pelo consumo de tempo da linha 1, que (n lg n).

3.6

Quickhull

possvel tratar geometria computacional como o estudo de problemas de busca e ordenao em dimenses maiores [Mulmuley 1994]. De fato, em um certo sentido, problemas de ordenao e busca em uma lista de elementos de um universo ordenado podem ser vistos como verses unidimensionais de alguns problemas em geometria computacional em dimenses maiores. Deste

21

ponto de vista, no nenhuma surpresa o fato de que algoritmos de ordenao e busca sejam uma constante fonte de inspirao para o projeto de algoritmos em geometria computacional. O algoritmo apresentado nesta seo foi proposto independentemente, com algumas variaes, por vrias pessoas quase ao mesmo tempo [Eddy 1977, Bykat 1978, Green and Silverman 1979]. Devido semelhana com o QuickSort, este algoritmo foi batizado de QuickHull [Preparata and Shamos 1985]. A idia bsica por trs do QuickHull que, para a maioria dos conjuntos de pontos, fcil descartar muitos pontos que esto no interior do fecho convexo e concentrar o trabalho nos pontos que esto prximos da fronteira.

A semelhana com o QuickSort vem do fato de que o QuickHull processa os pontos, montando duas colees de pontos basicamente disjuntas, onde o problema resolvido recursivamente. A partir dos fechos convexos destas duas colees, o fecho convexo da coleo dada obtido facilmente. A seguir, descrevemos uma rotina que chamamos de Particione, que faz esse trabalho de montar as duas colees. Vale ressaltar que essas duas colees no formam, como no caso do QuickSort, uma partio da coleo dada de pontos. A rotina detecta pontos da coleo que esto no interior do fecho, e no os inclui em nenhuma das duas colees montadas. Antes de apresentar o Particione, exibimos duas rotinas usadas nele. Lembre-se que Det(x1 , y1 , x2 , y2 , x3 , y3 ) o valor do determinante da pgina 13, cujo valor absoluto duas vezes a rea do tringulo de pontas (x1 , y1 ), (x2 , y2 ) e (x3 , y3 ). Considere a rotina rea (X, Y, i, j, k) 1 devolva |Det(X[i], Y [i], X[j], Y [j], X[k], Y [k])|/2 que devolve a rea do tringulo cujas pontas so os pontos da coleo de ndices i, j e k. O algoritmo abaixo recebe uma coleo de pelo menos trs pontos X[p . . r], Y [p . . r] em posio geral e, usando rea, devolve o ndice de um ponto extremo da coleo distinto de p e r. Este algoritmo ser usado no algoritmo Particione.

22

PontoExtremo (X, Y, p, r) 1 q p + 1 max rea(X, Y, p, r, q) 2 para i p + 2 at r 1 faa 3 se rea(X, Y, p, r, i) > max 4 ento q i max rea(X, Y, p, r, q) 5 devolva q O algoritmo PontoExtremo est correto. O algoritmo devolve o ndice de um ponto da coleo mais distante da reta que passa por (X[p], Y [p]) e (X[r], Y [r]). Este claramente um ponto extremo, j que a coleo est em posio geral. Um ponto mais distante da reta que passa pelos pontos (X[p], Y [p]) e (X[r], Y [r]) forma um tringulo de maior altura tendo (X[p], Y [p]) e (X[r], Y [r]) como base.
5 7 X 8 6 9 Y 2 2
1 2

3
3

0
4

1
5

1 1
6 7

2
8

4
9

2 1
1 2

4 1
3 4

4
5

1
6

3
7

2
8

2
9

4 1

PontoExtremo(X, Y, 1, 9) = 7

Como a rea de um tringulo metade do produto do comprimento de sua base por sua altura, e os tringulos considerados tm todos a mesma base, ento um ponto que forma um tringulo de maior altura um cujo tringulo tem a maior rea. PontoExtremo simplesmente encontra um tal ponto. Consumo de tempo de PontoExtremo. fcil ver que PontoExtremo consome tempo (n), onde n := r p + 1. O algoritmo Particione recebe uma coleo de pelo menos trs pontos X[p . . r], Y [p . . r] em posio geral tal que os pontos de ndice p e r so extremos consecutivos na fronteira do fecho convexo da coleo no sentindo anti-horrio. Ele rearranja X[p . . r], Y [p . . r] e devolve ndices p e q tais que p p < q < r e (i) o ponto de ndice r permaneceu na mesma posio, enquanto que o ponto de ndice p foi para a posio p , (ii) o ponto de ndice q extremo, (iii) X[p . . p 1], Y [p . . p 1] uma coleo de pontos interiores ao fecho convexo da coleo X[p . . r], Y [p . . r]. (iv) X[p +1 . . q1], Y [p +1 . . q1] a coleo dos pontos que esto esquerda da reta orientada determinada por (X[p ], Y [p ]) e (X[q], Y [q]). (v) X[q+1 . . r1], Y [q+1 . . r1] a coleo dos pontos que esto esquerda da reta orientada determinada por (X[q], Y [q]) e (X[r], Y [r]). 23

Particione (X, Y, p, r) 1 q PontoExtremo(X, Y, p, r) 2 (X[q], Y [q]) (X[p+1], Y [p+1]) 3 p r q r 4 para k r 1 decrescendo at p + 2 faa 5 se Esq(X, Y, p, p+1, k) 6 ento p p 1 (X[p ], Y [p ]) (X[k], Y [k]) 7 seno se Esq(X, Y, p+1, r, k) 8 ento q q 1 (X[q], Y [q]) (X[k], Y [k]) 9 p p 1 (X[k], Y [k]) (X[p ], Y [p ]) 10 q q 1 (X[q], Y [q]) (X[p+1], Y [p+1]) 11 p p 1 (X[p ], Y [p ]) (X[p+1], Y [p+1]) 12 p p 1 (X[p ], Y [p ]) (X[p], Y [p]) 13 devolva (p , q) A seguir mostramos uma simulao de uma chamada do Particione.
5 7 8 6 9 X Y 1 p q r 4
9

3 Particione(X, Y, 1, 9) p q r 4
9

p p+1 2 1 3
1 2 3

0
4

1
5

1 2
6 7

k 2
8

2
1

3
2

4 1
3 4

4
5

1 1
6 7

2
8

2
9

X Y

p 2 1
1 2

3
3

0
4

1
5

k 1 2
6 7

2
8

X Y

p 2 1
1 2

3
3

0
4

1
5

k 1
6

p 2 2
7 8

q r 4
9

2
1

3
2

4 1
3 4

4
5

1 1
6 7

2
8

2
9

2
1

3
2

4 1
3 4

4
5

1
6

2 1
7 8

2
9

X Y

p 2 1
1 2

3
3

0
4

k 1
5

1
6

p 2 2
7 8

q r 4
9

X Y

p 2 1
1 2

3
3

k 0
4

2
5

p 1 2
6 7

q 1
8

r 4
9

2
1

3
2

4 1
3 4

4
5

1
6

2 1
7 8

2
9

2
1

3
2

4 1
3 4

2
5

1 1
6 7

4
8

2
9

X Y

p 2 1
1 2

k 3
3

1
4

2
5

p 0 2
6 7

q 1
8

r 4
9

X Y

p k 2 1
1 2

2
3

p 1 2
4 5

0
6

q 3
7

1
8

r 4
9

2
1

3
2

4
3

1
4

2 1 1
5 6 7

4
8

2
9

2
1

3
2

2
3

1 1 1
4 5 6

4
7

4
8

2
9

24

X Y

p 2
1

1
2

2
3

p q 0 2 1
4 5 6

3
7

1
8

r 4
9

X Y

p 2
1

1
2

p 2
3

q 0 2 1
4 5 6

3
7

1
8

r 4
9

2
1

1
2

2 1 1
3 4 5

3
6

4
7

4
8

2
9

2
1

1 2 1 1
2 3 4 5

3
6

4
7

4
8

2
9

O algoritmo Particione est correto. O item (i) vale pois o ponto de ndice r no trocado de lugar e o de ndice p trocado apenas na linha 12, pelo de ndice p . O item (ii) vale pela especicao do PontoExtremo e pelas linhas 2 e 10. A cada passagem pela linha 4, imediatamente antes da comparao de k com p + 2, pode-se demonstrar que valem os seguintes invariantes: p + 1 k < p q r, os pontos de ndice p+1 e r so extremos consecutivos na fronteira do fecho convexo de X[q . . r], Y [q . . r] acrescido de (X[p+1], Y [p+1]) no sentindo anti-horrio, os pontos de ndice p e p+1 so extremos consecutivos na fronteira do fecho convexo de X[p . . q1], Y [p . . q1] acrescido de (X[p], Y [p]) e (X[p+1], Y [p+1]) no sentindo anti-horrio, os pontos da coleo X[k+1 . . i1], Y [k+1 . . i1] so interiores ao fecho convexo de X[p . . r], Y [p . . r]. No incio da ltima iterao, k = p+1. Portanto esses invariantes e as linhas 1012 garantem que, ao nal, X, Y , p e q satisfazem (ii)-(v). O primeiro invariante e o fato dos vetores X e Y serem alterados apenas por trocas simultneas nos vetores X e Y implicam que a coleo X[p . . r], Y [p . . r] ao nal tem os mesmos pontos que no incio. Consumo de tempo de Particione. Seja n := r p + 1. A linha 1 consome tempo (n). As linhas 2,3 e 10-13 consomem tempo (1). O bloco de linhas 5-9 executado n 3 e cada execuo consome tempo (1). Logo o consumo de tempo de Particione (n). Com isso, ca fcil descrever o QuickHull. Ele consiste em um prprocessamento e uma chamada ao algoritmo recursivo QuickHullRec, que o semelhante ao QuickSort. O algoritmo QuickHullRec recebe uma coleo de pelo menos dois pontos X[p . . r], Y [p . . r] em posio geral tal que os pontos de ndices p e r so extremos e os pontos X[p+1 . . r1], Y [p+1 . . r1] esto esquerda da reta orientada determinada por (X[p], Y [p]) e (X[r], Y [r]) e devolve a descrio combinatria do fecho convexo de X[p . . r], Y [p . . r] que comea de r. O algoritmo QuickHull recebe uma coleo de pontos X[1 . . n], Y [1 . . n] em posio geral e devolve uma representao combinatria do seu fecho convexo.

25

QuickHull (X, Y, n) 1 se n = 1 2 ento h 1 H[1] 1 3 seno k min{i [1 . . n] : Y [i] Y [j], 1 j n} 4 (X[1], Y [1]) (X[k], Y [k]) 5 i2 6 para j 3 at n faa 7 se Dir(X, Y, 1, i, j) ento i j 8 (X[n], Y [n]) (X[i], Y [i]) 9 (H, h) QuickHullRec(X, Y, 1, n, H, h) 10 devolva (H, h) O algoritmo QuickHull est correto. As linhas 3-4 rearranjam X e Y de modo que na posio 1 que um ponto com coordenada Y mnima. Tal ponto extremo pois a coleo dada est em posio geral. As linhas 5-7 so semelhantes a uma iterao de Embrulho, onde se busca o prximo ponto extremo do fecho, caso a coleo tenha pelo menos dois pontos. Ou seja, o ndice i imediatamente antes da linha 8 o ndice do sucessor de (X[1], Y [1]) na descrio combinatria do fecho convexo da coleo. A linha 8 coloca na posio n este ponto extremo. Com isso, X[1 . . n], Y [1 . . n] na linha 9 satisfaz a especicao de QuickHullRec. Desde que QuickHullRec esteja correto, o vetor H na linha 10 contm uma descrio combinatria do fecho convexo de X[1 . . n], Y [1 . . n]. Consumo de tempo de QuickHull. As linhas 1-8 consomem tempo (n). J, como veremos a seguir, o algoritmo QuickHullRec consome tempo O(n2 ), onde n := r p + 1. Portanto, QuickHull consome tempo O(n2 ). O QuickHullRec recursivo. QuickHullRec (X, Y, p, r) 1 se p = r 1 h exatamente dois pontos na coleo 2 ento h 2 H[1] r H[2] p 3 seno (p , q) Particione(X, Y, p, r) 4 (H1 , h1 ) QuickHullRec(X, Y, q, r, H, h) 5 (H2 , h2 ) QuickHullRec(X, Y, p , q, H, h)
H H1 H2 removendo uma cpia do q

6 7 8 9 10 11

h0 para i 1 at h1 faa h h + 1 H[h] H1 [i] para i 2 at h2 faa h h + 1 H[h] H2 [i] devolva (H, h)

26

5 7 8 6

3 X Y H1

p 2
1

1
2

p 2
3

q 0 2 1
4 5 6

3
7

1
8

r 4
9

2
1

1 2 1 1
2 3 4 5

3
6

4
7

4
8

2
9

9
1

3
2

5
3

7
4

4 1

H2 H

7
1

2
2

1
3

9
1

3
2

5
3

7
4

2
5

1
6

O algoritmo QuickHullRec est correto. A correo do QuickHullRec vericada por induo no nmero n := r p + 1 de pontos. evidente, pelas linhas 1-2, que o algoritmo d a resposta correta quando h apenas dois pontos na coleo. Suponha portanto que a coleo tem pelo menos trs pontos. Neste caso, o algoritmo executa o bloco de linhas 2-12. O Particione rearranja X[p . . r], Y [p . . r] e devolve dois ndices p e q entre p e r tais que (i)-(v) valem. Pelo (iii) da especicao do Particione, os pontos que no esto nas colees das chamadas recursivas no so extremos e portanto so irrelevantes. Por (ii), o ponto de ndice q extremo, e os demais pontos extremos esto particionados entre as duas colees de modo que a concatenao das descries combinatrias devolvidas, removida uma das cpias do q, formam uma descrio combinatria do fecho da coleo dada. Consumo de tempo de QuickHull. O consumo de tempo de QuickHullRec medido em relao ao nmero n := r p + 1 de pontos na coleo X[p . . r], Y [p . . r]. Seja T (n) o tempo consumido pelo algoritmo QuickHullRec quando aplicado a uma coleo de n pontos. A linha 3 consome tempo (n). O tempo consumido pelo bloco de linhas 6-12 proporcional ao nmero de pontos extremos da coleo. Como esse nmero no mximo n, ento o consumo de tempo desse bloco de linhas O(n). Portanto, T (n) = T (n1 ) + T (n2 ) + (n),

(2)

onde n1 := q p + 1 e n2 := r q + 1. O termo T (n1 ) corresponde ao consumo de tempo da linha 4 e o termo T (n2 ), ao consumo da linha 5. Vale que n1 + n2 = r p + 2 e tambm que n1 2 e n2 2 (por qu?). Do invariante (i) e das linhas 11-12 de Particione, temos que p p, logo n1 + n2 n + 1. A funo T (n) est em O(n2 ) (Exerccio 4). Ou seja, o algoritmo QuickHullRec consome tempo O(n2 ).

Exerccios
1. Quanto vale o determinante da pgina 13 quando (x1 , y1 ), (x2 , y2 ), e (x3 , y3 ) so colineares? 2. Calcule os determinantes associados s chamadas de Esquerda do exemplo da pgina 13. 27

3. Escreva uma verso do algoritmo InserePonto que funciona mesmo que a coleo dada de pontos no esteja em posio geral. Simule o Incremental com o seu algoritmo InserePonto para a coleo abaixo: X 0
1

1
2

2
3

4
4

2
5

6
6

0
1

1
2

2
3

0
4

0
5

0
6

4. Mostre que T (n) est em O(n2 ). [A ser completado.] 5. Mostre uma coleo de n pontos, para n arbitrrio, para a qual o algoritmo QuickHull consome tempo (n2 ) para dar sua resposta.

Interseo de segmentos

Um dos problemas mais bsicos em geometria computacional o de detectar interseo. O clculo de intersees d no plano e no espao 3-dimensional uma operao bb sica em diversas reas. Em robtica e planejamento de e a movimento, importante sabermos quando dois objetos c se intersectam para evitarmos colises. Em computao grca, ray shooting um mtodo importante para o processamento digital de cenas, e a parte deste que consome mais tempo justamente determinar intersees entre o raio e os outros objetos.

4.1

O problema

Muitos problemas complexos de interseo so decompostos em problemas mais simples. Apresentamos nesta seo um algoritmo para uma verso bem simples de problema de interseo. Problema de interseo de segmentos. Dada uma coleo de segmentos no plano, decidir se existem dois segmentos na coleo que se intersectam. Uma coleo de n segmentos no plano representada por dois vetores e[1 . . n] e d[1 . . n] de pontos. A coordenada do ponto e[i] (eX [i], eY [i]) e do ponto d[i] (dX [i], dY [i]).

28

4 3 2 5 1 6

eX eY dX dY

6 2 3 3 1 4 1 2 3 8 7 1 1 3 2 2 4 3

0 6 4 5 8 4

3 5 5 7 0 5

4 1 6 9 2 6

fcil projetar um algoritmo que resolve esse problema e consume tempo (n2 ). Como j vimos, s vezes considerar o problema em um espao de dimenso menor nos ajuda a encontrar um algoritmo mais rpido para espaos de dimenso maior. Vamos ento fazer um desvio e pensar no problema quando os segmentos dados esto em uma reta.

4.2

Interseo de intervalos

Quando os segmentos dados esto numa reta, podemos pensar neles simplesmente como intervalos. Cada intervalo pode ser dado por um par de nmeros. Usamos dois vetores eX [1 . . n] e dX [1 . . n] para representar os n intervalos [eX [1] . . dX [1]], . . . , [eX [n] . . dX [n]]. O seguinte algoritmo decide se h interseo entre dois dos intervalos dados, supondo que os pontos extremos so todos distintos. Varredura(e, d, n) 1 para i 1 at n faa para cada intervalo 2 E[i] eX [i] esq[i] verdadeiro extremo 3 E[i + n] dX [i] esq[i + n] falso extremo 4 MergeSort(E, esq, 1, 2n) 5 cont 0 resp falso 6 para p 1 at 2n faa para cada ponto extremo 7 se esq[p] 8 ento cont cont + 1 9 se cont = 2 ento resp verdadeiro 10 seno cont cont 1 11 devolva resp

esquerdo direito

Aps as linhas 1-3, o valor de esq[p] indica se o nmero E[p] o extremo esquerdo de um intervalo da coleo. A linha 4 rearranja simultaneamente os vetores E[1 . . 2n] e esq[1 . . 2n] de modo que E[1] < < E[2n]. Imagine uma formiga que comea a caminhar para a direita a partir do ponto extremo mais esquerda. Para saber se h interseo entre dois dos intervalos, cada vez que a formiga encontra o extremo esquerdo de um intervalo, ela incrementa um contador que indica o nmero de intervalos que contm o ponto em que ela est. Se o contador assume o valor 2, ento h um ponto em dois dos intervalos dados. Assim h na coleo dois intervalos que se intersectam. O algoritmo acima implementa esta idia. Perceba que o valor do contador

29

alterado apenas quando a formiga passa por um extremo de um dos intervalos dados.
eX 10 1 0 2 18 3 dX 16 1 7 2 22 3 Varredura(eX , dX , 3) = falso

E[i] esq[i] cont


eX 10 1 0 2 16 3

10

16 18

22

V
1

F
0

V
1

F V
0 1

F
0

dX

18 1

7 2

22 3

Varredura(eX , dX , 3) = verdadeiro

E[p] 0 esq[p] V cont 1

10

16 18

22

F
0

V
1

V F
2 1

F
0

O consumo de tempo de Varredura (n lg n) por causa da linha 4. As demais linhas consomem tempo (n). Este algoritmo um exemplo simples de aplicao de um mtodo mais geral e poderoso que passamos a descrever.

4.3

Mtodo da linha de varredura

No mtodo da linha de varredura (sweepline), uma linha imaginria, digamos vertical, move-se da esquerda para a direita. A medida que a linha prossegue, o problema restrito aos objetos que caram esquerda dela resolvido. Toda a informao da parte do problema que est esquerda da linha, e que necessria para estender a soluo parcial corrente, mantida numa descrio combinatria da linha de varredura. Apesar da metfora da linha mover-se continuamente da esquerda para a direita, a sua descrio combinatria muda apenas em posies chaves, chamadas de pontos eventos. Podemos imaginar que a linha de varredura avana de ponto evento em ponto evento, da esquerda para a direita. Pontos eventos so ento mantidos em uma la, que usualmente uma lista ordenada de acordo com o valor da coordenada X dos pontos. Esta la d a ordem em que estes pontos devem ser processados. Em algumas aplicaes, a la de eventos est completamente denida no instante inicial do algoritmo. Em outras, novos pontos eventos podem ser detectados e inseridos na la a medida que a linha avana. No algoritmo Varredura, a formiga faz o papel da linha de varredura e o contador a descrio combinatria da informao necessria naquele caso. Cada extremo de um intervalo um ponto evento. O tratamento de cada ponto evento consiste tipicamente nas seguintes tarefas: 30

Atualizar a la: remover o ponto evento corrente, junto com qualquer outro que tenha se tornado obsoleto e, eventualmente, inserir novos pontos eventos na la; Atualizar a linha: atualizar a descrio combinatria da linha de varredura para que esta represente a situao atual; Resolver o problema: estender a soluo corrente. A la de eventos de Varredura consiste em E[i . . 2n], a atualizao da linha feita nas linhas 8 e 10, quando cont ajustado, e a atualizao da soluo do problema feita quando a varivel resp eventualmente alterada na linha 9. O mtodo da linha de varredura reduz um problema esttico bidimensional a um problema dinmico unidimensional: o problema de manter a descrio combinatria da linha. O problema unidimensional resultante geralmente mais simples que o problema bidimensional original. Veremos duas aplicaes do mtodo: a primeira para o problema da interseo de segmentos no plano e a segunda para um problema de partio de polgonos.

4.4

Predicado geomtrico

O predicado geomtrico usado no principal algoritmo desta seo o Intersecta. Ele usa um dos predicados introduzidos na Subseo 3.2. O Intersecta recebe dois segmentos e devolve verdadeiro se os segmentos se intersectam, e falso caso contrrio. Intersecta(x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 ) 1 se Esquerda(x1 , y1 , x2 , y2 , x3 , y3 ) = Esquerda(x1 , y1 , x2 , y2 , x4 , y4 ) 2 e Esquerda(x3 , y3 , x4 , y4 , x1 , y1 ) = Esquerda(x3 , y3 , x4 , y4 , x2 , y2 ) 3 ento devolva verdadeiro 4 seno devolva falso
Esquerda(1, 2, 4, 2, 2, 1) = falso
4 3 2 1

Esquerda(1, 2, 4, 2, 3, 4) = verdadeiro Esquerda(2, 1, 3, 4, 1, 2) = verdadeiro Esquerda(2, 1, 3, 4, 4, 2) = falso Intersecta(1, 2, 4, 2, 2, 1, 3, 4) = verdadeiro Esquerda(3, 4, 6, 1, 1, 2) = falso
1 2 3 4 5 6

Esquerda(3, 4, 6, 1, 4, 2) = falso Intersecta(1, 2, 4, 2, 3, 4, 6, 1) = falso

Para melhorar a legibilidade, temos a seguinte variante do Intersecta, que recebe uma coleo e[1 . . n], d[1 . . n] de segmentos e dois ndices i e j, e devolve verdadeiro se os segmentos de ndices i e j da coleo se intersectam, e falso caso contrrio.

31

Inter(e, d, i, j) 1 devolva Intersecta(eX [i], eY [i], dX [i], dY [i], eX [j], eY [j], dX [j], dY [j])

4.5

Algoritmo de Shamos e Hoey

Uma idia natural para projetar um algoritmo eciente evitar o teste de interseo entre pares de segmentos que no tem chance de se intersectar. Como podemos fazer isto? Primeiro, pode-se eliminar os casos fceis. Dois segmentos cuja projeo no eixo X sejam disjuntas no se intersectam. Abaixo, os segmentos de ndices 2 e 5 no precisam ser submetidos ao teste de interseo.

4 3 2 5 1 6 3 2

4 1 5 6

Se a projeo no eixo X de dois segmentos tem interseo, ento h uma linha vertical que intersecta ambos. Para determinarmos estes pares de segmentos, usamos o mtodo da linha de varredura. Imaginamos uma linha vertical varrendo o plano da esquerda para a direita. Enquanto a linha varre o plano, mantemos todos os segmentos intersectados por ela na descrio combinatria da linha. Estes so os candidatos a realizarmos o teste de interseo. Os segmentos que intersectam a linha pontilhada mais esquerda na gura acima so {4, 5, 6}. Infelizmente, fazer o teste de interseo entre cada dois segmentos que so simultaneamente intersectados pela linha de varredura ainda resultaria num algoritmo que consome tempo (n2 ) no pior caso, pois a linha pode intersectar (n) segmentos simultaneamente. A segunda observao que, se mantivermos os segmentos na ordem em que intersectam a linha de varredura, ento basta, como veremos, realizarmos o teste de interseo entre pares de segmentos que so consecutivos nesta ordem em algum momento. O algoritmo que vamos apresentar nesta subseo implementa essa idia [Shamos and Hoey 1976]. Quando a linha de varredura a reta x = t, a ordem t em que os segmentos intersectados pela linha so mantidos a seguinte. Para dois segmentos de ndices i e j intersectados pela linha, i t j se o ponto de interseo da linha com o segmento i ca abaixo do ponto de interseo com o segmento j. No exemplo acima, 6 5 5 5 4 e 5 7 6 7 1. A descrio combinatria da linha esta ordem, que alterada apenas quando a linha atinge um ponto extremo de um dos segmentos ou um ponto de interseo entre segmentos. No entanto, o algoritmo aqui apresentado para assim que detecta o primeiro ponto de interseo. Logo, a descrio combinatria da linha ser alterada apenas em pontos extremos.

32

Usamos uma rvore de busca binria balanceada (ABBB) T para representar a descrio combinatria da linha. Mais precisamente, T representa a ordem t quando a linha de varredura for a reta x = t, ou seja, os segmentos armazenados em T so exatamente aqueles que intersectam a reta x = t e eles esto armazenados de acordo com a ordem t .
3 8 1 7 5 6
9

6572183 1 2
9

5 3 6 7 5 2 1 8 3

6 5 7 2 8

O algoritmo utiliza as seguintes rotinas de manipulao de uma ABBB: Crie(T ): cria uma ABBB T vazia; Insira(T, i): insere i na ABBB T , usando t com t = eX [i]; Remova(T, i): remove i da ABBB T , usando t com t = dX [i]; Predecessor(T, x, y): devolve o predecessor em T de um segmento que passa pelo ponto (x, y), usando x ; Sucessor(T, x, y): devolve o sucessor em T de um segmento que passa pelo ponto (x, y), usando x . O consumo de tempo de cada uma destas rotinas O(lg m), onde m o nmero de elementos em T [Cormen et al. 2001]. O algoritmo Interseo-SH recebe uma coleo e[1 . . n], d[1 . . n] de segmentos, e devolve verdadeiro se h dois segmentos na coleo que se intersectam, e falso caso contrrio. Para simplicar, Interseo-SH supe que no h dois pontos extremos com a mesma coordenada X e no h dois segmentos que se intersectam em mais do que um ponto. Ou seja, casos como os abaixo no so tratados.
eX eY 1 1 2 3 1 3 1 2 3 1 4 1 1 2 2 2 3 3 1 2 4 4 2 4 1 1 5 4 1 5 2 1 6 6 1 6

3 2

1 4 5 6
dX dY

O algoritmo Interseo-SH utiliza uma rotina FilaDeEventos que recebe os vetores e[1 . . n] e d[1 . . n] de pontos, representando uma coleo de n 33

segmentos, e troca e[i] por d[i] para todo i tal que eX [i] > dX [i], de modo que e[i] indique o extremo esquerdo do segmento i e d[i] indique o direito. Alm disso, Interseo-SH devolve um vetor E[1 . . 2n], com os pontos de e[1 . . n] e d[1 . . n] ordenados pelas suas coordenadas X, um vetor segm[1 . . 2n] onde segm[p] o ndice do segmento da coleo do qual E[p] extremo, e um vetor booleano esq[1 . . 2n] onde esq[p] verdadeiro se E[p] o extremo esquerdo do segmento de ndice segm[p] da coleo, e falso caso contrrio. O consumo de tempo de FilaDeEventos (n lg n). FilaDeEventos(e, d, n) 1 para i 1 at n faa para cada segmento 2 se eX [i] > dX [i] ento e[i] d[i] 3 E[i] e[i] segm[i] i esq[i] verdadeiro 4 E[i + n] d[i] segm[i + n] i esq[i + n] falso 5 MergeSort(E, segm, esq, 1, 2n) 6 devolva (E, segm, esq) Para o exemplo do incio desta subseo, os vetores E, segm e esq devolvidos pela rotina FilaDeEventos seriam
EX EY 2 1 3 1 1 2 3 1 v 1 2 2 v 2 1 4 3 1 3 v 3 1 2 4 2 4 f 4 2 4 5 4 5 v 5 2 3 6 3 6 f 6 2 1 7 6 7 v 7 3 5 8 1 8 f 8 3 2 9 5 9 v 9 4 2 10 4 10 f 10 5 0 11 5 11 f 11 6 1 12 6 12 f 12

segm

esq

Interseo-SH(e, d, n) 1 (E, segm, esq) FilaDeEventos(e, d, n) 2 Crie(T ) 3 para p 1 at 2n faa 4 i segm[p] 5 pred Predecessor(T, EX [p], EY [p]) 6 suc Sucessor(T, EX [p], EY [p]) 7 se esq[p] 8 ento Insira(T, i) 9 se (pred = nil e Inter(e, d, i, pred)) ou (suc = nil e Inter(e, d, i, suc)) 10 ento devolva verdadeiro 11 seno Remova(T, i) 12 se pred = nil e suc = nil e Inter(e, d, pred , suc) 13 ento devolva verdadeiro 14 devolva falso O algoritmo est correto. evidente que se o algoritmo devolve verdadeiro ento essa resposta correta: h interseo entre dois dos segmentos. Assim, se no h interseo entre dois dos segmentos da coleo, o 34

algoritmo devolve falso. Falta ento mostrar que, sempre que h dois segmentos que se intersectam na coleo, ele devolve verdadeiro. Depois da linha 1, vale que E[1], . . . , E[2n] so todos os pontos extremos dos segmentos da coleo e EX [1] EX [2n]. Seja E[0] um ponto arbitrrio esquerda do ponto E[1]. Para um nmero t, denotamos por t+ a ordem induzida pela linha de varredura assim que ela passou da reta x = t. A cada passagem pela linha 4, valem os seguintes invariantes: T representa a ordem t+ onde t = EX [p 1]; j foram submetidos ao teste de interseo todos os segmentos que so consecutivos em t+ para t = EX [1], . . . , EX [p]. O primeiro invariante decorre do teste da linha 7, que detecta se a linha de varredura atingiu o comeo ou o m do segmento i, denido na linha 4, e das linhas 8 e 11, que atualizam T adequadamente. O segundo invariante decorre do seguinte. Se i inserido em T , a linha 9 faz o teste de i com os segmentos consecutivos na ordem t com t = EX [p], isto , seu predecessor e seu sucessor em t , se existirem. Como no h dois pontos extremos com a mesma coordenada X, temos que neste caso t =t+ . Se i removido de T , a linha 12 testa a interseo entre o predecessor e o sucessor de i em t , se ambos existirem. Estes dois segmentos so consecutivos em t+ . Estes so os nicos testes de interseo necessrios para manter o segundo invariante. Suponha que h dois segmentos na coleo que se intersectam. Por hiptese, sempre que dois segmentos se intersectam, isso ocorre em um nico ponto. Escolha dois segmentos s e r da coleo que se intersectam num ponto (x, y) com x o menor possvel. Observe que s e r so consecutivos em t+ para t = EX [j] onde j = max{q : EX [q]<x}. Ento, pelos invariantes, o algoritmo termina com p j, devolvendo verdadeiro. Consumo de tempo. O consumo da linha 1 (n lg n) e da linha 2 (1). O bloco de linhas 4-13 executado 2n vezes. Como T armazena no mximo n segmentos, cada execuo deste bloco consome tempo O(lg n). Logo, o consumo total deste bloco de linhas O(n lg n) e o consumo de tempo do Interseo-SH (n lg n).

Exerccios
1. Ajuste Interseo-SH para que aceite pontos extremos com mesma coordenada X. 2. Escreva uma verso de Interseo-SH que, dada uma coleo de segmentos, devolva todas as intersees entre os segmentos. Para simplicar, suponha que no existam pontos extremos e intersees com a mesma coordenada X e que intersees entre mais do que dois segmentos no ocorram.

35

3. Descreva os campos de um n da ABBB T que armazena a descrio combinatria da linha de varredura usada em Interseo-SH. Utilizando essa descrio do n, escreva o algoritmo Predecessor(T, x, y) usando o predicado Esquerda.

Diviso em polgonos montonos

O interesse aqui decompormos um certo domnio complexo em uma coleo de objetos simples. A regio mais simples na qual podemos decompor um objeto plano um tringulo. Dado um polgono, queremos adicionar diagonais que no se cruzem de modo a dividi-lo em tringulos. Esse processo chamado de triangulao do polgono. O algoritmo que veremos nesta seo utiliza o mtodo da linha de varredura para dividir um polgono dado em polgonos ditos montonos. Ele a primeira parte de um algoritmo que no aqui apresentado, que triangula um polgono de n vrtices em tempo (n lg n). Polgonos montonos podem ser triangulados em tempo linear.

5.1

Polgonos e polgonos montonos

Uma curva poligonal uma seqncia nita (v1 , a1 , v2 , . . . , an1 , vn ) onde v1 , . . . , vn so pontos no plano e ai um segmento com extremos vi e vi+1 para i = 1, . . . , n 1. Os pontos v1 , . . . , vn so chamados de vrtices e os segmentos a1 , . . . , an1 de arestas. Uma curva poligonal fechada se v1 = vn . Considere os ndices dos vrtices e arestas de um polgono ciclicamente, ou seja, vn+1 = v1 , v0 = vn , an = a1 e a0 = an1 . Uma curva poligonal fechada simples se sempre que dois segmentos ai e aj com i = j se intersectam, ento j = i 1 e a interseo exatamente o vrtice vi , ou j = i + 1 e a interseo exatamente o vrtice vi+1 .
v2 v5 v6 v7 v3 v8 v9 v4

curva poligonal

fechada no-simples

fechada simples

Um polgono a regio fechada do plano limitada por uma curva poligonal fechada simples. A sua descrio combinatria uma sequncia de seus vrtices listados na ordem em que aparecem ao percorrermos a fronteira do polgono no sentido anti-horrio, sem repeties. A descrio combinatria do polgono mostrado abaixo (v1 , . . . , v17 ). O fecho convexo de um conjunto de pontos nada mais do que um polgono. 36

v1 v2 v1 v14 v15 v3 v5 v13 v9 v4 v7 v10 v8 v11 v10 v12 v7 v8 v9 v13 v12 v11 v6 v17 v16 v2 v6 v3 v4 v5 v15 v16 v21 v20 v19

v18 v17 v14

Um polgono chamado de Y -montono se a interseo dele com toda reta horizontal um segmento de reta, um ponto ou vazia. O primeiro polgono acima no Y -montono, j o segundo . Para simplicar a exposio, vamos assumir que o polgono no possui dois vrtices com a mesma coordenada Y .

5.2

O problema

Sejam u e v dois vrtices de um polgono P . O segmento uv uma diagonal de P se ele est contido em P e intersecta a fronteira de P apenas em u e v. A adio de uma diagonal a um polgono P o divide naturalmente em dois polgonos.
u

Problema da diviso em polgonos montonos. Dado um polgono P , encontrar um conjunto de diagonais de P que o dividam em polgonos Y -montonos. O polgono abaixo dividido em cinco polgonos Y -montonos pela adio das quatro diagonais indicadas.

a c b

37

Uma ponta interior de um polgono um vrtice vi para o qual ambos vi1 e vi+1 esto acima ou ambos esto abaixo de vi e o ngulo interno determinado por vi1 , vi , vi+1 maior que . Se ambos esto acima, vi uma ponta para baixo, seno uma ponta para cima. Acima, a e d so as pontas interiores para cima, e b, c e e so as pontas interiores para baixo. Pontas interiores so fontes locais de no-monotonicidade: um polgono Y -montono se no possui pontas interiores. De fato, suponha que P no Y -montono. Temos que mostrar que P contm uma ponta interior. Como P no Y -montono, existe uma reta horizontal que intersecta P em mais de um componente conexo. Podemos escolher tal que o componente mais esquerda seja um segmento e no um simples ponto. Seja p o extremo esquerdo deste segmento e q o seu extremo direito. Se seguirmos a fronteira de P em sentido anti-horrio a partir de q, ela intersecta novamente em algum ponto r. Se r = p ento o vrtice mais alto que encontramos neste percurso necessariamente uma ponta interior para cima.
ponta interior

p=r

P
ponta interior

Se r = p e seguirmos a fronteira de P a partir de q no sentido horrio, ela intersecta num ponto r . Observe que r = p, j que a fronteira de P intersecta mais do que duas vezes. Assim, o vrtice mais baixo que encontramos no percurso de q at r necessariamente uma ponta interior para baixo. Um polgono ter sido dividido em polgonos Y -montonos assim que nos livramos das suas pontas interiores. Fazemos isto adicionando diagonais que vo para cima a partir de pontas interiores para cima e que vo para baixo a partir de pontas interiores para baixo. Vamos descrever um algoritmo que resolve o problema da diviso em polgonos montonos atravs dessa idia, usando a tcnica da linha de varredura [Lee and Preparata 1977]. Um polgono com n vrtices representado por vetores X[1 . . n] e Y [1 . . n], com os vrtices na ordem em que aparecem em sentido anti-horrio na fronteira do polgono.

5.3

Trapzios e pontas interiores

Um trapzio um quadriltero que possui duas arestas paralelas. Para cada vrtice v de um polgono P , trace um segmento horizontal maximal passando por v e contido em P . Esses segmentos dividem P naturalmente em trapzios cujas arestas paralelas so horizontais. 38

Observe que, como no h vrtices com a mesma coordenada Y , o vrtice v o nico vrtice no seu segmento maximal. Assim, todo trapzio dessa diviso tem exatamente um vrtice de P na sua aresta horizontal superior, chamado de vrtice de suporte superior, e outro na sua aresta horizontal inferior, chamado de vrtice de suporte inferior. Se um tal vrtice estiver no interior de uma aresta do trapzio, ele ser chamado de vrtice interior de suporte. Abaixo, esquerda, destacamos os trapzios que tm vrtices interiores de suporte. Todo vrtice interior de suporte uma ponta interior e vice-versa.
111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 111111111111111111111 000000000000000000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000
111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000 111111111111111 000000000000000

111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000 111111 000000

Se ligarmos cada vrtice interior de suporte ao outro vrtice de suporte do trapzio, estes segmentos sero diagonais que dividem P em polgonos Y montonos. De fato, cada ponta interior deixa de ser uma ponta interior pois passa a ter, nos dois subpolgonos gerados por esta diagonal, um vizinho acima e outro abaixo dela. Os algoritmos mostrados a seguir utilizam a rotina PontaParaBaixo, que recebe o ndice x de um vrtice de suporte superior de um trapzio do polgono, o vetor Y [1 . . n] com as coordenadas Y dos vrtices do polgono e devolve verdadeiro se o vrtice de ndice x uma ponta interior para baixo, e falso caso contrrio. A rotina PontaParaBaixo consome tempo (1).

39

PontaParaBaixo(x, Y, n) 1 x x 1 x+ x + 1 2 se x = 0 ento x n 3 se x+ = n + 1 ento x+ 1 4 5 6


x e x+ so o predecessor e o sucessor de x na fronteira do polgono se Y [x ] > Y [x] e Y [x+ ] > Y [x] x ponta interior para baixo?

ento devolva verdadeiro seno devolva falso

5.4

Algoritmo de Lee e Preparata

O algoritmo que descrevemos aqui uma implementao da idia sugerida na subseo anterior [Lee and Preparata 1977]. Ele utiliza a tcnica da linha de varredura. Abaixo descrevemos quais so os pontos eventos, o funcionamento da la de pontos eventos, da estrutura da linha de varredura e como cada tipo de ponto evento processado pelo algoritmo, que recebe X[1 . . n] e Y [1 . . n], representando um polgono. Pontos eventos Os pontos eventos so os vrtices do polgono. A la de pontos eventos determinada estaticamente e consiste em um vetor E[1 . . n] com uma permutao dos ndices de 1 a n dos vrtices do polgono tal que Y [E[1]] > Y [E[2]] > > Y [E[n]]. Linha de varredura ((i, j), x, (k, l)), onde Descrevemos um trapzio do polgono pela tripla

(i, j) o par de ndices dos vrtices da aresta do polgono que contm o lado esquerdo do trapzio, sendo que i est acima de j, x o vrtice de suporte superior do trapzio, e (k, l) o par de ndices dos vrtices da aresta do polgono que contm o lado direito do trapzio, sendo que k est acima de l.

i k x l j

40

Imaginamos a linha varrendo o polgono de cima para baixo. Dizemos que um trapzio ativo se ele intersecta a linha de varredura. A descrio combinatria da linha guarda os trapzios ativos na ordem em que so intersectados por ela, da esquerda para a direita. Assim, quando a linha de varredura a reta y = t, temos que ((i, j), x, (k, l)) t ((i , j ), x , (k , l )) se a interseo da linha com o trapzio ((i, j), x, (k, l)) est esquerda da interseo com o trapzio ((i , j ), x , (k , l )). Usamos novamente uma ABBB T para representar a descrio combinatria da linha. Mais precisamente, T representa a ordem t quando a linha de varredura for a reta y = t, ou seja, os trapzios armazenados em T so os ativos e eles esto armazenados de acordo com a ordem t . O algoritmo utiliza as seguintes rotinas para manipular T : Crie(T ): cria uma ABBB T vazia; Insira(T, i, j, v, k, l): insere o trapzio ((i, j), v, (k, l)) na ABBB T , usando t com t = Y [v]; Remova(T, v): devolve nil se no h trapzio em T que contenha o vrtice v, do contrrio remove de T um trapzio que contenha o vrtice v e devolve a sua descrio combinatria, usando t com t = Y [v]. O consumo de tempo de cada uma destas rotinas O(lg m), onde m o nmero de trapzios em T [Cormen et al. 2001]. Processamento dos pontos eventos A atualizao da descrio combinatria da linha de varredura depende do tipo do ponto evento. Seja v o ponto evento corrente, v o seu predecessor e v + o seu sucessor na fronteira do polgono. Dividimos o processo em trs casos. O primeiro caso ocorre quando um entre v e v + est acima de v e o outro est abaixo. O segundo caso ocorre quando os dois esto abaixo de v, e o terceiro caso, quando os dois esto acima de v.

Caso 1

Caso 2

Caso 3

No primeiro caso, temos que substituir em T o trapzio ativo que tem v como vrtice de suporte inferior pelo que tem v como vrtice de suporte superior. Alm disso, se o vrtice de suporte superior do trapzio removido for uma ponta para baixo, traamos uma diagonal de v at ele. A rotina TrataCaso1 implementa esse caso. Ela recebe a ABBB T com a descrio combinatria da linha de varredura imediatamente acima do vrtice v, 41

trs ndices u, v, e w de vrtices consecutivos na fronteira do polgono tais que um dentre u e w est abaixo de v e o outro acima, as coordenadas Y [1 . . n] dos vrtices do polgono, e um vetor D[1 . . t] com diagonais do polgono. Ela ajusta T de maneira a que passe a representar a linha de varredura imediatamente abaixo de v, e eventualmente acrescenta ao vetor D uma diagonal com uma das pontas em v, a m de eliminar uma ponta para baixo.
a13 a17 a16 a18 a14 a15

P
a7 a8 a6 a9 a10 a5 a11

r
a21 a20

v
a19

a12

w
a2 a1 a23 a3 a4

a22 a21

(a8 , s, a9 ) (a21 , r, a20 ) (a10 , s, a12 ) (a18 , x, a6 ) (a21 , r, a20 )

(a8 , s, a9 )

(a10 , s, a12 ) (a19 , v, a6 )

TrataCaso1(T, u, v, w, Y, n, D, t) 1 se Y [u] < Y [w] ento u w 2 ((i, j), x, (k, l)) Remova(T, v) 3 se v = j o trapzio est direita de v? 4 ento Insira(T, v, w, v, k, l) 5 seno Insira(T, i, j, v, v, w) 6 se PontaParaBaixo(x, Y, n) 7 ento t t + 1 D[t] (x, v) O segundo caso ocorre com os vrtices v e r na situao ilustrada frente. Estes so os dois casos possveis: num o ponto evento est em um trapzio ativo que deixar de ser ativo, e no outro ele no est em nenhum trapzio ativo. Se v est em um trapzio ativo, como na situao ilustrada, ento ele uma ponta interior para cima e ser processado da seguinte maneira. Removemos de T o trapzio que contm v e inserimos os dois trapzios que passam a ser ativo, tendo v como vrtice de suporte superior. Ademais, traamos uma diagonal de v at x, onde x o vrtice de suporte do trapzio que foi removido de T . Se v no est em um trapzio ativo, ento um nico trapzio passa a ser ativo, tendo as arestas incidentes a v como arestas laterias e v como vrtice de suporte superior. 42

A rotina TrataCaso2 implementa esse caso. Ela recebe a ABBB T com a descrio combinatria da linha de varredura imediatamente acima do vrtice v, trs ndices u, v, e w de vrtices consecutivos na fronteira do polgono tais que u e w esto abaixo de v, as coordenadas X dos vrtices do polgono, e um vetor D[1 . . t] com diagonais do polgono. Ela ajusta T de maneira a que passe a representar a linha de varredura imediatamente abaixo de v, e eventualmente acrescenta uma diagonal ao vetor D.
a13 a17 a16 a18 a20 a21 a22 a21 a1 a23 (a8 , s, a9 ) (a21 , r, a20 ) (a10 , s, a12 ) (a19 , x, a6 ) (a21 , r, a20(a4 , v, a6 ) ) (a19 , v, a3 ) (a10 , s, a12 ) a2 a14 a15

P
a7 a8

x
a19

s
a9 a10 a5

a12

v
a3 a4

a6

u w

a11

(a8 , s, a9 )

TrataCaso2(T, u, v, w, X, D, t) 1 se X[u] > X[w] ento u w 2 trap Remova(T, v) 3 se trap = nil 4 ento Insira(T, v, u, v, v, w) 5 seno ((i, j), x, (k, l)) trap 6 Insira(T, i, j, v, v, u) 7 Insira(T, v, w, v, k, l) 8 t t + 1 D[t] (x, v)

v ponta interior para cima

O terceiro caso ocorre com os vrtices v e z na situao ilustrada frente. Estes so os dois casos possveis: num o ponto evento est em um trapzio ativo que deixar de ser ativo, e no outro ele est em dois trapzios ativos que deixaro de ser ativos. Se v est em um trapzio ativo apenas, ento basta remover este trapzio de T e se o vrtice de suporte superior deste trapzio for ponta interior para baixo, traamos uma diagonal de v para este vrtice. Se v est em dois trapzios ativos, ento removemos estes dois trapzios, que tm como vrtices de suporte superiores, digamos, x e y, e caso x ou y sejam 43

pontas interiores para baixo, traamos diagonais de v para eles. A rotina TrataCaso3 implementa esse caso. Ela recebe a ABBB T com a descrio combinatria da linha de varredura imediatamente acima do vrtice v, trs ndices u, v, e w de vrtices consecutivos na fronteira do polgono tais que u e w esto acima de v, as coordenadas Y dos vrtices do polgono, e um vetor D[1 . . t] com diagonais do polgono. Ela ajusta T de maneira a que passe a representar a linha de varredura imediatamente abaixo de v, e eventualmente acrescenta uma ou duas diagonais ao vetor D.
a13 a17 a16 a18 a20 a21 a14 a15

P
a7

w
a19

s
a8 a9

a12

a6

v
a22 a21 a1 a23 (a8 , s, a9 ) (a19 , x, a3 ) (a10 , s, a12 ) (a21 , u, a20 ) 4 , x, a6 ) (a (a4 , x, a6 ) (a21 , v, a3 ) (a10 , s, a12 ) (a8 , s, a9 ) a2 a3 a4 a5 a10 a11

TrataCaso3(T, v, Y, n, D, t) 1 ((i, j), x, (k, l)) Remova(T, v) 2 se PontaParaBaixo(x, Y, n) 3 ento t t + 1 D[t] (x, v) 4 se j = v ou k = v h um outro trapzio em T ? 5 ento ((i , j ), y, (k , l )) Remova(T, v) 6 se PontaParaBaixo(y, Y, n) 7 ento t t + 1 D[t] (y, v) 8 se l = v 9 ento Insira(i, j, v, k , l ) 10 seno Insira(i , j , v, k, l) O consumo de tempo das rotinas TrataCaso1, TrataCaso2 e TrataCaso3 O(lg m), onde m o nmero de trapzios em T . Temos que m < n, assim esse consumo O(lg n).

44

Algoritmo Finalmente estamos prontos para apresentar o pseudocdigo do algoritmo de Lee e Preparata. As linhas 1-3 constroem a la E[1 . . n] de pontos eventos, formada pelos ndices de 1 a n de modo que Y [E[1]] > > Y [E[n]]. O bloco 6-14 de linhas trata cada ponto evento conforme discutimos. DivideEmMontono-LP(X, Y, n) 1 para k 1 at n faa 2 E[k] k 3 MergeSort(Y, X, 1, n, E) ordenao indireta decrescente de Y 4 Crie(T ) t 0 5 para k 1 at n faa 6 v E[k] 7 v v 1 v+ v + 1 8 se v = 0 ento v n 9 se v + = n + 1 ento v + 1 10 se Y [v ] < Y [v] < Y [v + ] ou Y [v + ] < Y [v] < Y [v ] 11 ento TrataCaso1(T, v , v, v + , Y, n, D, t) 12 seno se Y [v ] < Y [v] 13 ento TrataCaso2(T, v , v, v + , X, D, t) 14 seno TrataCaso3(T, v, Y, n, D, t) 15 devolva (D, t) O algoritmo est correto. Primeiramente, cada par de pontos (x, v) inserido no vetor D nas rotinas TrataCaso1, TrataCaso2 e TrataCaso3 uma diagonal do polgono. De fato, x e v so vrtices de suporte de um mesmo trapzio: aquele que deixou de ser ativo e foi removido de T imediatamente antes do par ser includo em D. Assim, o segmento com extremos x e v est contido no polgono. Ademais, como pelo menos um entre x e v ponta interior, e portanto vrtice de suporte interior deste trapzio, este segmento intersecta a fronteira do polgono apenas em seus extremos e logo uma diagonal. Cada trapzio do polgono estar ativo em alguma iterao. Como j observado, uma ponta interior vrtice de suporte de algum trapzio. Uma ponta interior para baixo eliminada na iterao em que deixou de ser ativo o trapzio do qual ela vrtice de suporte superior. Isso pode ocorrer no TrataCaso1 ou no TrataCaso3. Uma ponta interior para cima eliminada quando deixou de ser ativo o trapzio do qual ela vrtice de suporte inferior. Isso ocorre no TrataCaso2. Consumo de tempo. As linhas 1-2 consomem tempo (n) enquanto que a linha 3 consome tempo (n lg n). Em cada execuo do bloco de linhas 6-14, exatamente uma entre TrataCaso1, TrataCaso2 ou TrataCaso3 acionada. Uma execuo do bloco de linhas 6-9 consome tempo (1). Assim, o consumo total de tempo do bloco de linhas 6-14 O(n lg n), j que este bloco executado n vezes. Com isso, o algoritmo de Lee e Preparata consome tempo (n lg n).

45

Exerccios
1. Ajuste DivideEmMontono-LP para que aceite vrtices com mesma coordenada Y . 2. Prove que a soma do nmero de vrtices dos subpolgonos obtidos pela adio das diagonais encontradas pelo algoritmo DivideEmMontonoLP O(n), onde n o nmero de vrtices do polgono dado. 3. Descreva os campos de um n da ABBB T que armazena a descrio combinatria da linha de varredura usada em DivideEmMontonoLP. Utilizando essa descrio, escreva um algoritmo Busca(T, v), que recebe a rvore T e o ndice de um vrtice do polgono representado por X[1 . . n], Y [1 . . n] e devolve nil caso no haja um trapzio em T que contm v, e caso contrrio devolve um trapzio de T que contenha v. Seu algoritmo deve usar o predicado Esquerda.

Agradecimentos
Somos gratos ao Paulo Feolo (Departamento de Cincia da Computao do Instituto de Matemtica e Estatstica da USP), de quem copiamos o formato do texto e com quem trocamos vrias idias. Nosso trabalho foi simplicado pois pudemos nos apoiar em seu captulo de Anlise de Algoritmos.

Referncias bibliogrcas
[Bykat 1978] Bykat, A. (1978). Convex hull of a nite set of points in two dimensions. Information Processing Letters, 7:296298. [Chand and Kapur 1970] Chand, D. and Kapur, S. (1970). An algorithm for convex polytopes. JACM, 17(1):7886. [Cormen et al. 2001] Cormen, T. H., Leiserson, C. E., Rivest, R. L., and Stein, C. (2001). Introduction to Algorithms. MIT Press, 2. edition. [de Berg et al. 1997] de Berg, M., van Kreveld, M., Overmars, M., and Schwarzkopf, O. (1997). Computational Geometry: Algorithms and Applications. Springer. Second Edition, 2000. [de Resende and Stol 1994] de Resende, P. and Stol, J. (1994). Fundamentos de Geometria Computacional. IX Escola de Computao. [Eddy 1977] Eddy, W. (1977). A new convex hull algorithm for planar sets. ACM Trans. Math. Software, 3(4):398403. [Figueiredo and Carvalho 1991] Figueiredo, L. and Carvalho, P. (1991). Introduo Geometria Computacional. 18o Colquio Brasileiro de Matemtica. IMPA. QA758 F475i. 46

[Graham 1972] Graham, R. (1972). An ecient algorithm for determining the convex hull of a nite planar set. Information Processing Letters, 1:132133. [Green and Silverman 1979] Green, P. and Silverman, B. (1979). Constructing the convex hull of a set of points in the plane. Computer Journal, 22:262266. [Jarvis 1973] Jarvis, R. (1973). On the identication of the convex hull of a nite set in the plane. Information Processing Letters, 2:1821. [Kleinberg and Tardos 2006] Kleinberg, J. and Tardos, E. (2006). Algorithm Design. Addison-Wesley. [Laszlo 1996] Laszlo, M. (1996). Computational Geometry and Computer Graphics in C++. Prentice Hall, Upper Saddle River, NJ. [Lee and Preparata 1977] Lee, D. and Preparata, F. (1977). Location of a point in a planar subdivision and its applications. SIAM Journal on Computing, 6:594606. [Mulmuley 1994] Mulmuley, K. (1994). Computational Geometry: An Introduction Through Randomized Algorithms. Prentice Hall, Englewood Clis, NJ. [ORourke 1993] ORourke, J. (1993). Computational Geometry in C. Cambridge University Press, Cambridge. Second Edition, 1998. [Preparata and Shamos 1985] Preparata, F. and Shamos, M. (1985). Computational Geometry: An Introduction. Texts and Monographs in Computer Science. Springer-Verlag, New York. [Shamos and Hoey 1975] Shamos, M. and Hoey, D. (1975). Closest point problems. In Proc. 16th Annual IEEE Symposium in Foundations of Computer Science, pages 151162. [Shamos and Hoey 1976] Shamos, M. and Hoey, D. (1976). Geometric intersection problems. In Proceedings of the 17th Annual IEEE Symposium on Foundations of Computer Science, pages 208215.

47

Você também pode gostar