Sunteți pe pagina 1din 17

Linia de segment intersectie

Tematica: harta de acoperire

Cand vizitati o tara, hartile sunt o sursa nepretuita de informatii. Ele va arata unde sunt situate obiec
tele turistice,ele indica drumurile si liniile de cale ferata pentru a ajunge acolo, ele arata mici lacuri, si asa
mai departe. Din pacate, ele pot fi o sursa de frustrare, asa cum este adesea dificil de gasit informatii:
chiar si atunci cand stii pozitia aproximativa a unui oras mic, poate fi dificil de gasit pe harta.
Pentru a face harti mai usor de citit, sistemele de informatii geografice le-a impartit in mai multe straturi.
Fiecare strat este o harta tematica care stocheaza doar un singur fel de informatii. Astfel va exista un
starat de stocare al drumurilor, un strat de stocare al oraselor, un strat de stocare al raurilor, si asa mai
departe. Tema unui strat poate fi mai abstract . De exemplu, poate exista un strat de densitate al
populatiei, de precipitatii a mediului, habitat ursului grizzly sau pentru vegetatie. Informatiile de tipul
geometric pot fi stocate in straturi diferite: stratul pentru un parcurs ar putea stoca drumuri ca fiind
colectii de segmente de linie(sau curbe, probabil),stratul de orase ar putea contine puncte etichetate cu
numele de oras, iar stratul de vegetatie ar putea stoca o subdiviziue a hartii in regiunile etichetate cu tipul
de vegetatie.
Utilizatorii unui sistem de informatii geografice pot selecta una dintre tematicile afisate pentru harti.
Pentru a gasi un oras mic ar selecta stratul stocare orase, si nu ar fi distras de informatii, cum ar fi numele
raurilor si al lacurilor. Dupa ce s-a reperat orasul probabil doriti sa stiti cum sa ajungeti acolo. In acest
sens sistemele de informatii geografice permite utilizatorilor sa vizualizeze o suprapunere de mai multe
harti.
Folosind o suprapunere de parcurs si harta de stocare a oraselor, acum va puteti da seama cum obtineti un
oras. Atunci cand doua sau mai multe straturi tematice ale harti sunt reprezentate impreuna, intersectiile
din suprapunere sunt pozitii de interes deosebit. De exemplu, atunci cand vizualizati suprapunerea a
stratului pentru drumuri si a stratului pentru rauri, ar fi util ca intersectiile sa fie in mod clar marcate.
In acest exemplu doua harti sunt practice retele si intersectiile sunt puncte. In alte cazuri, unul este
interest de intersectia regiunilor complete. De exemplu, geografii studiaza climatice ce ar putea fi
interesante in gasirea de regiuni in care exista o padure de pini si precipitatii anuale intre 1000mm si 1500
mm. Aceste regiuni sunt intersectiile regiunilor etichetate caPadurea de piniin harta vegetatiei si
regiunile cu eticheta 1000-1500 in Harta precipitatiilor.
Intersectia de segment linie 2.1
Vom studia in primul rand cea mai simpla forma de acoperire harta problema, in cazul in care cele doua
straturi ale harti sunt retelele reprezentate ca fiind colectii de segmente de linie. De expemlu, o harta cu
un strat de stocare al drumurilor, a cailor ferate sau a raurilor, la o scara mica. Retineti ca puteti asa puteti
sa puneti curbe apropiate de un numar mic de segmente. La inceput nu vom fi intersesati in regiunile
induse de aceste segmente de linie. Mai tarziu vom vedea mai multe situatii mult mai complexe unde
hartile nu sunt doar retele. Pentru a rezolva in reteaua suprapunere ,in primul rand problema trebuie sa se
afirme ca intr-un dcor geometric. Pentru acoperirea a doua retele geometrice avem urmatoarea situatie:
se dau doua seturi de segmente de linie, calculeaza toate intersectiile dintre un segment dintr-un set si un
segment din alt set. Cu aceasta specificatie problema nu este destul de precisa cu toate acestea, nu putem
defini cum doua segmente se intersecteaza. In special, doua segmente se intersecteaza atunci cand un
punct se afla sau nu pe celalalt? In alte cuvinte, trebuie sa specificati daca segmentele de intrare sunt

deschise sau inchise. Pentru a face aceasta decizie ar trebui sa mergem inapoi la cerere, acoperire retea
problema. Drumurile intr-o harta rutiera si raurile intr-o harta de rauri sunt reprezentate de lanturi d
segmente, astfel incat o trecere a unui drum si a unui rau corespunde la interior de un lant si se
intersecteaza in interior cu un alt lant. Acest lucru nu inseamna ca nu exista o intersectie intre interiorul a
doua segmente: intersectia unui punct s-ar putea intampla pentru a coincide cu punctual unui segment
dintr-un lant. In fapt, aceasta situatie nu este neobijnuta pentru ca vanturile si raurile sunt reprezentate de
mai multe segmente mici si coordinate de obiective ce pot fi rotunjite cand hartile sunt digitalizate. Putem
concluziona ca ar trebui sa definim segmentele pentru a fi inchise, astfel incat un punct al unui segment
calculat pe alt segment calculat se considera o intersectie.
Pentru a simplifica descrierea oarecum ne punem segmente din ambele seturi intr-un singur set, si
calculam toate intersectiile dintre segmente in acest set.
In acest fel vom gasi cu siguranta toate intersectiile pe care le vrem. Am gsit, de asemene a intersectiile
dintre segmentele din acelasi set. Alte intersectii pot fi filtrate dupa aceea verificand pur si simplu
verificand fiecare intersectie raportata. Daca cele doua segmente implicate fac parte din acelasi set. Deci
problema noastra, caietul de sarcini este dupa cum urmeaza: avand in vedere un set Sn segmente inchise
in plan, raporteaza toate punctele de intersectie dintre segmentele S.
Aceasta nu pare a fi o problema provocatoare: pur si simplu ne putem lua fiecare perechea de segmente,
calcula daca acestea se intersecteaza si daca este asam aprorteaza intersectia punctelor lor. Acest alogorit
necesita timp in mod special O(n2). Intr-un sens acesta este optim: cand fiecare pereche de segmente
intersecteaza orice algoritm trebuie sa iasa (n2) timp, pentru ca are de raportat toate intersectiile .Poate
fi dat un exemplu similar cand este considerata suprapunerea a doua retele. In situatiile practice, cu toate
acestea, cele mai multe segmente s eintersecteaza numarul sau doar alte cateva segmente,astfel incat
numarul total de puncte de intersectie sa fie mai mic decat patratica. Ar fi frumos sa aiba un algoritm care
este mai rapid in astfel de situatii. Cu alte cuvinte, ne dorim un algoritm al carui timp de rurale depinde nu
numai de numarul de segmente in introducere, ci si de numarul de puncte din intersectie . Un astfel de
algoritm este numit un algoritm sensibil la iesire: timpul de executie al algoritmului este sensibil la
marimea de iesire. Am putea apela, de asemenea, un astfel de algoritm sensibil la inersectie, deoarece
numarul de intersectii este ceea ce determina marimea de iesire.
Cum putem evita toate perechiile de segmente pentru intersectia de testare? Aici ne trebuie sa facem uz de
geometrie a situatiei: segmentele care sunt apropiate sunt candidate pentru intersectie, spre doasebire de
segmentele care sunt departe una de cealalta. Mai jos vom vedea cum putem folosi acesta observatie
pentru a obtine un algortim de iesire- sensibil pentru lina de segment intersectie.

Fie S:={

s 1 , s 2 ,..., s n } multimea de segmente pentru care noi ne dorim sa calculam toate

intersectiile. Dorim sa evitam perechile de segmente de testare, care sunt departe unele de altele. Dar cum
putem face acest lucru? Hai sa incercam mai intai intr-un caz simplu. Definim y- un interval de segment
care sa fie proiectie ortogonala pe axa y. Cand intervalul y are o pereche de segmente care nu se suprapun,
am putea spune ca aceasea sunt departe in afara, segmentele y nu se pot intersecta. Prin urmare, avem
nevoie doar pentru a testa perechi de segmente ale caror interval y sa se suprapuna, adica perechi care au
o linie orizontala care se suprapune cu ambele segmente. Pentru a gasi aceste perechi ne imaginam o linie
de maturat strada L in sos, deaspura planului, pornind de la o pozitie mai presus de toate segmentele. In
timp ce noi maturam linia imaginara, vom tine evident tuturor segmentelor intersectand detalii cu privire
la acest lucru ce va fi explicat mai tarziu, astfel incat sa putem gasi perechile de care avem nevoie.
Acest tip de algoritm este numit un algoritm ce matura avinul si linia L se numeste linia de rotire. Linia
de rotire este setul de segmente ce se intersecteaza. Modifica statutul in timp ce matura linie se muta in
jos, dar nu continuu. Numai punctele speciale sunt o actualizare a statutului necesara. Noi numim acesre
puncte, puncte eveniment de avion matura algoritm. In acest algoritm punctele de exeniment sunt capetele
segmentelor.

Momentele in care linia de rotire ajunge la un punct de eveniment sunt numai moment cand
algoritmul de fapt face ceva: actualizeaza statutului liniei de rotire si efectueaza unele teste ale
intersectiei. In special, daca evenimentul punctului este punctul final superior al unui segment,atunci noul
segment incepe intersectarea liniei matura si adauga starea. Acest segment este testat impotriva liniilor de
rotire deja intersectate. Daca la final un punct este mai mic,segmental se opreste din intersectia liniilor de
rotire si il elimina din statut. In acest fel am testat numai perechi de segmente pentru care exista o linie
orizonatala care intersecteaza ambele segmente. Din pacate, acesta nu este suficient: inca mai exista
situati in care am testat un numar patratic de perechi, intrucat exista doar un numar mic de puncte d
eintersectie. Un exemplu simplu este un set de segmente vertical care se intersecteaza de axa X. Deci,
algoritmul este sensibil la iesire. Problema este ca doua segmente care se intersecteaza linia de rotire
poate fi departe unul de celalalt in directia gresita.
Hai sa comandati segmentele de la stanga la dreapta ca sa intersecteze linai de rotire ,sa include idea
de a fi aproape in directia orizontala. Ne trebuie doar sa testeam segmentele atunci cand acestea sunt
adiacente in ordonarea orizontala. Acest lucru inseamna ca am testat orice segment nou impotriva celor
doua segmente. Mai tarziu,cand linia de rotire s-a mutat in jos intr-o alta pozitie, un segment poate devein
adiacent la alte segmente care vor fi testate. Strategia noastra ar trebui sa se reflecte in statutul
algoritmului nostru: starea acum corespunde sirului ordonat de segmente ce intersecteaza linia de rotire.
Noul statut nu se schimba numai la punctele de sfarsit de segmente; sunt de asemenea modificari la
punctele de intersectie, in cazul in care ordinea modificarilor interseteaza segmentele. Atunci cand se
intampla acest lucru trebuie sa testam cele doua segmente care isi schimba pozitia impotriva noilor
vechini. Acesta este un nou tip de ounct eveniment.
Inainte de a incerca sa transformam aceste idei int-un algoritm eficient, ar trebui sa ne convingem ca
abordarea este corecta. Am redus numarul dde perechi care urmeaza sa fie testat, dar nu vom gasi in
continuare toate intersectiile? Cu alte cuvinte, daca doua segmente
intotdeauna o pozitie a liniei de baleiere L in cazul in care

s i si s j se interesecteaza, exista

s i si s j

sunt adiacente de-a lungul lui

L? Hai sa ignoram mai intai unele cazuri: presupunem ca nici un segment nu este orizontal, ca oricare
doua segmente se intersecteaza in cel mult un punct, punctele nu se suprapun, si nici trei segmente nu se
intalnesc intr-un punct comun. Mai tarziu vom vedea ca aceste cazuri sunt usor de manevrat, dar cum este
convenabil sa se uite de ele. In cazul in care un punct final al unui segment se afla pe un alt segment poate
fi detectata cu usurinta atunci cand linia matura ajunge la punctul final. Asa ca singura intrebare este daca
intersectiile segmentelor interioare sunt detectate.

Lema 2.1: Fie

s i si s j doua segmente de baza non-orizontale ale caror interioare se

intersecteaza intr-un singur punct p, si sa isi asume ca nu exista un al treilea segment de trecere prin p.
Apoi, exista un punct de eveniment de mai sus, unde p,

s i si s j devin adiacente si sunt testate

pentru intersectie.
Demonstratie: Fie L o linie orizontala usor deasupra lui p. In cazul in care L este destul de aproape de p
atunci

s i si s j trebuie sa fie adiacente de-a lungul lui L. (Pentru a fi prcis trebuie sa luam un L

astfel incat sa nu existe nici un punct de eveniment L intre ele si linia orizontala p ). Cu alte cuvinte, este
o pozitie a liniei de rotire unde

s i si s j sunt adiacente. Pe de alta parte s i si s j nu sunt inca

adiacente cand incepe algoritmul,deoarece linia de rotire incepe mai presus de toate segmentele de linie.

Prin urmare, trebuie sa existe un eveniment unde punctual q,

s i si s j devin adiacente si sunt testate

pentru intersectie.
Deci, abordarea noastra este corecta, cel putun cand uitam despre cazurile urate pe care le-am
mentionat mai devreme. Acum putem contiuna cu dezvoltarea algoritmului avion-matura. Sa recapitulam
pe scurt abordarile gloabale. Ne imaginam ca se deplaseaza in jos o linie orizontala matura L peste plan.
Linia de rotiri opriri la anumite puncte de eveniment; in cazul nostrum,acestea sunt caracteristicile de
segment, care se stiu in preabalil, si punctele de intersectie,care sunt calculate din zbor. In timp ce linia de
rotire pastreaza secvente comandate de segmente intersectate de acesta. Cand linia de rotire se opreste la
un punct eveniment, secventa segmentelor se modifica si in functie de tipul de punct eveniment, trebuie
sa luam mai multe decizi pentru a actualize starea si a detecta intersectiile.
Atunci cand punctul de eveniment este punctul final superior al unui segment, exista un nou segment
care intersecteaza linia de rotire. Acest segment trebuie sa fie testat impotriva intersectiei celor doi vecini
ai sai de-a lungul liniei de rotire. Doar punctele de intersectie de sub linia de rotire sunt importante; cele
de mai sus de linia de rotire au fost deja detectate. De exemplu, in cazul in care segmentele
sunt adiacente pe linia de rotire, atunci trebuie sa testati

s i si s k

s j pentru intersectia cu s i si s k . Daca

vom gasi o intersectie sub linia de rotire, am gasit un nou punct de eveniment. Dupa ce punctul final
superior este atins vom continua cu urmatorul punct de eveniment.
Atunci cand punctul de eveniment este o intersectie, cele doua segmente care se intersecteaza isi vor
schimba ordinea. Ficare dintre ei devine (cel mult) un nou vecin impotriva caruia este testata o noua
intersectie. Din nou, numai intersectiile de sub linia de rotire sunt inca interesante. Sa presupunem ca
patru segmente

s j , s k , s l si s m apar in aceasta ordine pe linia de rotire atunci cand se ajunge

la punctual de intersectie al segmentelor


trebuie sa testam

s k si s l . Apoi

s k si s l isi comuta pozitiile si

s k si s l sub linia de rotire, si deasemenea, si

s l si s m . Intersectiile noi

pe care le gasim sunt, de sigur, asemenea puncte de eveniment ale algoritmului. Retineti, totusi, ca este
posibil ca aceste evenimente sa fi fost deja detectate, si anume in cazul in care o pereche a devenit
adiacenta, aceasta sa fi fost si inainte adiacenta.
Atunci cand punctul de eveniment este punctul final mai mic al unui segment, cei doi vecini ai sai
devin adiacenti si trebuie sa fie testati pentru intersectie. In cazul in care se intersecteaza sub linia de
rotire, punctual sau de intersectie este un punct de eveniment. ( Din nou, aceste eveniment ar putea sa fie
deja detectat). Presupunem trei segmente

s k , s l si s m care apar in aceasta ordine pe linia de

rotire ,atunci se intalneste obiectivul final inferior

s l . Atunci s k

si

s m vor devein adiacente

cand a fost testate intersectia.


Dup ace ne-am cuprins intregul plan mai exact, dupa cce vom testat si ultimul punct eveniment- am
calculate toate punctele de intersectie. Aceste lucruri sunt garantat invariante, ce detine in acest moment
timpul de rotire : toate punctele de intersectie deasupra liniei de rotire au fost calculate corect.
Dupa aceasta schita a algoritmului, este timpul pentru a merge in detaliu. Este timpul sa se uite la
cazurile degenerate care pot aparea, cum ar fi trei sau mai multe segmente intalnite intr-un punct. Noi
trebuie sa specificam in primul rand ceea ce asteptam de la algoritm in aceste cazuri. Am putea cere ca
algoritmul sa raporteze pur si simplu fiecare punct de intersectie o singura data, dar se pare ca este mai

util daca raporteaza pentru fiecare punct cate o lista de segmente care trec prin ea, sau sa-l afiseze un
punct final. Exista un alt caz special pentru care noi ar trebui sa definim iesirea necesara mai cu atentie, si
anume doua segmente partial suprapuse, dar pentru simplitate trebuie sa ignoram acest caz din aceasta
sectiune.
Incepem prin a descrie structurile de date ale algoritmului.
In primul rand avem nevoie de o structura de date- numita coada eveniment- care sticheaza
evenimentele. Vom desemna coada eveniment Q. Avem nevoie de o operatie care elimina uramtorul
eveniment care va avea loc in Q, si sa facem in asa fel incat sa fie tratata. Acest eveniment este cel mai
mare eveniment de sub linia de rotire. In cazul in care doua puncte de eveniment cu coordonatele y si x su
coordinate mai mici acestea vor fi returnate. Cu alte cuvinte, punctele de eveniment de pe linia orizontala
sunt tratate de la stanga la dreapta. Acest lucru implica faptul ca ar trebui sa consideram punct final stang
un segment orizontal care ar fi punct final superior,si punctual sau final drept sa fie mai mic. Va puteti
gandi, de asemenea, la conventia noastra dupa cum urmeaza: in loc de un eveniment orizontal linie,
imaginati-va ca este inclinat doar un pic in sus.Rezultatul liniei de rotire ajunge la punctul final stang al
unui segment orizontal chiar inainte de a ajunge la punctual final din dreapta. Coada de evenimente
trebuie s permit inserri, deoarece noi evenimente vor fi calculate pe zbor. Observati ca doua puncte de
eveniment pot coincide. De exemplu, pot coincide capetele superioare a doua segmente distinct. Este
convenabil de a trata acest lucru ca un punct eveniment. Prin urmare, o inseratie trebuie sa fie capabila sa
verifice daca un eveniment este eja present in Q.
Vom implementa coada de eveniment dupa cum urmeaza. Definiti un ordin eveniment care
reprezinta ordinea in care vor fi tratate. Prin urmare, daca p si q sunt doua puncte de eveniment atunci
avem p q daca si numai daca

p y >q y sau

p y =

q y si

px <q x . Depozitam punctele de

evenimente ntr-un arbore echilibrat binar de cutare, ordonate n func ie de . Cu fiecare punct de
eveniment p n Q vom stoca segmentele ncepnd de la p, adic, segmentele al cror punct final superior
este p. aceasta informatie se va ocupa de fiecare eveniment. Ambele operatiuni- preluarea unui eveniment,
introducand un eveniment de durata O( log m ), unde m este numarul de evenimente din Q. ( nu

folosim o gramada pentru a pune in aplicare coada eveniment, deoarece trebuie sa fie capabil sa testeze
daca un eveniment este deja existent in Q).
In al doile rand, avem nevoie sa mentinem statutul de algoritm. Pentru acest lucru este de comandat
secventa de segmente ce intersecteaza linia de rotire. Structura de stare, notate cu T, este folosita pentru a
accesa vecinii unui anumit segment s, astfel incat ele sa poata fi testate pentru intersectia cu s. Structura
de stare trebuie sa fie dinamnica: ca segment pornit sau oprit pentru a intersecta linia de rotire, acesta
trebuie sa fie inserate sau sterse din structura. Deoarece nu exista o ordine bine definite pe segmentele din
structura statutul poate folosi un arbore echilibrat de cautare binara ca structura de stare. Atunci cand sunt
utilizate numai pentru cautare binara arborii stocheaza numele, acest lucru ar putea fi surprinzator. Dar
arborii de cautare binara pot stoca orice set de elemente, atat timp cat exista o ordine a elementelor.
Mai detaliat, stocam segmentele ce intersecteaza linia de rotire ordonat in frunzele unui arbore
echilibrat de cautare binara T. Ordinea de la stanga la dreapta a segmentului de-a lungul liniei de rotire
corespunde cu ordinea de la stanga la dreapta pentru frunzele in T. Noi trebuie, de asemenea, sa stocam
informatiile in nodurile interne pentru a ghida cautarea arborelui la frunze. La fiecare nod intern, stocam
segmentul din frunze din dreapta in subarborele stang. (Alternativ, am putea stoca segmente doar din
nodurile interne. Acesta va salva unele date de stocare. Cu toate acestea, este conceptual mai simplu sa se
gaseasca la segmentele din nodurile interne valori pentru a ghida cautarea, nu ca elemente de date.) Sa
presupunem ca am cautat in T pentru segmentul imediat la stanga de punctul p, care se afla pe linia de
rotire. La fiecare nod intern v putem testa daca p se afla la stanga sau la dreapta a segmentului de stocare
v. In functie de rezultat coboram la stanga sau la dreapta subarborele de v, terminand in cele din urma la o
frunza. In mod similar,putem gasi segmentul imediat in partea dreapta a lui p sau segmentele care contin

p. Rezulta ca fiecare operatiune de cautare si actualizare a vecinilor ia O( log n ) timp. Coada de


eveniment Q si structura de stare T sunt structure de date doar daca avem nevoie. Algoritmul global poate
fi descris dupa cum urmeaza.
Algoritmul CautaIntersectii (S)
Intrare. Setul S de segmente de linie din avion.
Iesire. Setul de intersectie intre punctele segmentelor din S, cu fiecare punct care contine intersectia
segmentelor.
1. Initializeaza un gol eveniment coada Q. Apoi, intersectati capetele segmentului in Q; atunci cand
se intersecteaza un punct sfarsit superior, segmentul corespondent ar trebui sa fie depozitat cu
acesta.
2. Initializeaza un gol structura de stare T.
3. while Q nu este gol.
4. do determina urmatorul punct eveniment p in Q si il sterge
5. punctul coada eveniment (p)
Am vazut deja modul in care evenimentele sunt manipulate: la capetele de segmente noi trebuie sa
inserati sau sa stergeti segmentele din structura de stare T, si la punctele de intersectie putem schimba
ordinea celor doua segmente. In ambele cazuri, de asemenea- in cazul in care mai multe segmente sunt
implicate intr-un singur punct de eveniment-detaliile sunt un pic mai complicate. Urmatoarea procedura
descrie modul in care sa se punctele de eveniment corect.

Punct de coada eveniment (p)


1. Fie U(p) sa fie setul de segmente al caror punct superior este p; aceste segmente sunt stocate cu
punctul de eveniment p. (Pentru segmentele orizontale, obiectivul final superior este prin defini ie
final la stnga.)
2. Gasiti toate segmentele stocate in T care contin p; ele sunt adiacente in T. Fie L(p) ce denota un
subset de segmente constatate al carui obiectiv final inferior este p, si fie C(p) ce denota un subset
de segmente gasite care contin p in interiorul lor.
3. If L(p) U (p) C (p) contine mai mult de un segment.
4. Then Raporteaz p ca o intersectie, mpreun cu L (p), U (p) si C (p).
5. Stergeti segmentele din L (p) C (p) de la T.

6. Introducei segmentele din U (p) C (p) n T. Ordinea segmentelor din T ar trebui s

corespund cu ordinea n care acestea sunt intersectate de o matura line chiar mai jos p.
n cazul n care exist un segment orizontal,ultimul segment il contine pe p.
7. (* tergerea i re-introducerea segmentelor de C (p) inverseaz ordinea lor. *)
8. If U (p) C (p) =
s
s
9. Then lasa l si r la stanga si la dreapta vecinilor lui p in T.
10. GASITI UN PROIECT NOU(

sl

sr

,p)

11. Else s s fie segmentul U din stnga (p) C (p) n T.


sl
12. Fie
vecinul din stnga al lui s n T.
13. GASITI UN PROIECT NOU (

sl

, s,p)

14. Fie s segmentul U din stnga (p) C (p) n T.


sr
15. Fie
vecinul din dreapta al lui s n T.
16. GASITI NOI EVENIMENTE (s,

sl

, p)

Retineti ca in liniile 8-16 putem presupune ca

sl

si

sr

exista in realitate. In cazul in

care nu exista masutile corespunzatoare, acesta nu ar trebui , evident ,sa fie efectuat.
Procedurile pentru gasirea unor noi intersectii sunt usoare: testeaza pur si simplu doua segmente de
intersectie. Singurul lucru la care trebuie sa fim atenti este, atunci cand vom gasi o intersectie, daca
aceasta intersectie a fost deja verificata sau nu. Atunci cand nu exista segmente orizontale, intersectia
inca nu a fost verificata , atunci cand intersectia nu se afla sub linia de rotire.
Dar, cum ar trebui sa se ocupe segmentele orizontale?sa ne amintim ca in convenctia noastra
evenimentele de coordinate y sunt tratate de la stanga la dreapta. Asta implica ca suntem inca interesati de
punctele de intersectie situate la dreapta punctului eveniment. Prin urmaare, procedura GASESTE NOI
EVENIMENTE este definite dupa cum urmeaza.
GASITI UN PROIECT NOU(

1. if

sl

si

sr

s l , s r ,p)

se intersecteaza sub linia de rotire, sau pe ea si la dreapta actualul punct de

eveniment p, intersectia nu este inca prezenta ca eveniment in Q.

2. then introduce punctul de intersectie ca un eveniment in Q.


Cum ramane cu corectitudinea algoritmului nostrum? Este clar ca trebuie sa gasim intersectiile care
raporteaza doar punctele adevarate de intersectii, doar cum gasim toate acestea? Lema urmatoare afirma
cand este intradevar cazul.
Demonstratie: Sa ne amintim ca prioritatea unu eveniment este data de coordonatele y, si ca atunci cand
cele doua evenimente au aceleasi coordinate y, mai mici decat coordonata x, se acorda proritatea mai
mare. Vom dovedi lema prin inductia prioritatii punctelor de eveniment.
Fie p un punct de intersectie si sa presupunem ca toate punctele de intersectie q cu o prioritate mai mare
au fost calculate correct. Vom dovedi ca p si segmentele care il contin pe p sunt calculate corect.

Fie U(p) multimea segmentelor care au ca obiectiv punctul p superior(sau, pentru segmentele
orizontale ale acestora, la punct final la stanga), lasati L(p) sa fie setul de segmente avand p ca

punct final inferior(sau, pentru segmentele orizontale, obiectivul lor final fiind dreapta), si lasati
C(p) multimea segementelor avand p in interiorul lor.
In primul rand, sa presupunem ca p este un punct final al unuia sau mai multor segmente. In
acest caz p este stocat in coada de eveniment Q la inceputul algoritmului. Segmentele de la L(p)
de la U(p) sunt stocate cu p, astfel incat acestea vor fi gasite. Segmentele de la L(p) si C(p) sunt
stocate in T cand p este manipulate, astfel incat acestea vor fi gasite in lina 2 si C(p) sunt stocate
in T cand p este manipulate, astfel incat acestea vor fi gasite in linia 2 PUNCTUL DE
EVENIMENTE COADA. Astfel, p si toate segmentele implicate sunt determinate corect cand p
este un punct final al unuia sau mai multor segmente.
Acum, presupunem ca p nu este un punct final al unui segment. Tot ceea ce trebuie sa aratam
este ca p va fi inserat in Q la un moment dat. Retineti ca toate segmentele care sunt implicate au
si
sj
p in interiorul lor. Comandati aceste segmente de unghi in jurul valorii p, si lasati
si
sa fie doua segmente invecinate. Ca urmare in lema precedent vedem ca exista un punct de eveniment cu
o prioritate mai mare decat p astfel incat

s i si

ne-am asumat pentru simplitate pentru care

s i si

s j devin adiacente cand q este trecut. In lema 2.1


s j sunt non-orizontale, dar este simplu sa se

adapteze dovada pentru segmentele orizontale. Prin inductie, punctul de eveniment q a fost executat in
mod corect, ceea ce inseamna ca p este detectat si stocat in Q

Asa ca avem un algoritm corect. Dar, am reusit in dezvoltarea unei representative a


algoritmului? Raspunsul este da: timpul de rulare al algoritmului este O((n+k) log n )), unde k
este marimea de iesire. Urmatoare lema este un rezultat chiar mai puternic: timpul de rulare este O((n+I)

log n ), unde I este numarul de intersectii. Acest lucru este mai puternic, deoarece pentru o intersectie

iesirea poate consta intr-un numar mare de segmente, si anume in cazul in care mai multe segmente se
intersecteaza intr-un punct comun.
Lema 2.3 Perioada de functionare a algoritmului de gasire a intersectiilor pentru un set S de segmente n in
plan este O(n log n +I log n )), unde I este numarul de puncte de intersectie ale segmentelor din S.

Demonstratie: Algoritmul incepe prin construirea cozi de eveniment pe segmentul obiectiv. Pentru ca am

implementat coada de eveniment ca un arbore binar echilibrat, acesta ia O(n log n ) timp. Initializeaza
structura de stare in constanta de timp. Apoi coada avionului incepe si toate evenimentele sunt
manipulate. La maner un eveniment poate efectua trei operatii pe coada de eveniment Q: evenimentul in
sine se elimina de la Q in linia 4 de INTERSECTII GASITE, si nu poate fi una sau doua apeluri la
GASITI EVENIMENT NOU, ceea ce poate provoca cel mult doua noi evenimente in Q. Stergetii si
inserati de la Q in O( log n ) timp pentru fiecare. Noi de asemenea, efectuam operatiuni de inserare,
stergere si de gasirea unui vecin din structura T, care ia O( log n ) timp pentru fiecare. Numarul de
operatii este liniar in numarul m(p):= cartela( L (p) U (p) C (p)) din segmentele care sunt implicate in
eveniment. Daca notam suma tuturor m(p), in toate punctele de eveniment p, prin m, timpul de rulare al
algoritmului este O(m log n ).

Este clar ca m=O(n+k), unde k este marimea de iesire; dupa toate acestea, ori de cate ori m(p)>1
raportam toate segmentele implicate in eveniment, iar singurul eveniment care implica un segment sunt

punctele finale ale segmentelor. Dar vrem sa dovedim ca m=O(n+I), unde I este numarul de puncte de
intersectie. La acest lucru, vom interpreta un set de segmente ca un graf planar incorporate in avion. (daca
nu sunteti familiarizati cu tehnologia grafica in plan, trebuie sa cititi primele paragrafe din dectiunea 2.2
mai inati). Nodurile sale sunt capetele segmentelor si punctele de intersectie ale segmentelor, iar muchiile
sale sunt piesele de segmente la care se conecteaza nodurile. Sa consideram un punct de eveniment p. este
un varf de pe grafis si m(p) este delimitat de gaful nodului. Prin urmare, m este delimitat de suma
gradelor tuturor nodurilor din graficul nostru. Fiecare margine a grafului contribuie la gradul de exact
doua noduri (punctele finale ale acestuia), asa ca m este marginita de 2
muchii ale grafului. Hai sa ne legam de termeni n si I. Prin definitie,
cele mai multe ori 2n+I. Este bine cunoscut faptul ca in graficele plane

ne , unde ne este numarul de

n v , numarul de noduri, este de


ne =O( n v ), ceea ce

demonstreaza cererea noastra. Dar, pentru completare, sa ne dea argumentul aici. Fiecare fata a graficului
este delimitate de ce putn trei mucii, cu conditia sa existe cel putin trei segmente si o margine poate legata
de cel mult doua fete diferite. Prin urmare

n f , numarul de fete ,este 2 ne /3. Noi folosim acum

formula lui Euler, care prevede ca pentru orice graphic planar cu


confrunta , in

nf

urmatoarea relatie detine :

n v - ne +

n v noduri, muchiile
nf

2.

Are loc egalitatea daca si numai daca graficul este conectat. Astuparea limitelor privind

nf
Deci

in aceasta formula, obtinem : 2

(2n+I)-

ne se

nc si

ne +2 ne /3=(2n+I)- ne /3.

ne 6n+3I-6, si m 12n+6I-12, si leaga timpul de executare urmator.

Noi inca mai trebuie sa analizam celalalt aspect de complexitate, cantitatea de stocare utilizata de
algoritm. Marginile arborelui T este un segment de cel mult o data, asa ca foloseste O(n) de depozitare.
Marimea Q poate fi mai mare, cu toate acestea. Insertiile algoritmului intersectie sunt subliniate in Q
atunci cand sunt detectate si eliminate atunci cand acestea sunt manipulate. Atunci cand este nevoie de o
lunga perioada de timp intersectiile sunt tratate inainte, s-ar putea intampla ca Q sa devina foarte mare.
Bineinteles ca dimensiunea sa este intotdeauna delimitate de O(n+I), dar ar fi mai bine daca datele de
lucru sunt intotdeauna liniare.
Exista o modalitate relative simpla de a realize acest lucru: doar punctele magazin de intersec ie ale
perechilor de segment sunt n prezent adiacente pe linia de rotire . Algoritmul dat mai sus, de asemenea,
stocheaza punctele de intersectie ale segmentelor care au fost orizontal adiacente, dar nu mai sunt.
Numai in stocarea de intersectii intre segmentea adiacente, numarul de puncte de eveniment in Q este mai
mult liniar. Modificarea necesara in algoritm este ca puctul de intersectie dintre doua segmente trebuie sa
fie sters atunci cand nu mai sunt adiacente. Aceste segmente trebuie sa devina adiacente din nou, inainte
de a se ajunge la punctul de intersectie, astfel incat punctul de intersectie va fi in continuare raportat
corect. Timpul total luat de algoritm ramane O(n log n+ I log n ). Obtinem urmatoarea teorema:
Teorema 2.4. Fie S un set de segmente n linie in plan. Toate punctele de intersectie din S, cu fiecare

intersectie a segmentelor punct intersectie in aceasta, pot fi raportate in O (n log n+ I log n ) timp
si O(n) spatiu, unde este numarul de puncte de intersectie.

2.2 Lista de doua puncte dublu conectate pe muchie


Am rezolvat cel mai simplu caz al hartei de suprapunere, in cazul in care cele doua harti sunt retele
reprezentate ca colectii de segmente. In generat, hartile au o structura mai complicate: ele sunt
suubdiviziuni ale planului in regiuni etichetate. O harta tematica a padurilor din Canada, de exemplu, ar fi
o subdiviziune a Canadei in regiunile cu etichete, cum ar fi pin, foioase, mesteacan si mixt.
Inainte de a putea da un algoritm de calcul prin suprapunerea a doua subdiviziuni, trebuie sa dez voltam o
reprezentare adecvata pentru o subdiviziune. Stocarea unei subdiviziuni ca o stocare de segmente de linie
nu este o idee buna. Operatiuni cum ar fi raportarea la limita a unei regiuni ar fi destul de complicata. Este
mai bines a include, informatii structurate topologic: ce segmente lega o anumita regiune, care regiune
este adiacenta, si asa mai departe.
Hartile pe care le consideram subdiviziuni plane induse de incorporarea graficelor plane. O astfel de
subdiviziune este conectata in cazul in care graficul de baza este conectat. Incastrarea unui nod al
graficului este numit nod, iar incastrarea unui arc se numeste margine. Noi consideram doar incorporare
in cazul in care fiecare muchie este degment de linie dreapta. In principiu, marginile intr-o subdiviziune
nu trebuie sa fie drepte.
O subdiviziune nu trebuie sa fie chiar o incastrare plana a unui graphic, deoarece pot avea margini
nemarginite. In aceasta sectiune, cu toate acestea, noi nu consideram o subdiviziune mai generala. Noi
considera ca o margine sa fie deschisa, adica, obiectivele sale sunt nodurile din care nu fac parte din
subdiviziune. O fata a subdiviziunii este un subset maximal conectat cu planul, care nu contine un punct
situate pe o margine sau nod. Astfel, o fata este o regiune poligonala deschisa a carei limita este formata
din margini si varfuri din subdiviziune. Complexitatea subdiviziunii este de fapt ca suma numarului de
noduri. In cazul in care un varf este un obiectivul unei margini, atunci spunem ca varful si marginea sunt
incidente. In mod similar, o fata si o margine de pe linia ei sunt incidente, si o fata a nui varf al
frontierelor sale sunt incidente. Ce ar trebui sa cerem de la o reprezentare a unei subdiviziuni? O operatie
s-ar putea cere pentru a determina o suprafata care contine un anumit punct. Acesta este cu siguranta util
in unele aplocatii, intr-adevar, intr-un capitol urmattor avem proiectarea unei structure de date pentru
acesta, dar este putin cam mult pentru a cere o reprezentare de la o baza. Lucrurile pe care le putem cere
ar trebuii sa fie mai locale. De exemplu, este rezonabil sa impunem ca putem merge in jurul valorii limita
a unui anumit chip, sau ca am putea avea acces la o singura fata dintr-o alta invecinata, dca ni se da o
comuna margine. O alta operatiune care ar putea fi utila este de a vizita marginile din jurul unui varf dat.
Reprezentarea pe care o vom discuta sustine aceste operatiuni. Se numeste lista de margine dubluconectat.
O list de margine dublu-conectat conine o nregistrare pentru fiecare fa , margine, i vrfurile
subdiviziunii. Pe langa geometric i topologic informa iile sunt descries n scurt timp, fiecare
nregistrare poate stoca, de asemenea, informa ii suplimentare. De exemplu, n cazul n care o
subdiviziune reprezint o hart tematic pentru vegeta ie, Lista dublu conectata de margine s-ar stoca n
fiecare nregistrare a tipul de vegetaie si a regiunii corespunztoare. Informa iile de suplimentare sunt,
de asemenea, numite atribut de informaie. Informa iile geometrice i topologice stocate n Lista dublu
inlantuita de margine ar trebui s ne permit s efectueze opera iile de baz men ionate mai devreme.
Pentru a putea s se plimbe n jurul feei, n ordine invers acelor de ceasornic vom pstra un pointer de la
fiecare margine la alta. Ea poate veni, de asemenea, la ndemn s se plimbe n jurul valorii de a o
confrunt cu un alt mod, asa ca am stocat, de asemenea, un pointer la marginea anterioar. O margine de
obicei, are dou fee mrginete, deci avem nevoie de dou perechi de indicii pentru ea. Este convenabil
pentru a vizualiza diferitele pri ale unei muchii ca dou jumt i de margini distincte, astfel nct s
avem un unic urmtor de jumtate de or i jumtate anterior de vrf pentru fiecare jumtate de margine.
Acesta de asemenea inseamna ca are un hotar jumatate de margined oar o singura
fata. Cele doua jumatati de margini pe care le primim de la marginea data sunt

numite gemeni. Definind urmatoarea jumatate de margine a unei anumite jumatati


de margine in ceea ce priveste o traversare inversa a acelor de ceasornic a unei
fete induce o orientare asupra fiecarei jumatati de margine: ea este orientate astfel
incat fata pe care o margineste sta la stanga ei pentru un observator de mers pe
jos de-a lungul marginii. Pentru ca jumatatile de margine sunt orientate putem sa
vorbim despre originea si destinatia jumatatii de margine. In cazul in care o
jumatate de margine

are v ca origine si w ca destinatie, apoi are dublu twin(

e ) cu w ca punct de origine si v ca destinatie. Pentru a ajunge la limita unei fete


avem nevoie doar sa stocam un singur indicator in inregistrarea fata de un arbitrar
pe o jumatate de margine care delimiteaza fata. Pornind de la acea jumatate de
margine, putem pas cu pas sa ajungem de la o jumatate de margine la alta si in
jurul valorii ei. Ceea ce am spus pur i simplu nu deine destule limite de guri ntr-un chip: n cazul
n care acestea sunt traversate n ordine inversa a acelor de ceasornic, apoi fa a se afl la dreapta. Aceasta
va fi convenabil s se orienteze jumtate din margini, astfel nct fa a lor sa se afl ntotdeauna la aceea i
distant , astfel nct s schimbm direcia traversala pentru limita unei guri pentru sensul acelor de
ceasornic. Acum o fa se afl ntotdeauna la stnga oricrei jumtati de margine de pe marginea sa.
O alt consecin este c jumtatile marginilor gemene au ntotdeauna orientri opuse.
Prezena gurilor ntr-un chip nseamn, de asemenea, c un singur indicator de pe fata
arbitrar a jumtatii de margine de pe marginea sa nu este suficienta pentru a vizita intreaga limita:
avem nevoie de un pointer la o jumtate de or n fiecare component de delimitare. n cazul n care o fa
are vrfuri izolate aceasta nu are nici o margine de incident, deci putem stoca indicii pentru a le
deasemenea. Pentru simplificare, vom ignora acest caz.
Haidei s rezumam. Lista marginii dublu conectate const in trei colectii de inregistrari:
unul pentru nodurile, unul pentru fee i unul pentru marginile jumtati.
Aceste nregistrri pstreaz elementele geometrice si topologice prin urmtoarele:
Record de noduri de un nod v inmagazineaza coordonatele lui v ntr-un domeniu numit
Coordinate(v). Se stocheaz, de asemenea, un indicator Incident Edge(v) spre o arbitrare
jumtate-marginea a carui v este originea sa.
Record de fata de la o fata f stocheaz un pointer OuterComponent (f) la o
jumtate-margine spre limita sa exterioar. Pentru fata nemrginit acest indicator este nul.
Se stocheaz, de asemenea, o list de componente interioar (f), care conine, pentru fiecare gaura in
fata un pointer la o jumtate-margine pe marginea gurii.

Recordul jumatate de margine a unei jumatati de varf

e stocheaza un pointer de origine(

e ) la originea sa, un pointer twin( e ) dublu cu jumatate de margine, si un pointer


IncidentFace( e ) fata de limita sa. Noi nu avem nevoie de destinatia unei margini pentru a
stoca, deoarece este egala cu originea( Twin( e )). Originea este aleasa astfel incat
IndiceleFace( e ) se afla in stanga? Este atunci cand este traversat de originea destinatiei.
Recordul jumatate de margine stocheaza, de asemenea, indicia urmatori ( e ) si Prec( e ) la
marginea urmatoare si anterioara cu privire la limita IndiceFace( e ). Prin urmare in continuare
( e ) este unica pe jumatatea de margine a granite IndiceFace( e ) care are destinatia

e ca

originea sa, si precedeul ( e ) este unic pe jumatate de margine de pe limita de IncidentFace(

e ) care isi are originea ( e ) ca destinatie.


O cantitate constant de informaii se utilizeaz pentru fiecare nod i margine. O fa poate
necesita mai multe date de stocare, deoarece InnerComponents din lista (f) au ct mai multe elemente
deoarece exist guri n fa. Pentru c pentru orice jumtate de margine este indicat cel mult o dat
din toate InnerComponents (f)cu liste mpreun, am ajuns la concluzia c valoarea de stocare este liniar
n complexitatea subdiviziunii. Un exemplu de lista de margine dublu conectata pentru o subdiviziune
simpl este prezentat mai jos. Cele dou jumt i de margini corespunznd unei margini sunt etichetate

e i ,1 si e
i ,2 .
Varf

v1

Coordonate

Muchia incidenta

(0,4)

e 1,1

v2

(2,4)

e 4,2

v3

(2,2)

e 2,1

v4

(1,1)

e 2,2

Faa
f1

f2

Componente exterioar

e 1,1

zero

e 4,1

Jumatate de muchie
Anteriorul

zero

Origine

e 1,1

e 4,2

v1

e 1,2

f1

v2

e 1,1

f2

v3

e 2,2

f1

v4

e 2,1

f1

e 4,2

e 2,2
e 3,1

Fata de indice

e 4,1

e 2,1
e 2,2

dublu(twin)

e 3,1

e 1,2

e 3,2

Componente interioare

e 2,2

Urmatorul

e 3,1

e 1,1

e 3,1

f2

v3

e 4,2

f2

v2

e 4,1

e 3,2

e 4,2
e 2,1

v1

f1

e 1,2

e 4,1
e 1,2

e 3,2

e 2,2

e 3,2

e 4,1

v3

f1

e 1,1

Informatia stocata in lista de margine dublu-conectat este suficienta pentru a efectua operaatiile de baza.
De exemplu, putem merge in jurul limitei exterioare unui anumit chip f urmand urmatoarele indicii,
pornind de la o jumatate de margine Componenta exterioara(f). De asemenea,putem vizita toate marginile
incidente la un varf v. Este un exercitiu bun pentru a ne da seama cum sa facem acest lucru.
Am descries o versiune destul de generala a liste de margine dublu-conectate. In aplicatiile in care
nodurile nu transporta informatii atribut am putea stoca coordonatele lor direct in campul de origine() al
marginii; nu e nevoie stricta pentru un tip separate de inregistrare la varf. Chiar si mai important este sa
realizam ca in multe aplicatii fetele subdiviziunii nu purta nici un sens interesant (Cred ca a retelei de
rauri sau drumuri pe care ne-am mai uitat inainte). In cazul in care ne putem uita complet pe
inregistrarile fetei, Indicele din fata() este camp de jumatati de margini. Dupa cum vom vedea, algoritmul
sectiunii urmatoare nu are nevoie de aceste campuri(si este de fapt mai simplu de a pune in aplicare acest
caz in care nu avem nevoie sa se actualizeze). Unele implementari e liste de margini dublu-conectate pot,
de asemenea insista asupra faptului ca graficul de varfuri si muchiile subdiviziunii sa die conectate. Acest
lucru poate fi intotdeauna realizat prin introducerea marginilor false si are doua avantaje. In primul rand,
un grafic simplu transversal poate fi folosit pentru a vizita toate jumatatile de margini, iar pe de alta parte,
la Componentele Interioare() lista de fete nu este necesara.
2.3 Calcul Suprapunere a doua subdiviziuni
Acum ca ne-am proiectat o buna reprezentare a unei subdiviziuni, putem aborda problema generala
a harti supapunere. Vom defini suprapunerea a doua subdiviziuni S1 si S2 sa fie compartimentate
O(S1,S2), astfel iincat sa existe o fata f in O(S1,S2) daca si numai daca exista fete f1 in S1 si S2 in
F2 astfek incat f este maxim un subgroup conectat de f1

f2. Acest lucru suna mai complicat

decat este: ce inseamna ca suprapunerea este subdiviziune a planului indus de marginile de la S1 si


S2. Figura de mai jos ilustreaza acest lucru. Problema generala este harta de suprapunere care
calculeaza o lista de margine dublu-conectata pentru O(S1,S2), avand in vedere listele de margine
dublu-conectate S1 si S2. Solicitam ca fiecare fata in O(S1,S2) sa fie etichetate cu etichetele fetelor
din S1 si S2 pe care le contin. Astfel, au acces la informatiile despre attribute stocate pentru aceste
fete. Intr-o suprapunere a unei harti de vegetatie si o harta de precipitare, acestea ar insemna ca noi
stim pentru fiecare regiune in suprapunere tipul de vegetatie si cantitatea de precipitatii.

Sa vedem mai intai cat mai multe informatii din listele de margini dublu-conectate pentru S1 si S2,
ce putem re-utiliza in lista de margine dublu-conectata pentru O(S1,S2). Luati in considerare reteau
de muchii si varfuri ale lui S1. Aceasta retea este taiata in bucati de marginele lui S2. Aceste piese
sunt pentru o mare parte re-utilizabile; numai marginile care au fost taiate de marginile lui S1 ar
trebui sa fie reinnoite. Dar oare acest lucru detine, de asemenea pentru inregistrarile de jumatate de
margine in lista de margine dublu-conectate,care corespund pieselor? In cazul in care orientarea
jumatatilor de margine s-ar schimba, am fi in continuare nevoiti sa schimbam informatiile cuprinse in
aceste inregistrari. Din fericire, acest lucru nu este cazul. Jumatatile de margine sunt orientate astfel
incat fatele care au legat falsuri la stanga; forma fetei se poate schimba in suprapunere,dar va ramane
pe aceasi parte a jumatatii de margine. Prin urmare, putem re-utiliza inregistrarile jumatatilor de
margine corespunzatoare marginii care nu sunt intersectate de marginile din cealalta harta. Astfel
spus, inregistreaza doar o jumatate de margine in lista de margine dublu-conectata pentru O(S1,S2) pe
care nu le putem imprumuta de la S1 sau S2 sunt cele care sunt incidente intr-o intersectie intre
marginile din diferitele harti.
Acest lucru sugereaza urmatoarea abordare. In primul rand, copiati listele de margine dubluconectate ale lui S1 si S2 intr-o noua lista de margine dublu-conectata. Noua lista de margine dubluconectata nu este o lista de margine dublu-conectata valida, desigur, in sensul ca aceasta nu reprezinta
inca o subdiviziune plana. Aceasta este sarcina algoritmului de suprapunere: acesta trebuie sa
transforme lista de margine dublu-conectat in o lista valida de margine dublu-conectata pentru
O( S1,S2), prin calculul intersectiei intre cele doua retele de margini, si care leaga impreuna partile
adecvate din cele doua liste de margine dublu-conectate.
N-am discutat despre noile recorduri inca. Informatiile pentru acestea inregistrari sunt mai dificil de
calculat, asa ca vom lasa asta pentru mai tarziu. Noi descriem mai intai intr-un mod mai indetaliat in
care sunt calculate inregistratile nodurilor si jumatatilor de margini ale listei d margine coectate de
doua ori pentru O(S1,S2).
Algoritmul nostru se bazeaza pe algoritmul planului de rotatie de la sectiunea 2.1 pentru calcularea
intersectiilor dintr-un set de segmente. Rularea acestui algoritm se face pe seturi de segmente care
sunt unirea dintre seturile de margini ale celor doua subdiviziuni S1 si S2. Aici consideram marginile
care urmeaza sa fie inchise. Sa ne amintim ca algoritmul este sustinuit de doua structuri de date: un Q
coada eveniment, care stocheaza evenimentul in puncte, iar structura de stare T, care este un binary de
cautare care stocheaza arborele care echilibreaza segmentele ce se intersecteaza cu liniile de rotire,
comandat de la stanga la dreapta. Noi acum mentinem,de asemenea, o lista de margine dubluconectate D. Initial, D contine o copie din lista de margine dublu-conectata pentru S1 si o copie din
lista de margine pentru S2. In timpul algoritmului matura, vom transforma D la o corecta lista de

margine dublu conectata pentru O(S1,S2). Cu alte cuvinte, in ceea ce priveste varful si inregistrarile
pe jumatate de margine sunt in cauza; informatia nominal va fi calculate mai tarziu. Noi pastram
indicia incrucisati intre marginile din structura de stare T si inregistratile de jumatate de margine in D
care le corespund. In acest fel putem accesa o parte din D, care trebuie sa fie schimbat, atunci cand
ne intalnim cu un punct de intersectie. Invariantul in care ne mentine faptul ca, in orice moment pe
parcursul algoritmului matura, partea de suprapunere de deasupra liniei de rotire a fost calculata
corect.
Acum, se ia in considerare ceea ce trebuie sa facem cand ajungem la un punct de eveniment. Prima
data am actualizat T si Q ca in algoritmul de intersectie de segment de linie. In cazul in care
evenimentul implica margini doar la una dintre cele doua subdiviziuni, acesta este tot; Evenimentul
punct este un nod care poate sa faca modificari locale la D pentru a lega lista de margi dublu
conectate ale celor doua subdiviziuni orginale la punctul de intersectie. Asta e obositor, dar nu este
dificil.
situaia geometric, a
dou liste de margine dublu-conectate
nainte de a manipula intersecia

lista margine dublu conectata


dupa intersectia de manipulare

Noi descriem detaliile pentru una dintre posibilele cazuri, si anume atunci cand o margine e de la
S1 trece printr-un varf v din S2, a se vedea mai sus. Muchia e trebuie sa fie inlocuita cu doua
margini notate e i e . In lista de margine dublu-conectata, doua jumatati de margini pentru e
trebuie sa devina patru. Noi cream doua noi recorduri de jumatate de margine, cu v ca origine.
Cele doua existente jumatati de margini pentru e mentin capetele e ca si originea lor, asa cum se
arata in fig. 2.5. Apoi vom asocial pana la jumatate de marginile existente cu noile jumatati de
margini prin setarea unor indici twin(). Asa ca e este reperzentat de unul nou si unul existent pe
jumatate de margine, iar acelasi lucru este valabil pentru e . Acum noi trebuie sa stabilim un
numar de Prec() si Next() indicii. Noi mai intai pentru a face fata situatiei in jurul valorii de
capetele e; mai tarziu ne vom face griji cu privire la situatie din jurul lui v. Next() cursoarele
celor doua noi jumatati de margini cu exemplarul urmator() pointerul vechi de jumatate de
margine, care nu este geamanul sau. Jumatatile de margini la care indicii indica ca trebuie sa se
actualizeze, de asemenea, indicatorul Prec() setat la noi jumatati de margini. Corectitudinea
acestui pas poatte fi verificata cel mai bine prin ultima cifra.
Ramane de corectat situatia in jurul valorii varfului v. trebuie sa setati Next() si Perv()
indicii la cele patru margini reprezentand e i e , si cele patru jumatati de muchii incidente de
la S2 la v. Am localiza aceste patru semi-muchii din S2 , unde e i e ar trebui sa fie in ordine

ciclica a marginilor in jurul nodurilor v. Exista patru perechi de jumatati de muchii care devin
legate printr-un urmator() pointer din unul si un indicator Proc() de cealalta. Luati in considerare
o jumatate de margine pentru e care are v ca destinatie. Acesta trebuie sa fie legat de prima
jumatate de margine, vazut in sensul acelor de ceasornic de la e , cu v ca originea sa. Jumatatemargine pentru e cu v ca originea sa trebuie sa fie legata de prima jumatate, invers acelor de ceasornicargine cu v ca destinatie. Aceleasi afirmatii sunt si pentru e.
Cele mai multe dintre pasii din descrierea de mai sus necesita timp numai constant. Numai
unde e i e apar in ordinea ciclica in jurul valorii lui v poate dura mai mult: va fi nevoie de
timp liniar de gradul v. Celelalte cazuri care pot fi punctele de trecere a doua margini din
diferitele harti, si care coincid nu au nodurile mai dificile decat in cazul tomcai discutat. Aceste
cazuri, de asemenea, iau timp O(m), unde m este numarul de muchii incidente la punctul
evenimentului. Acesta inseamna ca actualizarea D nu creste timpul de functionare al intersectiei
segmentului liniei algoritmului asymptotic. Observati ca fiecare intersectie pe care o gasim are
este nod de suprapunere. Rezulta ca inregistrarile nodurilor si inregistrarile pe jumatate de
margine ale listei de margine dublu-conectate pentru O(S1,S2) poate fi calculate in O(
n log n+k logn ) timp, in cazul in care n reprezinta suma complexitatii S1 si S2, iar k este
complexitatea suprapunerii.
Dupa ce campurile implica jumatati de margine recordurile sunt stabilite, ramane de calculate
informatiile despre fetele O(S1,S2). Mai precis, trebuie sa creeze un record de fata pentru fiecare
fata f in O(S1,S2), trebuie sa facem Compomentul de iesire(f) indica o jumatate de margine de pe
limita exterioara f, si noi trebuie sa facem o lista de componente interne(f) indicii jumatatilor de
margine pe limitele gaurilor inferioare f. Mai mult decat atat, trebuie sa setati Indicele din fata()
campuri din jumatate de margini la limita lui f, astfel incat ele indica inregistrarea fetei lui f. In
cele din urma, fiecare dintre fetele noi trebuie sa fie etichetate cu numele fetelor din vechiile
subdiviziuni pe care le contin.
Cat de multe inregistrari cu care ne confruntam vor fi acolo? Ei bine, cu exceptia fetei
nemarginite, fiecare chip are o limita exterioara unica, astfel incat numarul de inregistrari de fata
este egal cu numarul limitelor exterioare plus unu. Din partea listei de margine dublu-conectat
construite putem extrage cu usurinta toate ciclurile limita. Dar cum stim daca un ciclu este o
limita exterioara sau limita unei gauri intr-o fata? Acest lucru poate fi decis de catre un varf v din
extremitatea stanga a ciclului, sau, in cazul unor legaturi, la cea mai mica dintre extreme. Sa ne
amintim ca jumatate din margini sunt orientate in asa fel incat fata lor incidenta sa se afle la nivel
local spre stanga. Luati in considerare cele doua jumatati de margini ale ciclului, care sunt
incidente la v. Pentru ca noi stim ca fata incidentului se afla la stanga, putem calcula unghiul
acestor doua jumatati de muchii in interiorul fetei incidente. In cazul in care acest unghi este mai
mic decat 180 atunci ciclul este o limita exterioara, si in caz contrar este limita unei gauri.
Aceasta proprietate este valabila si pentru varful unui ciclu la stanga, dar nu neaparat pentru alte
noduri ale acestui ciclu.
Pentru a decide care ciclu de frontier leaga aceasi fata vom construe graficul G. Pentru fiecare
ciclu de delimitare-interior si exterior exista un nod in G. Exista, de asemenea, un nod pentru
limita exterioara imaginara a fetei nemarginita. Exista un arc intre cele doua cicluri, daca si
numai daca unul dintre cicluri este aceea delimitate a unei gauri, iar celalalt ciclu are o jumatate
de margine imediat la stanga din stanga varfului acelui ciclu gaura. In cazul in care nu exista nico
jumatate de margine in partea stanga la cel mai din stanga nod al ciclului, atunci modul care
reprezinta ciclul este legat de grupa nodului nemarginit. Ciclurile hole sunt prezentate ca cercuri
singular, iar ciclurile de delimitare exterioare sunt reprezentate ca dublu cercuri. Se observa ca

C3 si C6 sunt cicluri dde gauri in suprafata exterioara a carei delimitare este C2. In cazul in care
exista doar o singura gaura intr-o fata f, atunci graficul G leaga granita ciclului la limita
exterioara f. In general, acest lucru nu trebuie sa fie : o gaura poate fi, de asemenea, legat de o
alta gaura, dupa cum se poate vedea in fig. 2.6. Aceasta gaura, care se afla in aceasi figura f,
poate fi legata de limita exterioara f, sau poate fi legata de o alta gaura. Dar, in cele din urma
trebuie sa se incheie la conectarea unei gauri de la limita exterioara, asa cum lema urmatoare
arata.
Lema: 2.5 Fiecare component conectata la graficul G corespunde exact setului de cicluri de
incidente ai unei singure fete.
Demonstratie: Sa consideram un ciclu C, delimitand o gaura intr-un chip f. Pentru ca f se afla la
nivel local spre stanga varfului C, C trebuie sa fie conectat la un alt ciclu care margineste si f.
Rezulta de aici ca, in cicluri de aceasi component conexa a lui G este legata aceasi fata.

Pentru a termina demonstratia, ne arata ca fiecare ciclu care delimiteaza o gaura in f este in
aceeasi component conectata ca in limita exterioara f. Sa presupunem ca exista un ciclu pentru care acest
lucru nu este cazul. Fie C astfel un ciclu de extrema stanga, si anume, unul

S-ar putea să vă placă și