Bibliografie                                                             Ministerul Educaţiei şi Tineretului               ...
Aprobat la şedinţa Senatului Universităţii de Stat dinTiraspol din 26 ianuarie 2009.                                      ...
{se determină pozitia druizilor fata de dreapta}                                                         Cuprinsif sarrus(...
for i:=1 to n do                                            begin   {se transferă originea..}6. Probleme geometrice de con...
2. Druizii se află în interiorul                           Introducere   pătratului cu latura 2L şi   centul în originea si...
Cu toate că aparatul matematic necesar pentru re-                for i:=1 to m do                                         ...
Date de ieşire   Fişierul de ieşire va conţine pentru fiecare set de datecuvîntul YES, dacă există cel puţin un sector în c...
În unele cazuri,                                                             6.10. Druizioperaţia poate fi re-alizată inver...
6.9. Cetate                                                         Astfel, sistemul de ecuaţii pentru rotaţia cu un unghi...
Trecerea de la coordonatele carteziene (x, y) la cele po-            else                                                 ...
begin                                        Procedura de deplasare a coordonatelor cu valoarea                      nr:=n...
{3. Dreapta şi latura nu sunt paralele}                                                                              if (A...
var                                                       ce trece prin aceste două puncte este:       nuc,camp:pol;      ...
Pentru aceasta se verifică condiţiile:                          Date de intrare                                            ...
Exemplu                                                             Se observă că în cazul intersecţiei dreptei l şi a seg...
Expresia Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) va avea          6.7. Evadarevaloare: pozitivă, dacă dreapta l şi segmentul s n...
then begin st:=k; dr:=k+1; end        else begin              if (alfa < a[1].u)                 then begin st:=k+1; dr:=n...
Algoritmul elementar se bazează pe două afirmaţiisimple:                                                                   ...
Exemplu                                                         Apartenenţa punctului la un triunghi   atac.in            ...
Aplicarea marcajelor este realizată în fragmentul:                      6.6. Atac     for i:=1 to n-2 do                  ...
6.5. Turnuri                                                     care, în mod cert, aparţine înfăşurătoarei convexe. La   ...
a) Se consideră tripletul p1 ← p, p2 ← p[urm],                     Exemplu                                                ...
6.4. Carcasa                                                        Pseudocodul algoritmului are următoarea formă:        ...
de exemplu, în [7, 303]). Poziţia reciprocă a punctelor este     Exempludeterminată de funcţia sarrus, descrisă anterior. ...
6.3. Piatra                                                                   while i<nsus do                             ...
Rezolvare4. Triangularizări                                                                          program p02;         ...
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Algoritmi şi probleme de geometrie computaţională
Upcoming SlideShare
Loading in …5
×

Algoritmi şi probleme de geometrie computaţională

4,461 views

Published on

Algoritmii fundamentali de geometrie computaţională şi implementările lor în limbajul de programare Pascal

Published in: Education
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,461
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Algoritmi şi probleme de geometrie computaţională

  1. 1. Bibliografie Ministerul Educaţiei şi Tineretului al Republicii Moldova1. Ammeraal, Leen. Programming Principles in Computer Universitatea de Stat din Tiraspol Graphics. John Wiley and Sons, 1986.2. Ammeraal, Leen. Computer Graphics for the IBM PC. John Wiley and Sons, 1986.3. Cerchez, Emanuela. Programarea în limbajul C/C++ pen- tru liceu. Vol III. Iaşi: Polirom, 2007. Sergiu CORLAT4. Cormen, Thomas. Introducere în algoritmi. Cluj: Agora.5. Foley, James; Andries, Van Dam. Fundamentals of Interac- tive Computer Graphics. Addison-Wesley Publishing, 1984.6. Giumale, Cristian. Introducere în analiza algoritmilor. Iaşi: Algoritmi şi probleme Polirom, 2004. de geometrie computaţională7. Sedgewick, Th. Algorithms in C. Addison Wesley, 2001.8. Williamson, Gill. Combinatorics for Computer Science. New York: Dover publications, 2002.9. Ласло, М. Вычислительная геометрия и компьютерная графика на С++. Москва: Бином, 1997.10. Нагао, М. Структуры и базы данных. Москва: Мир, 1986.11. Новиков, Ф. А. Дискретная математика для программистов. Санкт Петербург: Питер, 2001.12. Пападимитриу, Х. Комбинаторная оптимизация. Алгоритмы и сложность. Москва: Мир, 1985.13. Препарата, Ф.; Шеймос, М. Вычислительная геометрия. Введение. Москва: Мир, 1989. 76
  2. 2. Aprobat la şedinţa Senatului Universităţii de Stat dinTiraspol din 26 ianuarie 2009. Notaţii p1 p2 – segment orientat (vector) cuToate drepturile asupra acestei ediţii aparţin autorului. originea în punctul p1Reproducerea integrală sau parţială a textului sau a S = { p1 ,..., pN } – mulţimea S, cu elementele p1, ..., pNilustraţiilor din această ediţie este permisă doar cu acor-dul scris al autorului. |S| – cardinalul mulţimii S i↑ – incrementarea valorii i cu 1Autor: Sergiu Corlat, lector superior, UST k ←m – variabilei k i se atribuie valoareaRecenzenţi: Andrei Braicov, variabilei m doctor, conferenţiar universitar, UST Emanuela Cerchez, [a, b] – interval cu extremităţile a, b profesor gradul I, Liceul de Informatică Grigore Moisil”, Iaşi abc – triunghi cu vârfurile a, b, c ” DV(S) – diagrama Voronoi pentru mulţimea SRedactor: Tatiana Rusu T(S) – triangularizarea mulţimii SCoperta: Valentina Stratu Q(S) – înfăşurătoarea convexă a mulţimii S© Sergiu Corlat, 2009 A⇒ B – din A rezultă B© Editura Prut Internaţional, 2009 A⇔ B – A este echivalent cu BEditura Prut Internaţional, str. George Enescu, nr. 6, x ∈ X , ( x ∉ X ) – x aparţine (nu aparţine) mulţimii Xbl.1, Chişinău MD 2064 – submulţimea elementelor x din X, careTel.: 75 18 74, 74 93 18; fax: 50 87 20; e-mail: prut@mtc.md {x ∈ X : Q} satisfac condiţia QCZU 519.6+514 C15 A⊆ B – A se conţine în B (A este submulţime a mulţimii B)ISBN 978-9975-69-377-6 qsort(A,n) – apel al procedurii pentru sortarea structurii de date A din n elemente 75
  3. 3. {se determină pozitia druizilor fata de dreapta} Cuprinsif sarrus(d[3],d[4],d[1])*sarrus(d[3],d[4],d[2]) < 0 then writeln(‘NO’) else writeln(‘YES’); Introducere 5 end; if m>=2 then begin 1. Transformări de coordonate 7{... si cazul general} movecenter; 1.1. Deplasări şi rotaţii 7 qsort(d,1,n); 1.2. Coordonate polare 9 vec:=FALSE; for i:=1 to n-1 do 1.3. Implementări 10 if (d[i].t=’L’) and (d[i+1].t=’L’) then vec:=TRUE; 2. Intersecţii 12 if vec then writeln(‘YES’) else writeln(‘NO’); end; 2.1. Intersecţia dreptelor 12end; {solve} 2.2. Intersecţia dreptei cu un segment 14 2.3. Intersecţia segmentelor 16 3. Înfăşurătoarea convexă 17 3.1. Algoritmul elementar 17 3.2. Algoritmul Graham 20 4. Triangularizări 26 4.1. Un algoritm greedy pentru mulţimi de puncte 26 4.2. Triangularizarea poligoanelor convexe 28 4.3. Triangularizarea poligoanelor simple 29 5. Apropiere şi apartenenţă 31 5.1. Cea mai apropiată pereche de puncte 31 5.2. Apartenenţa punctului la un domeniu 35 5.3. Poligonul şi diagrama Voronoi 39 5.4. Nuclee 44 74
  4. 4. for i:=1 to n do begin {se transferă originea..}6. Probleme geometrice de concurs 48 d[i].x:=d[i].x - xint; d[i].y:=d[i].y - yint;6.1. Robot 48 { ... si se determină coordonatele polare - unghiul!}6.2. Robot II 506.3. Piatra 52 if d[i].x<>0 then begin6.4. Carcasa 54 d[i].a:=180/pi*arctan(abs(d[i].y/d[i].x));6.5. Turnuri 56 if (d[i].x<0) and (d[i].y>0) then d[i].a:=180-d[i].a;6.6. Atac 57 if (d[i].x<0) and (d[i].y<=0) then d[i].a:=d[i].a+180;6.7. Evadare 61 if (d[i].x>0) and (d[i].y<0) then d[i].a:=360-d[i].a;6.8. Arcaşi 62 end else begin if d[i].y> 0 then d[i].a:=90;6.9. Cetate 68 if d[i].y<0 then d[i].a:=270;6.10. Druizi 69 end; endNotaţii 75 end; {movecenter}Bibliografie 76 4. Se sortează sistemul de puncte pi după creşterea măsurii unghiului format de fiecare vector Opi cu axa Ox. 5. Dacă după sortare există cel puţin două puncte vecine, reprezentând druizi, rezultă existenţa unui sector al câmpiei cu aceeaşi proprietate. procedure solve; var vec: boolean; begin {cazurile elementare...} if ((m=0) and (n=1)) or ( (m=1) and (n=3)) then writeln(‘NO’); if ((m=0) and (n>1)) or ((m=1) and (n>4)) then writeln(‘YES’); if (m=1) and (n=4) then begin 73
  5. 5. 2. Druizii se află în interiorul Introducere pătratului cu latura 2L şi centul în originea sistemu- Geometria computaţională constituie una din ramurile lui de coordonate. Ei se află importante ale matematicii aplicate moderne. Pornind şi în interiorul cercului de de la cercetarea unor elemente geometrice simple (punct, rază 2L şi centrul în ori- segment, dreaptă), se ajunge la o modelare complexă a ginea sistemului de coordo- figurilor geometrice în plan şi a corpurilor în spaţiul tri- nate. Pentru fiecare din lini- dimensional. ile energetice se determină Algoritmii geometriei computaţionale stau la baza tutu- punctele ei de intersecţie cu ror aplicaţiilor de proiectare şi modelare grafică (aplicaţii cercul de rază 2L şi centrul în originea sistemului CAD, procesoare de grafică vectorială, aplicaţii de modelare de coordonate. Aceste puncte se marchează aparţinând 3D). Fără ei ar fi imposibilă proiectarea construcţiilor ar- dreptelor (D) de separare a sectoarelor. hitecturale moderne, realizarea proiectelor GPS, apariţia majorităţii absolute a produselor cinematografice de suc- 3. Originea sistemului de ces din ultimii ani. Enumerarea domeniilor de aplicarecoordonate se deplasează în poate fi continuată la nesfârşit.punctul de intersecţie a drepte- Domeniul vast de aplicare şi multitudinea fenome-lor (liniilor energetice). Apoi se nelor şi situaţiilor reale, descrise în termenii geometrieitrece la coordonatele polare computaţionale, au impus apariţia unor probleme geome-pentru punctele ce reprezintă trice în cadrul concursurilor de programare de cele maidruizii şi intersecţiile liniilor diferite nivele.energetice cu cercul (realizare Prezenta lucrare este concepută ca un curs de iniţiere în– procedura movecenter). algoritmii de geometrie computaţională pentru studenţii facultăţilor de profil, pentru profesorii de informatică,procedure movecenter; precum şi pentru elevii claselor liceale, participanţi labegin concursurile naţionale şi internaţionale de programare.{se determină punctul de intersectie al dreptelor} Un alt scop este de a-i forma cititorului abilităţi deif l1a<>0 then analiză şi proiectare a algoritmilor. În acest sens, algo- begin yint:=(l1c*l2a-l1a*l2c)/(l2b*l1a-l2a*l1b); ritmii şi soluţiile problemelor sunt însoţite de descrieri xint:=(-l1b*yint-l1c)/l1a; ale structurilor de date, fragmente de cod, de calcule ale endelse begin yint:=-l1c/l1b; complexităţii. xint:=(-l2b*yint-l2c)/l2a; end; 72 5
  6. 6. Cu toate că aparatul matematic necesar pentru re- for i:=1 to m do beginzolvarea problemelor de geometrie computaţională este readln(a,b,c);relativ simplu, implementarea acestuia este însoţită de if i=1 then begin l1a:=a; l1b:=b; l1c:=c; end;necesitatea cercetării unui număr considerabil de cazuri if i=2 then begin l2a:=a; l2b:=b; l2c:=c; end; ae:=b*b+a*a;speciale. Acesta este un motiv pentru care problemele de be:=2*b*c;geometrie computaţională se consideră printre cele mai ce:=c*c-a*a*2*r*r;dificile, în special în condiţii de concurs. de:=be*be-4*ae*ce; if a<>0 then begin Cercetarea şi optimizarea soluţiilor propuse pentru inc(n);unele din problemele prezente în lucrare îi vor permite d[n].y:=(-be-sqrt(de))/2/ae;cititorului să capete o experienţă necesară la comparti- d[n].x:=(-b*d[n].y-c)/a; d[n].t:=’D’;mentul rezolvare de probleme şi, nu în ultimul rând, la inc(n);generarea testelor pentru verificarea soluţiilor. d[n].y:=(-be+sqrt(de))/2/ae; La baza lucrării se află o serie de articole publicate d[n].x:=(-b*d[n].y-c)/a; d[n].t:=’D’;pe parcursul ultimilor ani în revista de matematică şi endinformatică Delta, materiale şi probleme elaborate în else begincadrul şcolilor de vară la informatică (ediţiile anilor inc(n);2001, 2002), precum şi probleme propuse la concur- d[n].y:=-c/b; d[n].x:=sqrt(2*r*r-c*c/b/b);sul de pregătire continuă la informatică „.campion” d[n].t:=’D’;(campion.edu.ro). inc(n); Ţin să aduc sincere mulţumiri tuturor celor care au d[n].y:=d[n-1].y; d[n].x:=-d[n-1].x;contribuit la apariţia acestei cărţi, în special colectivului d[n].t:=’D’;Catedrei de Informatică şi Tehnologii Informaţionale a end;Universităţii de Stat din Tiraspol. end; end; {readdata} Ianuarie 2009 Sergiu Corlat În rezolvare vor fi parcurse următoarele etape: 1. Toate liniile se intersectează într-un punct, care trebuie determinat. Dacă numărul de linii este 0 sau 1, sunt câteva cazuri elementare, care se cercetează aparte. Dacă numărul de linii este mai mare sau egal cu doi, atunci se folosesc oricare două linii pentru a determina coordonatele punctului de intersecţie. 6 71
  7. 7. Date de ieşire Fişierul de ieşire va conţine pentru fiecare set de datecuvîntul YES, dacă există cel puţin un sector în care se 1. Transformări de coordonateaflă doi sau mai mulţi druizi, NO, în caz contrar. Fiecare 1.1. Deplasări şi rotaţiirăspuns se va scrie într-o linie aparte, în ordinea apariţieiseturilor de date în fişierul de intrare. Rezolvarea oricărei probleme de geometrie computa- ţională începe (dacă e necesar) cu deplasarea coordonate-Exemplu lor elementelor cercetate (de cele mai dese ori, ale puncte- druizi.in druizi.out lor) într-un domeniu potrivit al sistemului de coordonate 3 2 3 YES 2 2 NO (de obicei, în cadranul unu). În unele cazuri, deplasarea 1 -1 poate fi însoţită şi de rotaţia sistemului de coordonate. -2 0 1 1 -1 Fie într-un sistem cartezian de coordonate un punct p 0 1 -1 de coordonate (x, y). Deplasarea de coordonate de-a lungul # axei Ox cu o valoare dată a implică o modificare a coordo- 1 0 100 natelor punctului conform formulelor: 0 0 ⎧ x′ = x + a ,Rezolvare ⎨ ⎩ y′ = y. Pentru implementare vor fi definite tipurile şi struc- În cazul deplasării de-a lungulturile: axei Oy cu valoarea b, transformareatype pt=record x,y,a:real; T:char; end; de coordonate va fi dată de sistemul: dr=array[1..3003] of pt; ⎧ x′ = x,var ⎨ d:dr; ⎩ y′ = y + b. n,m,i:integer; Modificarea „combinată” a coordo- Fig. 1.1. Rotaţia punctului int,xint,r,a,b,c,ae,be,ce,de, cu un unghi ϕ natelor cu a după axa Ox şi b după l1a,l2a,l1b,l2b,l1c,l2c: real; Oy va fi dată de sistemul: Pentru citirea şi preprocesarea datelor va fi utilizată ⎧ x′ = x + a ,procedura readdata: ⎨ ⎩ y′ = y + b.procedure readdata;begin Următorul tip de transformare este rotaţia cu un unghi readln(n,m,r); ϕ a punctului (punctelor) faţă de originea sistemului de for i:=1 to n do begin readln(d[i].x,d[i].y); d[i].t:=’L’; end; coordonate (fig. 1.1). 70 7
  8. 8. În unele cazuri, 6.10. Druizioperaţia poate fi re-alizată invers: prin Ruinele din Stonehenge se af-rotaţia originii siste- lă într-un loc special, unde semului de coordonate intersectează M linii energeticefaţă de un punct (sau ale Pământului. Liniile energe-sistem de puncte) dat. tice împart câmpia StonehengeAtunci există patru în sectoare. În fiecare an, în ceanumere a, b, c, d, care mai scurtă zi a anului, N druizipermit de a trece uni- se adună în câmpie pentru unvoc coordonatele ( x, y ) ritual, ce asigură o roadă bogată pentru anul următor. Pentru succesul ritualului este necesarîn ( x′, y′) , utilizând Fig.1.2. Determinarea cuadruplului a, b, c, d fo- losind punctele (1, 0) şi (0, 1) ca în fiecare sector al câmpiei, delimitat de liniile energetice,sistemul de ecuaţii: să se afle nu mai mult decât un druid. Câmpia are forma unui ⎧ x′ = ax + by, pătrat cu centrul în originea sistemului de coordonate şi care ⎨ (1.1) ⎩ y′ = cx + dy. are lungimea laturii 2 L. Liniile energetice sunt linii drepte. Druizii sunt punctiformi şi nu se pot afla pe liniile energetice. Pentru a determina acest cuadruplu de numere, pot fi Să se scrie un program care determină dacă există sec-folosite punctele (1, 0) şi (0, 1). toare ale câmpiei în care se află 2 sau mai mulţi druizi. Se observă că la rotaţia cu un unghi ϕ punctul de coor-donate (1, 0) trece în punctul (cos ϕ ,sin ϕ ) , iar punctul de Date de intrarecoordonate (0, 1) – în (− sin ϕ , cos ϕ ) (fig. 1.2). Fişierul de intrare conţine câteva (cel mult 5) seturi de După substituţia acestor valori, în calitate de coeficienţi date, separate prin câte o linie ce conţine semnul #. Prima linie a fiecărui set de date conţine numerele N, M şiai sistemului (1.1) se obţine: L (1 ≤ N ≤ 1000, 0 ≤ M ≤ 1000, 1 ≤ L ≤ 2000). Urmează N linii ce conţin câte două numere întregi xi, yi ⎧ x′ = a ⎧a = cos ϕ , ⎨ ⇒⎨ – coordonatele druizilor. Toţi druizii se află în interiorul câm- ⎩ y′ = c ⎩ c = sin ϕ . piei, oricare doi druizi nu coincid. Următoarele M linii ale setului de date conţin câte unAnalog: triplet de numere întregi ai, bi, ci. Numerele corespund ⎧ x′ = b ⎧ b = − sin ϕ , coeficienţilor ecuaţiei Ai x + Bi y + Ci = 0, care descrie linia ⎨ ⇒⎨ ⎩ y′ = d ⎩d = cos ϕ . energetică i. Niciun druid nu se află pe o careva linie. Oricare două linii nu coincid. Valorile ai, bi, ci nu depăşesc 10000 după modul. 8 69
  9. 9. 6.9. Cetate Astfel, sistemul de ecuaţii pentru rotaţia cu un unghi Arheologii din Bitlanda în timpul ϕ a unui punct arbitrar în jurul originii sistemului de co-săpăturilor au descoperit nişte pietre ordonate ia forma:aşezate oarecum straniu. Ei au ajuns ⎧ x′ = x cos ϕ − y sin ϕ ,la concluzia ca acestea formează frag- ⎨mente ale unui zid circular, care încon- ⎩ y′ = x sin ϕ + y cos ϕ .jura o cetate veche. În cazul în care rotaţia cu unghiul ϕ a punctului de Pentru a proteja de turişti şi de coordonate ( x, y ) este efectuată faţă de punctul de coordo-curioşi fragmentele descoperite, arheo- nate ( x0 , y0 ) , diferit de originea sistemului de coordonate,logii au decis să le înconjoare cu un gard din plasă metalică. întâi se transferă originea sistemului de coordonate înDeoarece este destul de complicat şi incomod de a înconjura centrul de rotaţie, apoi se efectuează rotaţia în jurul noiifiecare fragment, s-a luat decizia de a împrejmui toate frag- origini a sistemului de coordonate:mentele împreună. ⎧ x′ − x0 = ( x − x0 ) cos ϕ − ( y − y0 ) sin ϕ Să se scrie un program care să determine lungimea minimă ⎨a plasei necesare pentru a îngrădi fragmentele zidului. ⎩ y′ − y0 = ( x − x0 ) sin ϕ + ( y − y0 ) cos ϕDate de intrare sau Prima linie a fişierului de intrare conţine două numere: ⎧ x′ = x0 + ( x − x0 ) cos ϕ − ( y − y0 ) sin ϕn (1≤n≤180) – numărul fragmentelor de zid; r (1≤r≤100) – ⎨ ⎩ y′ = y0 + ( x − x0 ) sin ϕ + ( y − y0 ) cos ϕraza zidului. Urmează n perechi de numere întregi, caredescriu fragmentele de zid: ai, bi – măsura unghiurilor(în grade) care descriu începutul şi sfârşitul fragmentu- 1.2. Coordonate polarelui. Unghiurile se măsoară începând cu direcţia nord de Problemele în care apare necesitatea parcurgerii uneila centrul cetăţii, în sens opus mişcării acelor de ceasornic mulţimi de puncte pi , i = 1, N de coordonate (xi , yi) după(0 ≤ ai; bi < 360, ai ≠ bi). Fiecare fragment este descris unghiurile formate de vectorii Opi cu axa Ox se rezolvăla fel împotriva direcţiei de mişcare a acelor de ceasornic. mai simplu în coordonateFragmentele de zid nu au puncte comune. polare, unde fiecare punct pDate de ieşire este determinat de perechea Fişierul de ieşire va conţine lungimea minimă a plasei (r , ϕ ) , unde r este distanţanecesare, cu trei cifre după virgulă. de la punct până la origineaExemplu sistemului de coordonate, iar cetate.in cetate.out 2 10 61.888 ϕ – unghiul format de vecto- Fig. 1.3. Coordonatele polare ale 330 30 rul Op cu axa Ox (fig. 1.3). punctului de coordonate carteziene 90 270 (x, y) 68 9
  10. 10. Trecerea de la coordonatele carteziene (x, y) la cele po- else if sarrus(camp[j],camp[j+1],nuc[1])>=0 thenlare este determinată de următoarele formule [1, p. 77]: begin writeln(0); close(output); halt; ⎧ x end; ⎪ arctan y y>0 end; ⎪ ⎪ x function area(a:pol;n:integer):real; y<0 ⎪ ⎪π + arctan y r = x2 + y 2 , ϕ =⎨ {aria poligonului simplu} ⎪ π var s:real; x = 0, y > 0 ⎪ 2 i:integer; ⎪ begin 3π ⎪ x = 0, y < 0 s:=0; ⎪ ⎩ 2 for i:=1 to n do s:=s+(a[i+1].x-a[i].x)*(a[i+1].y+a[i].y)/2; area:=s;1.3. Implementări end; În problemele de geometrie computaţională pot apărea {programul principal}diferite modele de transformare a coordonatelor: deplasări begindupă o axă, deplasări combinate (după ambele axe), rotaţii assign(input,’arcas.in’);faţă de un punct, deplasări însoţite de rotaţii. Toate aceste reset(input); assign(output,’arcas.out’);transformări presupun recalcularea coordonatelor unui rewrite(output);punct sau ale unui sistem de puncte. init; Pentru rezolvarea eficientă a problemelor de geometrie for i:=1 to ncamp do cut(i);este foarte important de a alege corect structurile de date. writeln(area(nuc,nnuc));Pentru implementarea transformărilor de coordonate este close(input);necesară descrierea unei singure structuri – punctul: close(output); end.type point=record x,y : real; end; Orice obiect geometric determinat de un sistem depuncte poate fi descris cu ajutorul unui tablou unidimen-sional sau printr-o listă alocată dinamic, cu elemente detip point. 10 67
  11. 11. begin Procedura de deplasare a coordonatelor cu valoarea nr:=nr+1; vx după axa Ox şi cu valoarea vy după axa Oy poate fi inter[nr].x:=xint; inter[nr].y:=yint; realizată în modul următor: index[nr]:=i; end; procedure move(var P:point; vx,vy:real); end; beginif nr>=2 then P.x:=P.x+vx; begin P.y:=P.y+vy; if sarrus(camp[j],camp[j+1],nuc[index[1]])>=0 end;then La fel de simplă este şi o posibilă implementare a rota- begin ii:=1; ţiei cu un unghi u faţă de un punct de coordonate vx, vy: copy[1].x:=inter[1].x; procedure rotate (var P:point; u,vx,vy:real); copy[1].y:=inter[1].y; var for k:=index[1]+1 to index[2] do old:point; begin begin inc(ii); copy[ii]:=nuc[k]; old:=P; end; P.x:=vx+(old.x-vx)*cos(u*pi/180) inc(ii); copy[ii].x:=inter[2].x; -(old.y-vy)*sin(u*pi/180); copy[ii].y:=inter[2].y; P.y:=vy +(old.x-vx)*sin(u*pi/180) nnuc:=ii; +(old.y-vy)*cos(u*pi/180); inc(ii); copy[ii].x:=inter[1].x; end; copy[ii].y:=inter[1].y; end else begin ii:=0; for k:=1 to index[1] do begin inc(ii); copy[ii]:=nuc[k]; end; inc(ii); copy[ii].x:=inter[1].x;copy[ii].y:=inter[1].y; inc(ii); copy[ii].x:=inter[2].x;copy[ii].y:=inter[2].y; for k:=index[2]+1 to nnuc do begin inc(ii); copy[ii]:=nuc[k]; end; nnuc:=ii; inc(ii); copy[ii]:=nuc[1] end; nuc:=copy; end 66 11
  12. 12. {3. Dreapta şi latura nu sunt paralele} if (Ad*Bl<>Bd*Al) then if Al<>0 then begin2. Intersecţii yint:=(Ad*Cl-Cd*Al)/(Bd*Al-Ad*Bl); xint:=(-Bl*yint-Cl)/Al; În majoritatea proble- endmelor de geometrie compu- elsetaţională apare în calitate de begin yint:=-Cl/Bl; xint:=(-Bd*yint-Cd)/Ad;subproblemă determinarea end;coordonatelor punctului de if (((xint>=nuc[i].x) and (xint<=nuc[i+1].x))intersecţie a două drepte, a or ((xint>=nuc[i+1].x) and (xint<=nuc[i].x))) and(((yint>=nuc[i].y) and (yint<=nuc[i+1].y))două segmente sau a unui Fig. 2.1. Definirea dreptei (segmentu- or ((yint>=nuc[i+1].y) and (yint<=nuc[i].y)))segment şi unei drepte. lui) prin două puncte then intersect:=true else intersect:=false; Metoda folosită pentru rezolvarea acestor subprobleme end;este aceeaşi, cu diferenţe puţin semnificative pentru fie- function sarrus(a,b,c:lat):real;care caz. begin sarrus:=a.x*b.y+b.x*c.y+a.y*c.x-c.x*b.y-b.x*a.y-c.y*a.x; Atât pentru definirea dreptei, cât şi pentru definirea end;segmentului se vor folosi două puncte distincte: arbitrare(ale dreptei) sau extreme (pentru segment)(fig. 2.1). procedure cut(j:integer); Prin urmare, atât descrierea dreptei, cât şi descri- { Procesează latura j a poligonului P}erea segmentului pot fi realizate de aceeaşi structură de vardate, care va conţine coordonatele a două puncte şi, supli- al,bl,cl,ad,bd,cd:real;mentar, coeficienţii A, B, C ai ecuaţiei generale a dreptei. inter: array[1..4] of lat; index: array[1..4] of integer;Aceşti coeficienţi vor fi necesari pentru calculul coordo- k,ii,i,nr:integer;natelor punctului de intersecţie. Una din posibilele me- copy: pol;tode de definire a acestei structuri este: begin Ad:=camp[j+1].y - camp[j].y; Bd:=camp[j].x-camp[j+1].x;type line=record Cd:=camp[j+1].x*camp[j].y-camp[j].x*camp[j+1].y; x1,y1,x2,y2 : real; nr:=0; A, B, C : real; for i:=1 to nnuc do end; begin Al:=nuc[i+1].y -nuc[i].y; Bl:=nuc[i].x-nuc[i+1].x;2.1. Intersecţia dreptelor Cl:=nuc[i+1].x*nuc[i].y-nuc[i].x*nuc[i+1].y; if intersect(al,bl,cl,ad,bd,cd,i,j) thenEcuaţia generală a dreptei Fie dreapta l determinată de punctele p1 de coordo-nate ( x1 , y1 ) şi p2 de coordonate ( x2 , y2 ) . Ecuaţia dreptei 12 65
  13. 13. var ce trece prin aceste două puncte este: nuc,camp:pol; i,nnuc,ncamp:integer; x − x1 y − y1 xint,yint:real; = . (2.1) x2 − x1 y2 − y1 procedure init; var square : array[1..5,1..2] of integer; i: integer; Din această ecuaţie pot fi calculaţi coeficienţii ecuaţiei begin generale a dreptei: Ax + By + C = 0 .{initializare nucleu} Prin transformări elementare din (2.1) se obţine: nuc[1].x:=0; nuc[1].y:=0; nuc[2].x:=0; nuc[2].y:=10001; x( y2 − y1 ) + y ( x1 − x2 ) + ( x2 y1 − x1 y2 ) = 0. (2.2) nuc[3].x:=10001; nuc[3].y:=10001; nuc[4].x:=10001; nuc[4].y:= 0; Din (2.2) rezultă formulele de calcul pentru coeficienţii nuc[5].x:=nuc[1].x; nuc[5].y:= nuc[1].y; ecuaţiei generale: nnuc:=4; A = y2 − y1 , {… si initializare poligon} readln(ncamp); B = x1 − x2 , (2.3) for i:=1 to ncamp do readln(camp[i].x,camp[i].y); C = x2 y1 − x1 y2 . camp[ncamp+1].x:=camp[1].x;camp[ncamp+1].y:=camp[1].y; end;function intersect Determinarea punctului de intersecţie (al,bl,cl,ad,bd,cd:real;i,j:integer): boolean; a două drepte{determină intersecţia dreptei şi laturii Fie dreptele p şi l determinate de perechile de puncte + coordonate punctului de intersecţie}begin p1 ( x1 , y1 ) , p2 ( x2 , y2 ) şi respectiv p3 ( x3 , y3 ) , p4 ( x4 , y4 ) . Determinarea punctului q de intersecţie a acestor{1. dreapta şi latura sunt paralele} if Ad*Bl=Bd*Al then begin intersect:=false; exit; end; drepte se reduce la rezolvarea sistemului de ecuaţii:{2. dreapta intersectează 2 laturi adiacente în punct extrem} ⎧ A1 x + B1 y + C1 = 0 if (camp[j+1].x=nuc[i].x) and (camp[j+1].y=nuc[i].y) ⎨ ⎩ A2 x + B2 y + C2 = 0, then begin intersect:=true; xint:=nuc[i].x; yint:=nuc[i].y; exit; unde A1 x + B1 y + C1 = 0 este ecuaţia generală a dreptei p end; şi A2 x + B2 y + C2 = 0 este ecuaţia generală a dreptei l. if (camp[j].x=nuc[i+1].x) and (camp[j].y=nuc[i+1].y) Coeficienţii acestor ecuaţii pot fi calculaţi conform for- then begin intersect:=true; xint:=nuc[i+1].x; mulelor (2.3). yint:=nuc[i+1].y; exit; Până la rezolvarea nemijlocită a sistemului urmează end; să se verifice dacă dreptele p şi l sunt paralele sau coincid. 64 13
  14. 14. Pentru aceasta se verifică condiţiile: Date de intrare Fişierul de intrare arcas.in va conţine pe prima linie un a) A1 B2 = A2 B1 & A1C2 ≠ A2C1 – dreptele p şi l sunt număr întreg N – numărul de vârfuri ale poligonului sim- paralele; plu care descrie perimetrul câmpului de luptă. Urmează N b) A1 B2 = A2 B1 & A1C2 = A2C1 – dreptele p şi l coincid. linii care conţin coordonatele vârfurilor poligonului, par- Dacă niciuna din condiţiile precedente nu se satisface, curse în sensul mişcării acelor de ceasornic, câte un vârfatunci există un punct unic de intersecţie a dreptelor p pe linie. Linia i+1 conţine două numere întregi xi, yi,şi l, ale cărui coordonate pot fi calculate după formulele: separate prin spaţiu, – coordonatele vârfului i. a) dacă A1 ≠ 0 , ysol = A1C2 − C1 A2 , Date de ieşire B2 A1 − B1 A2 Fişierul de ieşire arcas.out va conţine un singur număr (2.4 a) B y − C1 întreg – numărul maxim de arcaşi care pot fi plasaţi pe xsol = − 1 sol ; poziţii. A1 b) dacă A1 = 0 , Restricţii C 3 ≤ N ≤ 1000 ysol = − 1 , B1 0 < xi, yi ≤ 10000 (2.4 b) B y + C2 xsol = − 2 sol . Exemplu A2 arcas.in arcas.out 9 11 Cu ajutorul setului de formule (2.4) pot fi calculate co- 2 5 3 6ordonatele punctului de intersecţie q a dreptelor p şi l. 2 7 4 7 6 9 8 62.2. Intersecţia dreptei cu un segment 7 2 5 4 Formulele deduse în paragraful precedent permit să 3 4se calculeze coordonatele punctului de intersecţie a douădrepte. Cazul intersecţiei a două segmente sau a unei Rezolvaredrepte şi a unui segment pot fi reduse la cel al intersecţiei program p68;dreptelor, dar cu verificarea unor condiţii suplimentare. type lat=record x,y:real; end; Fie dreapta l care trece prin punctele p1 , p2 şi segmen- pol=array[0..1001] of lat;tul s cu punctele extreme s1 , s2 . 14 63
  15. 15. Exemplu Se observă că în cazul intersecţiei dreptei l şi a segmen- evadare.in evadare.out explicaţie tului s, extremităţile segmentului sunt poziţionate de părţi 5 3 7 7 DA diferite faţă de vectorul p2 p1 . Dacă obiectele cercetate nu 1 2 se intersectează, atunci ambele extremităţi ale segmentu- 2 6 6 4 lui se află de aceeaşi parte a vectorului p2 p1 (fig. 2.2). 6 7 7 5 10 4 7 2 3 16.8. Arcaşi Secretul victoriilor faimo- Fig. 2.2. Poziţia segmentului faţă de dreaptăsului comandant de oşti Mega-Flop este strategia lui de Poziţia punctului faţă de un vectoralegere a poziţiei arcaşilor pe Fie vectorul p2 p1 de coordonate ( x2 , y2 ) , ( x1 , y1 ) şicâmpul de luptă. Câmpul are punctul s de coordonate ( x3 , y3 ) .forma unui poligon simplu şi Pentru a poziţiona punctul s faţă de vectorul p2 p1 ,e înconjurat de păduri. Mega- poate fi folosit următorul determinant [12, p. 60]:Flop plasează arcaşii doar pe x2 y2 1poziţii din care este văzut totcâmpul de luptă. Se consideră Δ = x1 y1 1 .că arcaşii văd tot câmpul, dacă din orice punct care aparţine x3 y3 1poziţiei lor de tragere se poate trage cu săgeata în orice alt Determinantul este pozitiv, dacă punctul s este situatpunct al câmpului. Traiectoria săgeţii este liniară. Nimerind în semiplanul drept faţă de vectorul p2 p1 ; este nul, dacăîn pădure, săgeata se pierde. Pentru tragere, fiecare arcaş punctul s aparţine dreptei determinate de acest vector;are nevoie de o unitate de suprafaţă. Astfel, numărul ma- este negativ, dacă s este situat în semiplanul stâng.xim de arcaşi care pot fi plasaţi pe poziţii este determinat O realizare posibilă a funcţiei de calcul al determinan-de aria poligonului din care este văzută toată câmpia. tului este următoarea: Să se scrie un program care determină numărul maxim function sarrus(p1,p2,p3:point ): real;de arcaşi care pot fi plasaţi pe poziţii de tragere în câmpul begin sarrus:= p1.x*p2.y+p2.x*p3.y+p1.y*p3.xde luptă. -p3.x*p2.y-p3.y*p1.x-p1.y*p2.x; end; 62 15
  16. 16. Expresia Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) va avea 6.7. Evadarevaloare: pozitivă, dacă dreapta l şi segmentul s nu se in-tersectează (ambele extremităţi ale segmentului sunt Un grup de pinguini a decis să evadeze din grădinasituate de aceeaşi parte a dreptei, valorile determinantu- zoologică. În acest scop ei au săpat un tunel liniar. Dinlui sunt de acelaşi semn); nulă, dacă cel puţin una dintre nefericire, zidul grădinii zoologice formează un poligonextremităţi aparţine dreptei (pentru extremitatea segmen- simplu cu N (3≤N≤10000) laturi, astfel încât, ieşind dintului care aparţine dreptei, determinantul este egal cu 0); tunel, pinguinii nu pot afirma cu certitudine dacă se aflănegativă, dacă dreapta l şi segmentul s se intersectează în interiorul grădinii zoologice sau în afara ei.(extremităţile segmentului sunt situate de părţi diferiteale vectorului, valorile determinantului au semne dife- Să se scrie un program care, după coordonatele punc-rite). telor extreme ale tunelului şi coordonatele vârfurilor po- Prin urmare, dacă pentru dreapta l determinată de ligonului ce stabilesc perimetrul grădinii zoologice, va de-punctele p1 şi p2 şi segmentul s cu extremităţile s1 şi s2 termina dacă evadarea s-a soldat cu succes sau nu.expresia Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) are valoarenegativă, atunci dreapta l şi segmentul s se intersectează, Date de intrareiar coordonatele punctului de intersecţie pot fi calculate Prima linie a fişierului de intrare evadare.in conţineconform formulelor (2.4). patru numere întregi, separate prin spaţiu, – coordonatele Dacă valoarea expresiei este nulă, se verifică nemijlocit punctelor extreme ale tunelului. Următoarele linii conţincare dintre extremităţile segmentului aparţine dreptei. În descrierea consecutivă a vârfurilor zidului: fiecare linie vacazul în care ambele extremităţi ale segmentului aparţin conţine câte o pereche de numere, separate prin spaţiu, –dreptei, întreg segmentul este conţinut de aceasta. coordonatele unui vârf.2.3. Intersecţia segmentelor Date de ieşire Fişierul de ieşire evadare.out va conţine un singur cu- Fie segmente s şi p cu extremităţile s1 , s2 , respectiv vânt: DA – în cazul în care punctul final al tunelului este p1 , p2 . Pentru simplitate se va considera că segmentele în afara grădinii zoologice; NU – în caz contrar.nu aparţin aceleiaşi drepte şi nu sunt paralele (cazuriledate pot fi verificate cu ajutorul precondiţiilor pentru for- Restricţiimulele (2.4)). Coordonatele vârfurilor poligonului şi ale punctelor Segmentele se vor intersecta numai dacă extreme ale tunelului sunt numere întregi din intervalul Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) ≤ 0 şi [-1000, 1000]. Sarrus(s2,s1,p1)*Sarrus(s2,s1,p2) ≤ 0. 16 61
  17. 17. then begin st:=k; dr:=k+1; end else begin if (alfa < a[1].u) then begin st:=k+1; dr:=n+1; end 3. Înfăşurătoarea convexă else begin st:=1; dr:=k; end; repeat mj:=(st + dr) div 2; Problema determinării înfăşu- if a[mj].u >alfa then dr:=mj else st:=mj rătoarei convexe este una dintre until dr=st+1; problemele centrale ale geometriei end; computaţionale. Ea apare atât în5. Se determină poziţia centrului de masă şi a punctu- cadrul unor aplicaţii economice, fi- lui curent al mulţimii M faţă de latura determinată. nanciare, ecologice, arhitecturale, Dacă sunt de aceeaşi parte, punctul curent este cât şi în probleme geometrice ana- în interior. Pentru determinarea poziţiei se litice. Fig. 3.1. Înfăşurătoarea Noţiunea de înfăşurătoare con- convexă a unei mulţimi de x1 y1 1 puncte foloseşte semnul determinantului vexă în plan este intuitiv simplă: x2 y2 1 , pentru o mulţime S de puncte ale planului, înfăşurătoarea x3 y3 1 convexă Q ( S ) este mulţimea de vârfuri ale poligonului1 unde (x1, y1), (x2, y2) sunt coordonatele vârfurilor care convex cu cea mai mică arie, care conţine toate punctele determină latura, iar (x3, y3) – coordonatele punctului mulţimii S. Înfăşurătoarea convexă poate fi modelată cu cercetat (respectiv coordonatele centrului de masă). ajutorul inei benzi elastice, întinse în jurul mulţimii S. La eliberare, banda elastică va repeta conturul înfăşurătoareiq:=semn(a[st].x,a[st].y,a[dr].x,a[dr].y,b[i].x,b[i].y); convexe (fig. 3.1).p:=semn(a[st].x,a[st].y,a[dr].x,a[dr].y,xcm,ycm);if p*q>0 then inc(s); 3.1. Algoritmul elementar Fie mulţimea de puncte din plan S = { p1 , ... , pN } . Fie- care element pi al mulţimii este descris prin coordonatele sale carteziene ( xi , yi ) . O metodă intuitivă de determina- re a înfăşurătoarei convexe presupune eliminarea din mulţimea iniţială a tuturor punctelor ei interioare. 1 Poligon – figură geometrică plană, închisă, formată dintr-un număr finit de segmente, numite laturi. Aici şi în continuare prin poligon se va înţelege frontiera acestuia în reuniune cu interiorul său. Poligonul P este convex, dacă ∀x1 , x2 ∈ P, [x1 , x2 ]∈ P . Poligonul P este simplu, dacă laturile lui se intersectează doar în extremităţile lor. 60 17
  18. 18. Algoritmul elementar se bazează pe două afirmaţiisimple: function angle(cx,cy:real): real; begin a) înfăşurătoarea convexă a unei mulţimi de puncte sinus:=(cy -ycm)/ sqrt(sqr(cy-ycm)+sqr(cx-xcm)); cosinus:= (cx -xcm)/ sqrt(sqr(cy-ycm)+sqr(cx-xcm)); S este formată din punctele extreme ale mulţimii S; if cosinus=0 then b) un punct p ∈ S nu este un punct extrem dacă şi if sinus>0 then angle:= pi/2 else if sinus<0 then angle:=3*pi/2 numai dacă există cel puţin un triunghi, determinat else begin de punctele pi , p j , pk ∈ S , astfel încât p să-i aparţină if (sinus>0) and (cosinus>0) (fig. 3.2). then angle:=arctan(sinus/cosinus); if (sinus>0) and (cosinus<0) then angle:=pi-arctan(abs(sinus/cosinus)); În baza acestor afirmaţii, punc- if (sinus<=0)and (cosinus<0)tele interioare ale mulţimii se ex- then angle:=pi+arctan(abs(sinus/cosinus)); if (sinus<=0) and (cosinus>0)clud prin cercetarea apartenenţei then angle:=2*pi-arctan(abs(sinus/cosinus));fiecărui punct la fiecare triunghi end;generat de punctele mulţimii. Atât end;pseudocodul, cât şi implementareaalgoritmului sunt extrem de sim- 3. Pentru un punct dat alple: Fig. 3.2. Determinarea unui mulţimii M se calculează un- punct interior ghiul format de semidreaptaPseudocod determinată de acesta şi cen- trul de masă al poligonului cuPas 1 C←S axa Ox. Se foloseşte aceeaşiPas 2 Pentru toate punctele pi ∈ S funcţie de la etapa 2. Pentru toate punctele p j ∈ S , p j ≠ pi alfa:=angle(b[i].x,b[i].y) Pentru toate punctele pk ∈ S , pk ≠ pi , pk ≠ p j 4. Se determină latura poligonului intersectată de semi- Pentru toate punctele dreapta determinată la pasul 3. Pentru optimizarea p ∈ S , p ≠ pi , p ≠ p j , p ≠ pk acestui pas se foloseşte căutarea binară. if p ∈ Δpi p j pk then C ← C /{ p} k:=1; {determinarea vârfului cu unghi maxim} while (a[k].u<=a[k+1].u) and (k<n) do k:=k+1; {divizarea binara} if (alfa < a[k+1].u) or (alfa>a[k].u) 18 59
  19. 19. Exemplu Apartenenţa punctului la un triunghi atac.in atac.out Explicaţie 4 2 Condiţia p ∈ Δpi p j pk poate fi verificată prin determi- 2 4 narea poziţiei punctului p faţă de fiecare din vectorii pi p j , 8 4 6 8 p j pk , pk pi . Dacă semnul valorilor returnate la apelurile 4 6 funcţiei sarrus(pi,pj,p), sarrus(pj,pk,p), sarrus(pk,pi,p) 4 este acelaşi, atunci p ∈ Δpi p j pk . Prin urmare, verificarea 3 5 4 7 apartenenţei punctului la un triunghi poate fi realizată 5 5 într-un număr de operaţii mărginit de o constantă. 6 7 Instrucţiunile ciclice din pasul 2 al algoritmului gene- rează un număr de operaţii proporţional cu N 4 , ceea ce de- 4Rezolvare termină şi complexitatea finală a algoritmului – O ( N ). Formularea abstractă a problemei este următoarea: Fie în plan un poligon convex P cu n vârfuri. În acelaşi Implementareplan este dată o mulţime M din m puncte. Se cere să se Structura de date utilizată pentru determinarea înfăşu-determine câte puncte din M aparţin interiorului P. rătoarei convexe este un tablou de elemente, fiecare din- Rezolvarea se divide în câteva etape. tre ele fiind un articol cu trei componente: coordonatele punctului şi marcajul (0 – punct extrem, 1 – punct interi-1. Se determină un punct interior or), care specifică apartenenţa la înfăşurătoarea convexă: al poligonului de coordonate type point=record x,y,int: integer; (xcm , ycm) (de exemplu, centrul de masă). end; Fiind date coordonatele (xi , yi), Verificarea dacă punctul aparţine la un triunghi estei = 1, n , ale vârfurilor poligonului realizată de funcţia apart:P, coordonatele centrului de masă function apart(l,i,j,k:integer) : boolean;pot fi calculate după formula: var k1,k2,k3: real; n n begin apart:=true; k1:=sarrus(a[i],a[j],a[l]); ∑x i ∑y i i =1 i =1 k2:=sarrus(a[j],a[k],a[l]); xcm = , ycm = . k3:=sarrus(a[k],a[i],a[l]); n n if (k1*k2 <0 ) or (k1*k3<0) or (k2*k3<0) 2. Fiind dat un punct interior (xcm , ycm) al poligonului, then apart:=false;se calculează unghiurile pe care le formează cu axa Ox end;semidreptele duse din acesta prin vârfurile (cx , cy). 58 19
  20. 20. Aplicarea marcajelor este realizată în fragmentul: 6.6. Atac for i:=1 to n-2 do Agenţia Spaţială a planetei Bitterra (ASB) a recepţionat un for j:=i+1 to n-1 do for k:=j+1 to n do roi meteoritic, care se apropie de planetă. Fiecare stat de pe for l:=1 to n do Bitterra a fost anunţat despre pericol şi a primit lista punctelor if (l<>i) and (l<>j) and (l<>k) then de cădere a meteoriţilor, calculate de ASB. Serviciile pentru if apart(l,i,j,k) then a[l].int:=1; situaţii excepţionale ale fiecărui stat urmează să determine Afişarea coordonatelor punctelor care formează înfăşu- câţi meteoriţi vor cădea pe teritoriul ţării. Frontiera oricăruirătoarea se realizează prin verificarea marcajelor: stat de pe Bitterra este un poligon convex; meteoriţii sunt punc- for i:=1 to n do if a[i].int=0 tiformi. Punctele de pe frontieră nu se consideră aparţinând then writeln(a[i].x, ’ ’,a[i].y); statului. Frontiera poate conţine mai multe vârfuri consecutive Algoritmul descris, deşi este unul polinomial, nu este coliniare.cel mai eficient pentru determinarea înfăşurătoarei con-vexe a unei mulţimi de puncte. Să se scrie un program care va determina numărul de meteoriţi ce cad pe teritoriul unui stat dat.3.2. Algoritmul Graham Date de intrare Un algoritm eficient pentru determinarea înfăşurătoarei Prima linie a fişierului de intrare atac.in conţine numărulconvexe a fost propus de R. L. Graham în 1972. Algorit- n – numărul de vârfuri ale poligonului care descrie frontieramul se bazează pe determinarea unui punct interior al unui stat. Următoarele n linii conţin descrierea consecutivă amulţimii S, deplasarea în el a originii sistemului de coordo- vârfurilor frontierei: fiecare linie va conţine câte o pereche denate şi sortarea celorlalte numere separate prin spaţiu – coordonatele unui vârf. Urmeazăpuncte pi ale mulţimii o linie care conţine un număr întreg m – numărul de meteoriţi,după măsura unghiu- apoi m linii, care conţin câte două numere, separate prin spaţiu,lui format de vectorul – coordonatele punctelor de cădere a meteoriţilor.Opi cu axa Ox. După Date de ieşiresortare, punctele din S Fişierul de ieşire atac.out va conţine un singur număr în-sunt plasate într-o listă treg – cel al meteoriţilor care cad pe teritoriul statului dat.bidirecţională, circulară.La următoarea etapă se Restricţii 1. Coordonatele vârfurilor poligonului şi ale punctelor deparcurge lista formată, cădere a meteoriţilor sunt numere întregi din intervalulpornind de la punctul de puncte [-1000000, 1000000].de abscisă minimă (fig. Fig. 3.3. Parcurgerea listei(punctele p con- form algoritmului Graham 1 , p2, 2. 3 ≤ n ≤ 20000.3.3). Acesta este un punct p3 marchează tripletul curent) 3. 2 ≤ m ≤ 20000. 20 57
  21. 21. 6.5. Turnuri care, în mod cert, aparţine înfăşurătoarei convexe. La Bitlanda este o ţară care se extinde permanent, lini- fiecare „moment” al parcurgerii se cercetează un tripletar. Frontiera ţării reprezintă o linie frântă închisă, fără de elemente2 consecutive ale listei p1 , p2 , p3 . Cercetareaautointersecţii. Pentru a apăra frontierele sale, după fie- este realizată prin verificarea poziţiei punctului p2 faţăcare extindere, în noile puncte extreme ale frontierei se de vectorul p1 p3 .construiesc turnuri de veghe. Există N turnuri de veghe, Poziţionarea în semiplanul stâng stabileşte p2 ca fiinddate prin coordonatele lor (xi , yi) – numere întregi. Regele un punct interior al mulţimii. În acest caz, p2 este exclusBitlandei, Bytezar, a decis sa trimită la vatră garnizoanele din listă, iar tripletul care urmează să fie cercetat devineturnurilor care nu se mai află la hotarele ţării. p0 , p1 , p3 ( p0 – elementul precedent pentru p1 ). Poziţionarea în semiplanul drept stabileşte p2 ca fiind Să se scrie un program care va determina câte turnuri un punct posibil al înfăşurătoarei convexe. În acest caz,vor fi lipsite de garnizoane. p2 este păstrat în listă, iar tripletul care urmează să fie cercetat devine p2 , p3 , p4 ( p4 – elementul următor pentruDate de intrare p3 ). Parcurgerea ia sfârşit când se revine în punctul de Prima linie a fişierului de intrare conţine un număr unde a început.întreg: N (1 ≤ N ≤ 10000) – numărul de turnuri de vegheîn Bitlanda. Pseudocod Urmează N linii ce conţin câte două numere întregi xi , yi Pas 1 Se determină un punct interior z , z ∈ S.(–1000 ≤ xi , yi ≤ 1000), separate prin spaţiu, – coordonateleturnurilor de veghe. Pas 2 Se transferă originea sistemului de coordonate în punctul z.Date de ieşire Pas 3 Se determină coordonatele polare (r , ϕ ) ale fiecă- Fişierul de ieşire va conţine un număr întreg – numărul rui punct p ∈ S , p ≠ z , apoi se sortează dupăde turnuri care pot fi lipsite de garnizoane. creşterea ϕ (pentru punctele cu unghiuri congru-Exemplu ente sortarea se efectuează după creşterea r). turn.in turn.out 10 5 Pas 4 Se formează o listă bidirecţională, circulară, ale 2 1 cărei elemente sunt punctele sortate (Q). 3 4 6 3 Pas 5 Se stabileşte p0 – punctul de abscisă minimă (în 6 6 8 5 sistemul cartezian de coordonate). p ← p0 . 10 3 11 7 Pas 6 Cât timp la p0 nu se ajunge prin mişcări „înainte”, 12 6 se repetă: 9 11 2 15 8 Fiecare element al listei descrie un punct al mulţimii S. 56 21
  22. 22. a) Se consideră tripletul p1 ← p, p2 ← p[urm], Exemplu date.in date.out p3 ← p2 [urm] . 10 6 16 3 b) Dacă p2 e poziţionat în semiplanul drept faţă 3 14 13 4 de vectorul pk pi , atunci se efectuează mişcarea 23 14 „înainte”: p ← p[urm] , altfel p2 se exclude 33 4 33 14 din lista Q şi se efectuează mişcarea „înapoi”: 23 24 p ← p[ prec] . 13 14 3 24Pas 7 Q – înfăşurătoarea convexă. -7 14 -7 4 Complexitatea algoritmului este O ( N log N ) şi edeterminată de complexitatea pasului 3 – sortarea punc- Rezolvaretelor după unghiul ϕ . Paşii 1, 2, 4, 5 au o complexitate Deoarece carcasa se sprijină pe care-liniară. Aceeaşi complexitate o are şi pasul 6 – la fiecare va puncte extreme ale poligonului, pro-„moment” fie este eliminat un punct, fie se realizează blema poate fi divizată în două subpro-un pas înainte. Numărul de operaţii pentru verificarea bleme relativ simple:poziţiei punctului p2 este mărginit de o constantă. 1) determinarea înfăşurătoarei convexe a vârfurilor poligonului;Modificarea Andrew 2) verificarea dacă un triunghi are un unghi obtuz. Modificarea Andrew a algoritmului Graham are Prima subproblemă este rezolvată cu ajutorul algorit-drept scop omiterea determinării punctului interior z, a mului descris anterior (§ 3.2).deplasării originii sistemu- După determinarea înfăşurătoareilui de coordonate şi a calcu- convexe, problema poate fi reformulatălului coordonatelor polare. în felul următor:La baza variantei Andrew Fie un poligon convex P şi un punctstă următorul principiu: par- interior c, unit prin linii drepte cu vârfurile poligonului. Întea superioară (după y) a câte dintre triunghiurile formate înălţimea construită dinînfăşurătoarei convexe este punctul c se proiectează într-un punct interior al laturiibombată (în sus) pentru ori- poligonului care aparţine triunghiului?care 3 puncte consecutive ale Evident, înălţimea construită din c se proiectează pe latură dacă niciunul dintre unghiurile alăturate laturii poli-sale, cea inferioară – bombată gonului nu este obtuz. Verificarea unghiurilor se realizeazăîn jos (fig. 3.4). Fig. 3.4. Construirea înfăşurătoarei convexe. Modificarea Andrew pentru elementar cu ajutorul teoremei cosinusurilor. Complexi- algoritmul Graham tatea etapei este liniară după numărul de vârfuri. 22 55
  23. 23. 6.4. Carcasa Pseudocodul algoritmului are următoarea formă: Pas 1 Se determină două puncte extreme pmin , pmax ∈ S Fie o carcasă având forma de abscisă minimă (respectiv maximă).unui poligon simplu. Pentrua fi poziţionată vertical pe o Pas 2 Se separă S în Ssup şi Sinf după poziţia punctelorsuprafaţă plană, carcasa trebuie din mulţimea iniţială faţă de vectorul pmin pmax .să aibă centrul de masă situat Ssup va fi formată din punctele extreme şi cele dinstrict între 2 puncte de contact stânga vectorului, Sinf – din punctele extreme şicu suprafaţa. Centrul de masă cele din dreapta vectorului.este întotdeauna un punct interior al carcasei şi nu coin- Pas 3 Se sortează Ssup, Sinf după creşterea abscisei.cide cu nici un vârf al ei. Să se scrie un program care va determina numărul Pas 4poziţiilor în care poate fi stabilizată vertical carcasa. a) Se verifică toate tripletele de puncte consecutive pi , pi +1 , pi + 2 ∈ Ssup , pornind de la pmin.Date de intrare Dacă pi +1 este poziţionat în stânga vectorului Prima linie a fişierului de intrare date.in conţine trei pi pi + 2 , atunci se execută mişcarea „înainte”, al-numere întregi, separate prin spaţiu: N – numărul de tfel – mişcarea „înapoi”. La atingerea pmax, punc-vârfuri ale carcasei – şi xc, yc – coordonatele centrului de tele rămase în Ssup formează partea superioară amasă. înfăşurătoarei convexe. Urmează N linii ce conţin câte două numere întregi xi, yi b) Se verifică toate tripletele de puncte consecutive(–1000 ≤ xi , yi ≤ 1000), separate prin spaţiu, – coordonatele pi , pi +1 , pi + 2 ∈ Sinf , pornind de la pmin .vârfurilor poligonului în ordinea parcurgerii lor. Dacă pi +1 este poziţionat în dreapta vectoruluiDate de ieşire pi pi + 2 , atunci se execută mişcarea „înainte”, alt- Fişierul de ieşire date.out va conţine un singur număr fel – mişcarea „înapoi”. La atingerea pmax, punc-întreg – numărul de poziţii în care poate fi stabilizată ver- tele rămase în Sinf formează partea inferioară atical carcasa. înfăşurătoarei convexe. Pas 5 Q ← Sinf ∪ Ssup .Restricţii 3 ≤ N ≤ 1000 În cele ce urmează este propusă o realizare a acestui –1000 ≤ xc , yc ≤ 1000 algoritm. Se presupune că punctele sunt date prin coordo- natele lor – numere întregi. Sortarea este realizată de pro- cedura qsort (descrierea şi implementarea poate fi găsită, 54 23
  24. 24. de exemplu, în [7, 303]). Poziţia reciprocă a punctelor este Exempludeterminată de funcţia sarrus, descrisă anterior. date.in date.out 2 1 9 14 4 2 4 1 8 Structurile de date: 1 12 3 9 drag – mulţimea S 4 14 6 11 sus, jos – mulţimile Ssup, Sinf 7 14 9 10 9 14 7 16 n – |S| 6 10 8 8 3 6 6 6procedure conv; 4 2 4 5var minx,maxx:longint; 11 10 12 14 j, imin, imax,i, nsus, njos: integer; 8 6 10 8 rem: boolean; 12 8 14 4 p1,p2,p3:nod;begin{1. determinarea extremelor dupa x} Rezolvare minx:=drag[1].x; maxx:=drag[1].x;imin:=1; imax:=1; program p03; for i:=2 to n do type point=record x,y: real; end; if drag[i].x< minx then segment=record e1,e2: point; end; begin minx:=drag[i].x; imin:=i; end var g: array[1..1000] of segment; else if drag[i].x>maxx then l: segment; begin maxx:=drag[i].x; imax:=i; end; n,i,k: integer; function sarrus(p1,p2,p3:point): real;{2. separarea in submultimi} begin sarrus:=p1.x*p2.y+p2.x*p3.y+p1.y*p3.x nsus:=1; njos:=1; -p3.x*p2.y-p3.y*p1.x-p1.y*p2.x; sus[1]:=drag[imin]; jos[1]:=drag[imin]; end; for i:=1 to n do if not (i in [imin, imax])then begin if sarrus(drag[imin],drag[imax],drag[i])<0 assign(input, ’date.in’); reset(input); n:=0; then readln(l.e1.x,l.e1.y,l.e2.x,l.e2.y); begin inc(njos); jos[njos]:=drag[i]; end while not eof do else begin begin inc(nsus); sus[nsus]:=drag[i]; end; inc(n); readln( g[n].e1.x, inc(nsus);sus[nsus]:=drag[imax]; g[n].e1.y,g[n].e2.x,g[n].e2.y); inc(njos);jos[njos]:=drag[imax]; end; k:=0;{3. sortarea subseturilor } for i:=1 to n doqsort(sus,2,nsus-1); ifqsort(jos,2,njos-1); sarrus(l.e1,l.e2,g[i].e1)*sarrus(l.e1,l.e2,g[i].e2) < 0{crearea infăşurătoarei convexe} then inc(k);{4. sus} assign(output, ’date.out’); rewrite(output); repeat writeln(k); close(input); close(output); rem:=false; i:=2; end. 24 53
  25. 25. 6.3. Piatra while i<nsus do begin p1:=sus[i-1]; p2:=sus[i]; p3:=sus[i+1]; ... şi unde nu porneşte stânca la vale, săltând tot mai sus de if sarrus(p1,p3,p2)>0 then i:=i+1 un stat de om; şi trece prin gardul şi prin tinda Irinucăi, pe else begin la capre, şi se duce drept în Bistriţa, de clocotea apa! rem:=true; for j:=i to nsus-1 do Ion Creangă. Amintiri din copilărie sus[j]:=sus[j+1]; dec(nsus); Piatra pornită de Ion Creangă se rostogolea în linie end; end;dreaptă, dărâmând totul în calea sa. Casa Irinucăi are until not rem;mulţi pereţi, unii nimerind în calea pietrei. Fiind date {si jos}coordonatele a două puncte prin care trece piatra şi repeatextremităţile segmentelor care descriu baza pereţilor ca- rem:=false; i:=2;sei, să se determine câţi pereţi vor fi dărâmaţi de piatra while i<njos do beginîn cădere. Peretele atins într-un punct extrem rămâne în- p1:=jos[i-1]; p2:=jos[i]; p3:=jos[i+1];treg. if sarrus(p1,p3,p2)<0 then i:=i+1 Să se scrie un program care determină numărul de else begin rem:=true;pereţi dărâmaţi de piatră. for j:=i to njos-1 do jos[j]:=jos[j+1]; Date de intrare dec(njos); end; Fişierul de intrare date.in conţine N (N < 1000) linii a end;câte patru numere întregi. Prima linie conţine descrierea until not rem;a două puncte prin care trece piatra, în forma x1, y1, x2, y2 {5. asamblarea}(|xi, yi|<500). Următoarele N-1 linii conţin descrierea for i:= nsus-1 downto 2 docoordonatelor extremităţilor bazelor pereţilor, în aceeaşi begin inc(njos);consecutivitate, cu aceleaşi restricţii de valori. jos[njos]:=sus[i]; end; Date de ieşire drag:=jos; n:=njos; Unica linie a fişierul de ieşire date.out va conţine un end;{conv}număr întreg – numărul de pereţi dărâmaţi de piatră. La finalul execuţiei procedurii punctele care formează înfăşurătoarea convexă vor fi stocate în structura de date jos. 52 25
  26. 26. Rezolvare4. Triangularizări program p02; const pi=3.141592; Din punct de vedere geo- type point=recordmetric, triangularizarea T(S) x,y : real; end;a mulţimii de puncte S este var P: point;o divizare a înfăşurătoarei alfa,xn,yn:real;convexe Q(S) în triunghiuri.Suplimentar, se vor respecta procedure move(var P:point; vx,vy:real); begincondiţiile: P.x:=P.x+vx; a) vârfri ale triunghiurilor P.y:=P.y+vy; pot fi numai puncte end; Fig. 4.1. Triangularizarea unei mul- din S; ţimi de puncte procedure rotate (var P:point; u,vx,vy:real); b) toate punctele mulţimii var old:point; S vor fi utilizate în calitate de vârfuri (fig. 4.1). begin old:=P; P.x:=vx+(old.x-vx)*cos(u*pi/180)-4.1. Un algoritm greedy (old.y-vy)*sin(u*pi/180); pentru mulţimi de puncte P.y:=vy +(old.x-vx)*sin(u*pi/180)+ (old.y-vy)*cos(u*pi/180); Fie mulţimea de puncte S şi N=|S|. Fiecare punct p ∈ S end;este descris prin coordonatele sale carteziene ( x, y ) . Tri- beginangularizarea T(S) poate fi cercetată ca un graf planar cu assign(input,’data.in’); reset(input);mulţimea de noduri S. Prin urmare, numărul de laturi assign(output,’data.out’); rewrite(output);M în S este proporţional cu N (conform formulei Euler, readln(P.x,P.y); while not eof do M ≤ 3 N − 6 ). begin O soluţie simplă în plan este generarea tuturor seg- readln(alfa,xn,yn);mentelor posibile cu extremităţi în S, sortarea lor după if alfa>90 then move(P,xn,yn) else rotate(P,alfa,xn,yn);lungime, apoi adăugarea consecutivă în triangularizare. end;În proces se verifică dacă latura curentă intersectează la- writeln(P.x:10:3,’ ’,P.y:10:3);turile adăugate anterior. Dacă intersecţiile lipsesc, latura close(input); close(output); end.este adăugată, în caz contrar, se trece la cercetarea laturiiurmătoare. 26 51

×