Geometrie 5

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

Sunteți pe pagina 1din 82

Ministerul Educaiei i Tineretului al Republicii Moldova Universitatea de Stat din Tiraspol

Sergiu CORLAT

Algoritmi i probleme de geometrie computaional

Chiinu, 2009

Cuprins
Introducere 5 7
7 9 10

1. Transformri de coordonate
1.1. Deplasri i rotaii 1.2. Coordonate polare 1.3. Implementri

2. Intersecii 2.1. 2.2. 2.3.

12
12

Intersecia dreptelor Intersecia dreptei cu un segment 14 Intersecia segmentelor

16

3. nfurtoarea convex 3.1. 3.2.


Algoritmul elementar Algoritmul Graham 20

17
17

4. Triangularizri 4.1. 4.2. 4.3.

26

Un algoritm greedy pentru mulimi de puncte 26 Triangularizarea poligoanelor convexe

28
Triangularizarea poligoanelor simple 29

5. Apropiere i apartenen 5.1.

31

Cea mai apropiat pereche de puncte 31


4

5.2. 5.3. 5.4.

Poligonul i diagrama Voronoi 35 Apartenena punctului la un domeniu 40 Nuclee 45

6. Probleme geometrice de concurs 6.1. 6.2. 6.3. 6.4. 6.5. 6.6. 6.7. 6.8. 6.9. 6.10.
Notaii Bibliografie
Robot Robot II Piatra Carcasa Turnuri Atac Evadare Arcai Cetate Druizi

48 48 50 52 54 56 57 61 62 68 69 75 76

Introducere
Geometria computaional prezint una din ramurile importante ale matematicii aplicate moderne. Pornind de la cercetarea unor elemente geometrice simple (punct, segment, dreapt), se ajunge la o modelare complex a figurilor geometrice n plan i a corpurilor n spaiul tridimensional. Algoritmii geometriei computaionale stau la baza tuturor aplicaiilor de proiectare i modelare grafic (aplicaii CAD, procesoare de grafic vectorial, aplicaii de modelare 3D). Fr ei ar fi imposibil proiectarea construciilor arhitecturale moder-ne, realizarea proiectelor GPS, apariia majoritii absolute a produselor cinematografice de succes din ultimii ani. Enumerarea domeniilor de aplicare poate fi continuat la nesfrit. Domeniul vast de aplicare i multitudinea fenomenelor i situaiilor reale, descrise n termenii geometriei computaionale, au impus apariia unor probleme geometrice n cadrul concur-surilor de programare de cele mai diferite nivele. Prezenta lucrare este conceput ca un curs de iniiere n algoritmii de geometrie computaional pentru studenii facul-tilor de profil, pentru profesorii de informatic, precum i pen-tru elevii claselor liceale, participani la concursurile naionale i internaionale de programare. Un alt scop este de a-i forma cititorului abiliti de analiz i proiectare a algoritmilor. n acest sens, algoritmii i soluiile problemelor sunt nsoite de descrieri ale structurilor de date, fragmente de cod, calcule ala complexitii. Cu toate c aparatul matematic necesar pentru rezolvarea problemelor de geometrie computaional este relativ simplu, implementarea acestora este nsoit de necesitatea cercetrii unui numr considerabil de cazuri
6

speciale. Acesta este un motiv, pentru care problemele de geometrie computaional se consider printre cele mai dificile, n special n condiii de concurs. Cercetarea i optimizarea soluiilor propuse pentru unele din problemele prezente n lucrare va permite cititorului s capete o experien necesar la compartimentul rezolvare de probleme, i nu n ultimul rnd la generarea testelor pentru verificarea soluiilor. La baza lucrrii se afl o serie de articole publicate pe parcursul ultimilor ani n revista de matematic i informatic Delta, materiale i probleme elaborate n cadrul colilor de var la informatic (ediiile anilor 2001, 2002), precum i probleme propuse la concursul de pregtire continu la informatic .campion (campion.edu.ro). in s aduc sincere mulumiri tuturor celor care au contri-buit la apariia acestei cri, n special colectivului Catedrei de Informatic i Tehnologii Informaionale a Universitii de Stat din Tiraspol.
Ianuarie 2009 Sergiu Corlat

1. Transformri de coordonate
1.1. Deplasri i rotaii
Rezolvarea oricrei probleme de geometrie computaional ncepe (dac e necesar) cu deplasarea coordonatelor elementelor cercetate (de cele mai dese ori ale punctelor) ntr-un domeniu potrivit al sistemului de coordonate (de obicei, n cadranul unu). n unele cazuri, deplasarea poate fi nsoit i de rotaia siste-mului de coordonate. Fie ntr-un sistem cartezian de coordonate un punct p de coordonate (x, y). Deplasarea de coordonate de-a lungul axei Ox cu o valoare dat a implic o modificare a coordonatelor punctului conform formulelor:

x = x + a, y = y.
n cazul deplasrii de-a lungul axei Oy cu valoarea b, transformarea de coordonate va fi dat de sistemul:

x = x, y = y + b.
Modificarea combinat a coordonatelor cu a dup axa Ox i b dup Oy va fi dat de sistemul:

x = x + a, y = y + b.
Urmtorul tip de transformare este rotaia cu un unghi a pun-ctului (punctelor) fa de originea sistemului de coordonate (fig. 1.1). n unele cazuri, operaia poate fi realizat invers: prin rotaia originii
8

Fig. 1.1. Rotaia punctului cu un unghi .

sistemului de coordonate fa de un punct (sau sistem de puncte) dat. n acest caz exist patru numere a,b,c,d, care permit de a trece univoc coordonatele ( x, y) n ( x, y) , utiliznd sistemul de ecuaii:

x = ax + by, (1.1) y = cx + dy. Pentru determinarea acestui cuadruplu de nume-re pot fi folosite punctele (1,0) i (0,1). Se observ c la rotaia cu un unghi punctul de co-ordonate (1,0) trece n pun-ctul (cos ,sin ) , iar (0, 1) n

Fig. 1.2. Determinarea cuadruplului a, b, c, d, folosind punctele (1,0) i (0,1)

( sin , cos ) (fig. 1.2). Dup nlocuirea acestor valori n calitate de coefi-cieni ai sistemului (1.1) se obine: x = a a = cos , y = c c = sin .

Analog:
x = b b = sin , y = d d = cos .

Astfel, sistemul de ecuaii pentru rotaia cu un unghi a unui punct arbitrar n jurul originii sistemului de coordonate ia forma: x = x cos y sin y = x sin + y cos
9

n cazul, n care rotaia cu unghiul a punctului de coordonate ( x, y ) este efectuat fa de punctul de coordonate ( x0 , y0 ) , diferit de originea sistemului de coordonate, mai nti se transfer originea sistemului de coordonate n centrul de rotaie (deplasarea de coordonate), apoi se efectueaz rotaia n jurul noii origini a sistemului de coordonate:

x x0 = ( x x0 ) cos ( y y0 )sin y y0 = ( x x0 ) sin + ( y y0 ) cos


sau

x = x0 + ( x x0 ) cos ( y y0 ) sin y = y0 + (x x0 ) sin + ( y y0 ) cos

1.2. Coordonate polare


Problemele n care apare procedura de parcurgere a unei mulimi de puncte dup unghiu-rile formate de acestea cu axa Ox se rezolv mai simplu n cazul trecerii la coordonate po-lare. n acest sistem de coordo-nate fiecare punct p Fig. 1.3. Coordonatele polare ale punctului este deter-minat de perechea de coordonate carteziene (x, y) (r, ), unde r reprezint distana de la punct pn la originea sistemului de coordonate, iar - unghiul format de vectorul Op cu axa Ox. Trecerea de la coordonatele carteziene (x, y) la cele polare (fig. 1.3) este determinat de formulele [1, p. 77]:
10

uu u r

r = x2 + y 2 ,

x arctan y x + arctan y = 2 3 2

y>0 y <0 x = 0, y > 0 x = 0, y < 0

1.3. Implementri
n problemele de geometrie computaional pot aprea diferite modele de transformare a coordonatelor: deplasri dup o ax, deplasri combinate (dup ambele axe), rotaii fa de un punct, deplasri nsoite de rotaii. Toate aceste transformri presupun recalcularea coordonatelor unui punct sau ale unui sistem de puncte. Pentru rezolvarea eficient a problemelor de geometrie este foarte important de a alege corect structurile de date. Pentru implementarea transformrilor de coordonate este necesar descrierea unei singure structuri punctul:
type point=record x,y : real; end;

Orice obiect geometric, determinat de un sistem de puncte poate fi descris prin intermediul unui tablou unidimensional sau list alocat dinamic, cu elemente de tip point. Procedura de deplasare a coordonatelor cu valoarea vx dup axa Ox i vy dup Oy poate fi realizat n felul urmtor:
procedure move(var P:point; vx,vy:real); begin P.x:=P.x+vx; 11

P.y:=P.y+vy; end;

La fel de simpl este i o posibil implementare a rotaiei cu un unghi u fa de un punct de coordonate vx i vy:
procedure rotate (var P:point; u,vx,vy:real); var old:point; begin old:=P; P.x:=vx+(old.x-vx)*cos(u*pi/180) -(old.y-vy)*sin(u*pi/180); P.y:=vy +(old.x-vx)*sin(u*pi/180) +(old.y-vy)*cos(u*pi/180); end;

12

2. Intersecii
n majoritatea problemelor de geometrie compu-taional apare n calitate de subproblem determinarea coordonatelor punctului de intersecie a dou drepte, a dou segmente sau a unui segment i unei Fig. 2.1 Definirea dreptei (segmentului) prin drepte. dou puncte Metoda folosit pentru rezolvarea acestor subprob-leme este aceeai, cu dife-rene puin semnificative pentru fiecare caz. Att pentru definirea dreptei, ct i pentru definirea segmentului se vor folosi dou puncte distincte: arbitrare (ale dreptei sau extreme pentru segment, fig. 2.1). Prin urmare, att descrierea dreptei, ct i descrierea segmentului pot fi realizate de aceeai structur de date, care va conine coordonatele a dou puncte i, suplimentar, coeficienii A,B,C ai ecuaiei generale a dreptei. Aceti coeficieni vor fi necesari pentru calculul coordonatelor punctului de intersecie. Una din posibilele metode de definire a acestei structuri este:
type line=record x1,y1,x2,y2 : real; A, B, C : real; end;

2.1. Intersecia dreptelor


Ecuaia general a dreptei Fie dreapta l determinat de punctele p1 ( x1 , y1 ) i p2
( x2 , y2 ) .
13

Ecuaia dreptei ce trece prin dou puncte date este:


x x1 y y1 = (2.1) x2 x1 y 2 y1

Din aceast ecuaie pot fi calculai coeficienii ecuaiei generale a dreptei: Ax + By + C = 0 . Efectund transformri elementare, din (2.1) se obine:
x( y 2 y1 ) + y ( x1 x2 )+ ( x2 y1 x1 y2 )= 0.

(2.2)

Din (2.2) rezult formulele de calcul pentru coeficienii ecuaiei generale:


A = y2 y1 , B = x1 x2 , C = x2 y1 x1 y2 .

(2.3)

Determinarea punctului de intersecie a dou drepte Fie dreptele p i l, determinate respectiv de punctele p1
( x1 , y1 ) , p2 ( x2 , y2 ) i p3 ( x3 , y3 ) , p4 ( x4 , y4 )

Determinarea punctului q de intersecie a acestor drepte se reduce la rezolvarea sistemului de ecuaii:


A1 x + B1 y + C1 = 0 A2 x + B2 y + C2 = 0,

unde A1 x + B1 y + C1 = 0 este ecuaia general a dreptei p i


A2 x + B2 y + C2 = 0 este ecuaia general a dreptei l. Coeficienii acestor ecuaii pot fi calculai conform formulelor (2.3). Pn la rezolvarea nemijlocit a sistemului urmeaz s se verifice dac dreptele p i l sunt paralele sau coincid. Pentru aceasta se verific condiiile:

A1B2 = A2 B1 & A1C 2 A2C1 dreptele p i l sunt paralele;

A1 B2 = A2 B1 & A C2 = A2 C1 dreptele p i l coincid. 1


14

Dac niciuna din condiiile precedente nu se satisface, atunci exist un punct unic de intersecie a dreptelor p i l, ale crui coordonate pot fi calculate dup formulele: a) Dac A1 0 . A C C1 A2 ysol = 1 2 , B2 A1 B1 A2 (2.4 a) B1 y sol C1 xsol = ; A1 b) Dac A1 = 0
ysol = xsol = C1 , B1 B2 ysol + C2 . A2

(2.4 b)

Cu ajutorul setului de formule (2.4) pot fi calculate coordonatele punctului de intersecie q ( xsol , ysol ) a dreptelor p i l.

2.2. Intersecia dreptei cu un segment


Formulele deduse n paragraful precedent permit s se calculeze coordonatele punctului de intersecie a dou drepte. Cazul interseciei a dou segmente sau a unei drepte i a unui segment pot fi reduse la cel al interseciei dreptelor, dar cu verificarea unor condiii suplimentare Fie dreapta l care trece prin punctele p1 i p2 i segmentul s cu punctele extreme s1 i s2 (fig 2.2). Se observ, c n cazul interseciei dreptei l i a segmentului s, extremitile segmentului sunt poziionate u uu uu r de pri diferite fa de vectorul p2 p1 . Dac obiectele cercetate nu se intersecteaz, atunci ambele extremiti ale u uu uu r segmentului se afl de aceeai parte a vectorului p2 p1 .

15

Fig. 2.2. Poziia segmentului fa de dreapta.

Poziia punctului fa de un vector u uu uu r Fie vectorul p2 p1 coordonate ( x2 , y2 ) , ( x1 , y1 ) , i punctul s de coordonate ( x3 , y3 ) .


u uu uu r Pentru a poziiona punctul s fa de vectorul p2 p1 , poate fi folosit urmtorul determinant [12, p. 60]:
x2 = x1 x3 y2 1 y1 1 y3 1

Determinantul este pozitiv dac punctul s este situat n u uu uu r semiplanul drept fa de vectorul p2 p1 ; este nul, dac punctul s aparine dreptei determinate de acest vector, i negativ, dac s este plasat n semiplanul stng. O realizare posibil a funciei de calcul al determinantului este urmtoarea:
function sarrus(p1,p2,p3:point1): real; begin sarrus:= p1.x*p2.y+p2.x*p3.y+p1.y*p3.x -p3.x*p2.y-p3.y*p1.x-p1.y*p2.x; end;

Intersecia Expresia Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) va avea valoare pozitiv, dac dreapta l i segmentul s nu se


1

type point=record

x,y : real; end;

16

intersecteaz (ambele extremiti ale segmentului sunt situate de aceeai parte a dreptei, valorile determinantului sunt de acelai semn), nul, dac cel puin una dintre extremiti aparine dreptei (pentru extremitatea segmentului, care aparine dreptei determinantul este egal cu 0), negativ, dac dreapta l i segmentul s se intersecteaz (extremitile segmentului sunt situate de pri diferite ale vectorului, valorile determinantului au semne diferite). Prin urmare, dac pentru dreapta l determinat de punctele p1 i p2 i segmentul s cu extremitile s1 i s2 expresia Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) are valoare negativ, atunci dreapta l i segmentul s se intersecteaz, iar coordonatele punctului de intersecie pot fi calculate conform formulelor 2.4. Dac valoarea expresiei este nul, se verific nemijlocit care dintre extremitile segmentului aparine dreptei. n cazul n care ambele extremiti ale segmentului aparin dreptei, tot segmentul aparine acesteia.

2.3. Intersecia segmentelor


Fie segmente s i p cu extremitile s1 s2 , respectiv p1 ,
p2 . Pentru simplitate se va considera c segmentele nu aparin aceleiai drepte i nu sunt paralele (cazurile date pot fi verificate cu ajutorul precondiiilor pentru formulele 2.4). Segmentele se vor intersecta numai dac
Sarrus(p2,p1,s1)*Sarrus(p2,p1,s2) 0 i Sarrus(s2,s1,p1)*Sarrus(s2,s1,p2) 0

Coordonatele punctului de intersecie i n acest caz pot fi calculate folosind formulele 2.4.

17

3. nfurtoarea convex
Problema determinrii nf-urtoarei convexe este una dintre problemele centrale ale geometriei computaionale. Ea apare att n cadrul unor aplicaii economice, financiare, ecologice, arhitecturale, ct i n probleme geometrice analitice. Noiunea de nfurtoare Fig. 3.1. nfurtoarea convex a convex n plan este intuitiv unei mulimi de puncte simpl: pentru o mulime S de puncte ale planului, nfurtoarea convex Q( S ) este mulimea de vrfuri ale poligonului convex2 cu cea mai mic arie, care conine toate punctele mulimii S. nfurtoarea convex poate fi modelat cu ajutorul inei benzi elastice, ntinse n jurul mulimii S. La eliberare, banda elastic va repeta conturul nfurtoarei convexe (fig. 3.1).

3.1. Algoritmul elementar


Fie mulimea de puncte din plan S = { p1 , ... , p N } . Fiecare element pi al mulimii este descris prin coordonatele sale carteziene ( xi , yi ) . O metod intuitiv de determinare a nfurtoarii convexe presupune eliminarea din mulimea iniial a tuturor punctelor ei interioare. Algoritmul se bazeaz pe dou afirmaii simple:

a) nfurtoarea convex a unei mulimi de puncte S


este format din punctele extreme ale mulimii
2

S;

Poligonul P - convex, dac x1,x2 P, [x1,x2] P. 18

b) un punct p S nu este
un punct extrem dac i nu-mai dac, exist cel puin un triunghi, determinat de punctele pi , p j , pk S , ast-fel nct
p s se afle n interiorul

lui (fig 3.2). n baza acestor afirmaii, interior pun-ctele interioare ale mulimii se exclud prin cercetarea apartenenei fiecrui punct fiecrui triunghi generat de punctele mulimii S . Att pseudocodul, ct i implementarea algoritmului sunt extrem de simple: Pseudocod Pas 1 C S Pas 2 Pentru toate punctele pi S Pentru toate punctele p j S , p j pi Pentru toate punctele pk S, pk pi , pk p j Pentru toate punctele p S , p pi , p p j , p p k
if
Fig. 3.2. Determinarea unui punct

p pi p j pk 3

then C C /{ p}

Apartenena punctului la un triunghi


u uu u u u u u u ur r p fa de fiecare din vectorii pi p j , p j pk , poziiei punctului u uu uu r pk pi

Condiia

p pi p j pk

poate fi verificat prin determinarea

. Dac semnul valorilor returnate la apelurile funciei

sarrus(pi,pj,p), sarrus(pj,pk,p), sarrus(pk,pi,p), este aceAici i n continuare notaia p pi p j pk va specifica triunghiul n reuniune cu domeniul su interior 19
3

i j k lai, atunci . Prin urmare, verificarea dac un punct aparine interiorului unui triunghi poate fi realizat ntr-un numr de operaii mrginit de o constant. Instruciunile ciclice din pasul 2 al algoritmului genereaz un numr de operaii, proporional cu N 4 , ceea

p p p p

4 ce determin i complexitatea final a algoritmului O ( N ) .

Implementare Structura de date utilizat pentru determinarea nfurtoarei convexe este un tablou de elemente, fiecare dintre ele fiind un articol cu trei componente: coordonatele punctului i marcajul (0 punct extrem, 1 punct interior), care specific apartenena la nfurtoarea convex:
type point=record x,y,int: integer; end;

Verificarea dac punctul aparine la un triunghi este reali-zat n cadrul funciei apart:
function apart(l,i,j,k:integer) : boolean; var k1,k2,k3: real; begin apart:=true; k1:=sarrus(a[i],a[j],a[l]); k2:=sarrus(a[j],a[k],a[l]); k3:=sarrus(a[k],a[i],a[l]); if (k1*k2 <0 ) or (k1*k3<0) or (k2*k3<0) then apart:=false; end;

Aplicarea marcajelor este realizat n urmtorul fragment:


for i:=1 to n-2 do for j:=i+1 to n-1 do for k:=j+1 to n do for l:=1 to n do if (l<>i) and (l<>j) and (l<>k) then if apart(l,i,j,k) then a[l].int:=1; 20

Afiarea coordonatelor punctelor, care formeaz nfur-toarea se realizeaz prin verificarea marcajelor:
for i:=1 to n do if a[i].int=0 then writeln(a[i].x, ' ',a[i].y);

Algoritmul descris, dei este unul polinomial, nu este cel mai eficient pentru determinarea nfurtoarei convexe a unei mul-imi de puncte.

3.2 Algoritmul Graham.


Un algoritm eficient cu complexitatea O ( N log N ) a fost propus de R. L. Graham n 1972. Algoritmul se bazeaz pe determinarea unui punct inte-rior al mulimii S , deplasarea n el a originii sistemului de coordonate, i sortarea celor-lalte puncte ale mulimii dup unghiul format de ele cu axa Ox. Parcurgerea listei de Dup sortare, punctele din Fig. 3.3. algoritmului Graham. puncte p , conform Punctele 1 S sunt plasate ntr-o list p2, p3 marcheaz tripletul curent. bidirecional, circular. La urmtoarea etap se parcurge lista format, pornind de la punctul cu abscisa minim (fig. 3.3). Acesta este un punct care, n mod cert, aparine nfurtoarei convexe. La fiecare moment al parcurgerii se cerceteaz un triplet de elemente4 consecutive ale listei p1 , p2 , p3 . Cercetarea este

Fiecare element al listei descrie un punct al mulimii S.


21

realizat prin verificarea poziiei punctului


u ur uu vectorul p1 p3 .

p2

fa de

Poziionarea n semiplanul stng stabilete p2 ca fiind un punct interior al mulimii. n acest caz, p2 este exclus din list, iar tripletul care urmeaz s fie cercetat devine p0 , p1 , p3 . Poziionarea n semiplanul drept stabilete p2 ca fiind un punct posibil al nfurtoarei convexe. n acest caz, p2 este pstrat n list, iar tripletul care urmeaz s fie cercetat devine p2 , p3 , p4 6. Parcurgerea ia sfrit cnd se revine n punctul de unde a nceput. Pseudocod Pas 1 Se determin un punct interior z , z S . Pas 2 Se transfer originea sistemului de coordonate n punctul z. Pas 3 Se determin coordonatele polare (r, ) ale fiecrui punct p S , p z , apoi se sorteaz dup creterea (pentru punctele cu unghiuri egale sortarea se efectueaz dup creterea r ). Pas 4 Se formeaz o list bidirecional, circular, ale crei elemente sunt punctele sortate (Q). Pas 5 Se stabilete p0 punctul de abscis minim (n sistemul cartezian de coordonate). p p0 Pas 6 Ct timp la p0 nu se ajunge prin micri nainte, se repet: Se consider tripletul p1 p, p2 p[urm], p3 p2 [urm ]
Dac p2 e poziionat n semiplanul drept fa de vectorul
5 6

a) b)

p0 elementul precedent pentru p1 p4 elementul urmtor pentru p3


22

c)

p p [urm ] , , atunci se efectueaz micarea nainte: altfel p2 se exclude din lista Q i se efectueaz micarea napoi: p p [prec ] .

Pas 7 Q nfurtoarea convex. Complexitatea algoritmului este O( N log N ) i e determinat de complexitatea pasului 3 sortarea punctelor dup unghiul . Paii 1, 2, 4, 5 au o complexitate liniar. Aceeai complexitate o are i pasul 6 la fiecare moment fie este eliminat un punct, fie se realizeaz un pas nainte. Numrul de operaii n cadrul verificrii poziiei p2 este mrginit de o constant. Modificarea Andrew Modificarea algoritmului are drept scop omiterea deter-minrii punctului intern z, deplasrii originii sistemului de coordonate, i a calculului coordonatelor polare. La baza variantei Andrew st urm-torul principiu: partea superi-oar (dup y ) a nfurtoarei convexe este bombat (n sus) pentru oricare 3 puncte Fig. 3.4. Construirea nfurtoarei conse-cutive ale sale, cea convexe. Modificarea Andrew inferioar bobmbat n jos (fig 3.4). Pseudocodul algoritmului are urmtoarea form: Pas 1 Se determin dou puncte pmin , pmax S de abscis minim (respectiv maxim).
23

Pas 2 Se separ S n Ssup i Sinf dup poziia punctelor fa de pmin pmax . Ssup va fi format din punctele extreme i cele din stnga vectorului, Sinf din punctele extreme i cele din dreapta vectorului. Pas 3 Se sorteaz Ssup , Sinf dup creterea abscisei. Pas 4 a. Se verific toate tripletele consecutive pi , pi+1 , p i+ 2 S sup , pornind de la pmin . u u ur uuu Dac pi +1 este poziionat n stnga pi pi + 2 atunci se execut formeaz convexe. micarea partea nainte, superioar
altfel

u u u uu uuuu r

micarea

napoi. La atingerea pmax , punctele rmase n Ssup a nfurtoarei

b. se verific toate tripletele consecutive pi , pi+1 , p i+ 2 S inf , pornind de la pmin . u u ur uuu Dac pi +1 este poziionat n dreapta pi pi + 2 , atunci se execut nainte, altfel micarea napoi. La atingerea pmax , punctele rmase n Sinf formeaz partea inferioar a nfurtoarei convexe. Pas 5 Q S inf S sup Mai jos este propus o realizare a acestui algoritm. Se presupune c punctele sunt date prin coordonatele lor numere ntregi. Sortarea este realizat de procedura qsort, care nu este descris aici, fiind considerat elementar. Poziia reciproc a punctelor este determinat de funcia sarrus, descris anterior. Structurile de date:
drag sus, jos n mulimea S - mulimile Ssup , Sinf - |S | 24

micarea

procedure conv; var minx,maxx:longint; j, imin, imax,i, nsus, njos: integer; rem: boolean; p1,p2,p3:nod; begin {1. determinarea extremelor dupa x} minx:=drag[1].x; maxx:=drag[1].x;imin:=1; imax:=1; for i:=2 to n do if drag[i].x< minx then begin minx:=drag[i].x; imin:=i; end else if drag[i].x>maxx then begin maxx:=drag[i].x; imax:=i; end; {2. separarea in submultimi} nsus:=1; njos:=1; sus[1]:=drag[imin]; jos[1]:=drag[imin]; for i:=1 to n do if not (i in [imin, imax])then if sarrus(drag[imin],drag[imax],drag[i])<0 then begin inc(njos); jos[njos]:=drag[i]; end else begin inc(nsus); sus[nsus]:=drag[i]; end; inc(nsus);sus[nsus]:=drag[imax]; inc(njos);jos[njos]:=drag[imax]; {3. sortarea subseturilor } qsort(sus,2,nsus-1); qsort(jos,2,njos-1); {crearea infurtoarei convexe} {4. sus} repeat rem:=false; i:=2; while i<nsus do begin p1:=sus[i-1]; p2:=sus[i]; p3:=sus[i+1]; if sarrus(p1,p3,p2)>0 then i:=i+1 else begin rem:=true; 25

for j:=i to nsus-1 do sus[j]:=sus[j+1]; dec(nsus); end; end; until not rem; {si jos} repeat rem:=false; i:=2; while i<njos do begin p1:=jos[i-1]; p2:=jos[i]; p3:=jos[i+1]; if sarrus(p1,p3,p2)<0 then i:=i+1 else begin rem:=true; for j:=i to njos-1 do jos[j]:=jos[j+1]; dec(njos); end; end; until not rem; {5. asamblarea} for i:= nsus-1 downto 2 do begin inc(njos); jos[njos]:=sus[i]; end; drag:=jos; n:=njos; end;{conv}

La finalul execuiei procedurii punctele care formeaz nfurtoarea convex vor fi stocate n structura jos.

26

4. Triangularizri
Din punct de vedere geometric, triangularizarea T (S ) a mulimii de puncte S este o divizare a nfurtoarei convexe Q (S ) n fee din exact 3 muchii. Suplimentar, se vor respecta condiiile:

a) vrfuri ale muchiilor pot fi


numai puncte din S ;

b) toate punctele mulimii S


vor fi utilizate n calitate de vrfuri. (fig. 4.1).
Fig. 4.1. Triangularizarea unei mulimi de puncte

4.1. Un algoritm greedy pentru mulimi de puncte


Fie mulimea de puncte S i N = S . Fiecare punct p S este descris prin coordonatele sale carteziene ( x, y) . Triangularizarea T ( S ) poate fi cercetat ca un graf planar cu mulimea de noduri S . Prin urmare, numrul de muchii M n T (S ) este proporional7 cu N . O soluie simpl n plan este generarea tuturor muchiilor posibile cu extremiti n S , sortarea lor dup lungime, apoi adugarea consecutiv n triangularizare. n proces se verific, dac muchia curent intersecteaz muchiile adugate anterior. Dac interseciile lipsesc, muchia este adugat, n caz contrar, se trece la cercetarea muchiei urmtoare. Numrul total de muchii posibile pe punctele din S este
N 2 2 . Fiecare muchie poate fi cercetat ca un segment

descris prin extremitile sale:


7

Conform formulei Euler: M 3 N 6 . 27

type segment=record p1,p2:nod; l:real; end;

Prin urmare, verificarea interseciei muchiilor poate fi realizat folosind o procedur identic cu procedura de verificare a interseciei segmentelor ( 2.3).
Function intersect (A,B: segment): boolean; Begin If Sarrus(A.p2,A.p1,B.s1)*Sarrus(A.p2,A.p1,B.s2) 0 and Sarrus(B.s2,B.s1,A.p1)*Sarrus(B.s2,B.s1,A.p2) 0 then Intersect:= true else Intersect:= false End;

Calculul distanei (lungimii muchiei) dintre dou puncte


pi , p j S poate fi realizat printr-o funcie elementar:
Function distant (p[i],p[j]: nod): real; Begin Distant:= sqrt(sqr(p[i].x-p[j].x)+ sqr(p[i].y-p[j].y)); End;

Pseudocod Pas 1 m 0 Pas 2 For i 1 to N do


For j 1+i to N do Begin m Muchie[m].l Muchie[m].st Muchie[m].fin End; distant(p[i],p[j]) p[i] p[j]

Pas 3 qsort(muchie,m);
28

Pas 4 k0 Pas 5 For i 1 to M do


Begin z false For j 1 to k do If intersect(Muchie[i],Triang[j]) then z true If NOT z then Begin k; Triang[k] Muchie[i] End;

N .
2

Numrul total de muchii generate este proporional cu Sortarea lor va necesita un numr de operaii

N 2 log( N ) . Complexitatea pasului 5 este proporional cu determinat de numrul de verificri ale interseciilor, care nu depete N 3 . Prin urmare, complexitatea algoritmului

greedy este O( N 3 ) , ceea ce las de dorit pentru valori mari ale lui N .

4.2. Triangularizarea poligoanelor8 convexe


Este o problem elementar, care poate fi rezolvat n timp liniar. Fie P un poligon convex, dat prin lista vrfurilor p1 , p2 ,..., pN n ordinea parcur-gerii lor. Pentru a construi o triangularizare n P , este sufi-cient s fie construite segmen-tele p1 p3 ,..., p1 pN 1 (fig. diagonale
8

Fig. 4.2. Triangularizarea unui poligon convex

Aici i n continuare prin poligon se va nelege conturul acestuia n reuniune cu domeniul lui interior. 29

4.2). Numrul diagonalelor este proporional cu N (numrul de vrfuri ale poligonului). Construcia unei diagonale necesit un numr constant de operaii. Triangularizarea poligonului convex poate fi util pentru calculul ariei lui. Aria poligonului este egal cu suma ariilor triunghiurilor din triangularizare.

4.3. Triangularizarea poligoanelor simple9.


Metoda greedy. Realizarea direct a metodei din compartimentul precedent n cazul poligoanelor simple nu este posibil, deoarece apar dou condiii suplimentare care trebuie verificate:

a) aparine

oare muchia curent exteriorului poligonului triangularizat.

interiorului

sau

b) muchiile care formeaz frontiera poligonului urmeaz s


fie incluse n triangularizare indiferent de locul ocupat n lista distanelor. Verificarea primei condiii este echivalent cu verificarea apartenenei mijlocului muchiei la domeniul interior al poligo-nului. Algoritmul cere rezolv aceast problem este prezentat n ( 5.1). Problema a doua se rezolv elementar: prin includerea muchiilor, care formeaz frontiera P n nceputul listei, care descrie triangularizarea. Fie P un poligon simplu, dat prin lista de vrfuri p1 , p2 , ... , pN n ordinea parcurgerii lor. Algoritmul greedy va fi descris de urmtorul pseudocod:
Pas 1 m 0 Pas 2 For i 1 to N do For j 2+i to N do
9

Un poligon este simplu, dac laturile lui se intersecteaz doar n vrfuri. 30

Begin m Muchie[m].l Muchie[m].st Muchie[m].fin End; Pas 3 qsort(muchie,m);

distant(p[i],p[j]) p[i] p[j]

Pas 4 For i 1 to N-1 do Begin Triang[i].st p[i] Triang[i].fin p[i+1] End; Triang[N].st p[N] Triang[N].fin p[1] k N Pas 5 For i 1 to M do Begin z false For j 1 to k do If intersect(Muchie[i],Triang[j]) then z true If NOT z then Begin x,y middle(Muchie[i]) if apart(x,y,P)then begin k; Triang[k] Muchie[i] end; End; End;

Calculul coordonatelor mijlocului segmentului necesit un numr constant de operaii:


Procedure middle(a: segment; var x,y:real); Begin x:=(a.st.x+ a.fin.x)/2; y:=(a.st.y+ a.fin.y)/2; end;

Verificarea apartenenei la domeniul interior al poligonului are o complexitate proporional cu numrul N de laturi n P . Prin urmare, nu influeneaz complexitatea pasului 5 i complexitatea total a algoritmului .
31

5. Apropiere i apartenen
Capitolul este consacrat analizei unor probleme geometrice formulate pe puncte n plan: determinarea celei mai apropiate perechi de puncte i apartenena punctului la un domeniu. Soluiile directe ale problemelor de apropiere i apartenen sunt relativ simple, dar nu i optime.

5.1. Cea mai apropiat pereche de puncte


Fie n plan o mulime de puncte S = { s1 ,..., sN } . Se cere s se determine o pereche de puncte
si* , s* , i j : d (si* , s* ) = min d (si , s j ). j j
i =1,..., N j =1,..., N i j

Calculul direct al tuturor distanelor dintre N puncte ne-cesit un numr de 2 operaii pro-porional cu N :
index1 1; index2 2; min distance( s1 , s2 ); For i1 to N do For j1+i to N do If distance( si , s j ) < min then Begin min distance( si , s j ) index1 i; index2 j; End;
Fig. 5.1 Cea mai apropiat pereche de puncte

32

Acelai rezultat poate fi obinut ntr-un timp mai restrns, folosind algoritmul optim cu o complexitate de O( N log N )

33

Algoritmul optim Pentru a determina n timp optim cea mai apro-piat pereche de puncte, poate fi folosit tehnologia recursiv mparte i stp-nete. Ideea major este divizarea la fiecare pas re-cursiv a mulimii Fig. 5.2. Divizarea mulimii n submulimi seiniiale n dou parabile pentru rezolvarea recursiv a problemei cea mai apropiat pereche de puncte submulimi liniar separabile i rezolvarea prob-lemei pe fiecare submul-ime n parte (fig 5.2). Cazul elementar, care permite calculul direct al soluiei, este mulimea format din dou sau trei puncte. Numrul de operaii la acest pas este constant. Specificul problemei este determinarea soluiei optime la etapa de asamblare: avnd dou submulimi S1 i S 2 , cea mai apropiat pereche de puncte n S1 S2 poate s fie determinat de o pereche s, s : s S1, s S 2 . Se poate demonstra c la etapa asamblrii soluiei, numrul necesar de verificri la fiecare nivel este liniar fa de numrul de puncte n mulimile asamblate. Numrul de divizri consecutive ale mulimii n submulimi balansate10 nu va depi log( N ) . Dac numrul de operaii necesare pentru determinarea soluiei la un nivel de asamblare este proporional cu N , complexitatea final a algoritmului va fi O( N log N ) . Pentru soluionarea optim a problemei este necesar o preprocesare a mulimii: sortarea punctelor dup abscis (se obine irul sortat X ) i sortarea punctelor dup ordonata lor (irul Y ). Avnd complexitatea
10

Numrul de elemente n fiecare submulime difer cu cel mult o unitate. 34

O( N log N ) , sortarea nu modific complexitatea final a algoritmului. Fie la un nivel de divizare mulimea S , irul X sortat dup x, irul Y cu elementele S sortate dup y. Aparent, procesul de asamblare a soluiei la un nivel dat

are o complexitate O( N 2 ) : maxim N puncte n S1 i maxim N puncte n S 2 , dintre care urmeaz s fie calculate distanele. n realitate, numrul de operaii este mult mai mic. Fie S a fost divizat n submulimile S1 i S 2 , pe care au fost determinate distanele minime 1 i 2 , precum i perechile respective de puncte. Se consider (fig. 5.3) Pentru determina-rea soluiei optime pe

= min( 1, 2 )

S1 S2 este

necesar de a cerceta doar punctele, aflate n fia de lime de la dreapta l care separ submulimile. Celelalte puncte din Fig. 5.3. Determinarea punctelor poteniale pentru submulimi se afl, soluia pe S1 S2 evi-dent, la o distan mai mare dect unul de altul i nu pot mbunti soluia. Aceast restrngere nu garanteaz efectuarea unui numr liniar de operaii, deoarece pentru un punct cercetat s S1 n fia poate fi un numr de puncte proporional cu S 2 . O analiz mai detaliat permite
35
Fig. 5.4. Zona de cercetare n S 2 pentru un punct dat

s S1

excluderea din cercetare a tuturor punctelor care se afl n exteriorul dreptunghiului cu latura 2 , asociat punctului s (fig. 5.4). Numrul de puncte din

S 2 care se pot afla n

aceast zon nu poate fi mai mare dect 6, prin urmare numrul de verificri la etapa de asamblare nu va depi 6N . Folosind irurile X i Y, se formeaz irul Y , care conine punctele din S situate n fia [ l , l + ] , sortate dup y mulimea punctelor care pot m-bunti soluia. Pentru fiecare element din Y se calculeaz distanele doar pn la urm-toarele 8 elemente: ele repre-zint (n cel mai ru caz) simet-ric 6 puncte din din (fig. 5.5). Pseudocod
Preprocesare X S, sort(X) Y S, sort(Y) Procedure apr2p(S, X, Y) If {sortare dup x} {sortare dup y}

S1 plus 6 punc-te

Fig. 5.5. Numrul elementelor consecutive Y care pot modifica distana minim nu depete 9

S 2 minus 3 puncte care coincid, minus punctul cercetat

S 4 then
begin formeaz S1 , S 2 , X 1 , X 2 , Y1, Y2

min (apr2p( S1 , X 1 , Y1 ),apr2p( S 2 , X 2 , Y2 ) ) formeaz Y for i 1 to Y do


for j 1 to 8 do if distance( Y [i], Y [i+j]) < then 36

distance ( Y [i], Y [i+j]) Return end else Return distana minim n S {calculat direct}

5.2. Pologonul i diagrama Voronoi


O alt problem de apropiere n plan este problema deter-minrii poligonului Voronoi pentru o mulime de puncte. Fie n plan mulimea de puncte S = { p1 ,..., pN } . Fiecare punct
pi , i = 1, N ,

este descris prin coordonatele sale

carteziene pi ( xi , yi ) . Pentru un punct dat pi S se cere s se determine poligonul V (i ) care va conine toate punctele planului, mai apro-piate de pi dect de oricare alt punct
pj S, pi p j (fig. 5.6).

Problema generalizat pen-tru toate punctele mulimii S este cunoscut sub numele diag-rama Voronoi (fig 5.7). De menionat, c pentru unele puncte ale mulimii S , domeniul determinat de poligonul Voronoi poate fi unul infinit. Se poate demonstra c aceast proprietate o posed punctele, care formeaz nfurtoarea convex a mulimii S . Algoritmul direct pentru determinarea poligonului Voro-noi V(i) se bazeaz pe urm-toarea observaie: Dreapta l perpendicular pe mijlocul segmentului pi , p j
37

Fig. 5.6. Poligonul Voronoi V(i) pentru punctul pi.

Fig. 5.7 Diagrama Voronoi pentru mulimea S

conine punctele egal deprtate att de Punctele mai apropiate de


pi . pi

pi ct i de p j .

dect de

pj

vor forma

semiplanul de-terminat de dreapta l, care conine i punctul Fiecare punct p S este descris prin coordonatele sale car-teziene ( x, y) . Prin urmare, pentru perechea de puncte
pi , p j ,

mijlocul m al segmentului pi , p j va fi determinat de punctul cu coordonatele:


xm = ym = xi + x j 2 yi + y j 2 , ;

dreapta d, care conine segmentul cu extremitile pi , p j va fi descris de ecuaia Ax + By + C = 0 , unde


A = y j yi B = xi x j C = x j yi xi y j

orice dreapt l , perpendicular pe segmentul cu extremitile pi , p j va avea ecuaia general de forma Bx Ay + C = 0 ;

pentru dreapta l , perpendicular pe segmentul cu extremitile pi , p j , i care trece prin mijlocul acestuia,

valoarea coeficientului C este: Aym Bxm Odat ce este cunoscut ecuaia

dreptei

perpendiculare pe segmentul pi , p j , care trece prin mijlocul

38

acestuia,
V (i ) =

poate

fi
11

determinat

semiplanul

R( j) :

p R ( j ), d ( p, pi ) < d ( p, p j ).

Atunci

j =1,.., N j i

R ( j ).

Pentru realizarea algoritmului poate fi construit un poligon R de restrngere a planului, astfel nct S R . Cea mai simpl form a poligonului R este un dreptunghi avnd laturile paralele cu axele de coordonate, determinat de punctele diagonale ( xmin , ymin ) , ( xmax , ymax ) :
xmin = min ( xi ) 1 , xmax = max ( xi ) + 1 ,
i =1,..., N i =1,..., N

ymin = min ( yi ) 1 , ymax = max ( y i ) + 1 .


i =1,..., N i =1,..., N

Complexitatea algoritmului direct pentru construirea poligonului Voronoi V(i) este O( N 2 ) : Etapa 1: determinarea poligonului de restrngere necesit un numr de operaii, proporional cu N; Etapa 2: determinarea ecuaiei dreptei l, perpendiculare pe segmentul pi , p j necesit un numr de operaii mrginit de o constant. Etapa 3: determinarea interseciei dreptei l cu poligonul R i restrngerea ulterioar a acestuia necesit un numr de operaii proporional cu numrul de laturi ale poligonului R (nu mai mare dect N). Etapele 2 - 3 se repet pentru toate punctele p S , p pi . Prin urmare, numrul de operaii necesare pentru determinarea poligonului Voronoi va fi proporional cu N 2 .

11

Pentru dou puncte a,b date prin coordonatele ( xa , y a ), ( x b , y b )

d ( a, b ) =

xa xb + y a y b

39

Utilizarea algoritmului direct pentru determinarea diagra-mei Voronoi nu este eficient: complexitatea algoritmului crete pn la O( N 3 ) . Realizarea eficient a algoritmului de determinare a diagramei Voronoi se bazeaz pe tehnica divizrii consecutive a problemei n mulimi liniar separabile, pn la atingerea Fig. 5.8. Diagramele Voronoi DV(S1) i DV(S2) pn la concatenare. cazurilor elementare, i asamblarea ulterioar a soluiei [11, pag 258 - 269]. Fie S = S1 S 2 i au fost construite diagramele Voronoi
DV ( S1 ), DV (S 2 ) . (fig. 5.8) Pentru asamblarea soluiei vor fi realizate urmtoarele etape: Etapa 1: deter-minarea vectorilor de intrare (ieire) a lan-ului de concatenare: se construiesc muchii-le lips (dou la nu-mr) pentru nfurtoarea convex comu-n a S1 S 2 , se deter-min mijloacele aces-tor muchii i se tra-seaz vectorii perpendiculari pe acestea, i care trec prin punctele de mijloc. Pentru muchia superioar vectorul este orientat spre muchie, pentru cea inferioar de la ea (fig. 5.9). Din Fig. 5.9 Construirea nfurS prin nfurtoarea convex pentru toarei convexe pentruTrasarea adugarea muchiilor.

S1 S2

sunt

eliminate

lan-urile
40

vectorilor de intrare (ieire) a lanului de concatenare

interioare de muchii ale nf-urtoarelor separate pentru i

S1

S2 .

Etapa 2: Construirea lanului de concatenare. Construcia lanului ncepe pe vectorul superior, dintr-un punct care precede toate interseciile vectorului cu razele diagramelor construite anterior. Lanul se construiete de-a lungul vectorului, pn la intersecia cu una din muchiile diagramelor DV (S1 ) sau DV (S 2 ) . n punctul de intersecie direcia vectorului se modific. (fig. 5.10) Modificarea direciei lanului este determinat de modificarea perechii de puncte ntre care se traseaz acesta. Fie, iniial, lanul marcheaz frontiera dintre pi , p j . punctele Atingerea muchii diagramelor unei a
Fig. 5.10. Construirea lanului de concatenare

construite anterior semnific fie nlocuirea pi prin pk (dac muchia atins separ pi , pk ) fie nlocuirea p j prin pk (dac muchia atins separ perechea p j , pk ). Direcia nou a lanului de concatenare este determinat de normala median la segmentul ce unete perechea nou creat. Procesul ia sfrit n momentul atingerii vectorului inferior al lanului de concatenare. Etapa 3: Mo-dificarea muchiilor diagramei. Muchiile infinite (semidrep-te) intersectate de lanul de concate-nare
41

se transform n segmente delimi-tate de originea semidreptei i punctul de intersecie a acesteia cu lanul de concatenare. Muchiile finite (segmentele) i modific unul din punctele extreme, fiind nlocuit cu punctul de intersecie cu lanul de concatenare. Muchiile din DV (S1 ) , situate integral n dreapta de lanul de concatenare, i DV (S 2 ) , muchiile din situate integral n stnga, se exclud din diagrama final. Cazul elementar se obine pentru
2 S 3.

Procesarea acestuia este realizat printr-un numr de operaii mrginit de o constant. Fig. 5.11. Concatenarea diagramelor Divizarea consecutiv a mulimii pentru obinerea cazurilor elementare necesit o sortare prealabil a punctelor din S dup abscisa lor. Complexitatea O( N log N ) . preprocesrii este Numrul de divizri consecutive ale mulimii curente n dou submulimi aproape egale12 este proporional cu log( N ) . Pentru concatenarea soluiilor pariale, n cazul alegerii structurilor de date adecvate este necesar un numr de operaii proporional cu numrul total de muchii din soluiile pariale. Deoarece diagrama Voronoi este o divizare planar a unei mulimi din N puncte, numrul de muchii va fi proporional cu N. Prin urmare, complexitatea to-tal a algoritmului optim este O( N log N ) .
12

S1 aproape egal cu S 2 dac S1 S2 1


42

5.3. Apartenena punctului la un domeniu


Apartenena punctului la un poligon convex Problema determinrii apartenenei unui punct la un poligon convex este una simpl i poate fi rezolvat cu ajutorul algoritmilor cercetai anterior. Se observ uor (fig. 5.12) c poziia unui punct interior fa de fiecare din vectorii determinai de vrfurile consecutive ale poligonului este una i aceeai la dreapta, dac vrfurile sunt parcurse n direcia micrii acelor de ceasornic, i la stnga n cazul parcurgerii vrfurilor n direcie opus. Poziia punctului s fa de un vector
u uu uu r pi p j

poate

fi

determinat n timp constant ( 3.1). Prin urmare, complexitatea algorit-mului este proporional doar cu numrul de laturi ale poligonului. Fie punctual s de coor-donate ( xs , ys ) i poligonul con-vex Fig. 5.12. Punctele interioare sunt plasate de aceeai parte a vectorilor P = ( p1 , p2 , ... , pN ) cu N laturi, determinai de vrfurile consecutive ale descris prin lista vrfurilor, poligonului, poziia celor exterioare poate varia. parcurse consecutiv (coordonatele vrfurilor sunt stocate n tabloul liniar de articole P cu cmpurile x i y). Pentru a simplifica implementarea, n lista de vrfuri ale poligonului este inclus un vrf virtual

pN +1 p1 .

function apart : boolean; var i : integer; function verific_punct(x1,y1,x2,y2,x3,y3:real):boolean; 43

begin if x1*y2+x2*y3+y1*x3-x3*y2-x2*y1-y3*x1 > 0 then verific_punct:=true else verific_punct:=false; end; begin apart:=true; for i:=1 to N do if not verific_punct(p[i].x,p[i].y,p[i+1].x,p[i+1].y,s.x,s.y) then apart:=false; end;

44

Apartenena punctului la un poligon stelat Fie un poligon arbitrar P = ( p1 , p2 ,..., pN ) cu N laturi. Dac n P exist un punct interior c, astfel nct toate segmentele [c, p1 ],[c, p2 ],...,[c, pN ] aparin integral P, poligonul se numete stelat. (fig. 5.13) n cazul, n care punctul interior c este cunoscut Fig. 5.13. P - poligon stelat apriori, determinarea apartenenei unui punct arbitrar s la domeniul interior al poligonului se reduce la verificarea existenei unui triunghi13
Vcpi pi +1 , , i = 1, N care s conin punctul s n calitate de punct

interior. Numrul triunghiurilor este N, numrul de operaii necesare pentru verificarea apartenenei punctului la interiorul unui triunghi este mrginit de o constant. Prin urmare complexitatea determinrii apartenenei punctului la un poligon stelat va fi cunoscut. Apartenena punctului la un poligon simplu Problema apartenenei unui punct s la domeniul determinat de un poligon simplu P poate fi rezolvat prin triangularizarea P i prin verificarea ulterioar a apartenenei s la unul din triun-ghiurile formate n procesul triangularizrii.
13

O( N ) n condiia c punctul c este

Vrful pN+1 este unul virtual i coincide cu p1


45

Un algoritm mai eficient este bazat pe numrarea interseciilor ale dreptei orizon-tale l care trece prin punctul dat s cu laturile poligonului P. (fig. 5.14). Se va cerceta partea dreptei spre stnga de s. Pentru latura curent se determin :

poziia punctului fa de aceasta

intersecia laturii cu semidreapta l. Dac numrul interseciilor spre stnga de s este impar punctul se afl n interiorul poligonului; pentru un numr par de intersecii, punctul se afl n exterior. Demonstraia este elementar: la parcurgerea spre stnga, prima intersecie marcheaz intrarea semidreptei n interiorul poligonului, urmtoarea ieirea. Fiecare pereche urmtoare de intersecii are aceeai semnificaie. Pentru stabilirea interseciei semidreptei cu latura curent pot fi utilizate metodele descrise n 2.2. Cazuri speciale. dreapta l trece printr-un vrf pi al poligonului P la stnga de s. Vrfurile pi 1 i pi +1 se afl de pri diferite ale dreptei l. Numrul de intersecii se incrementeaz cu 1.

Fig. 5.14. Numrul de intersecii ale semidreptei l cu laturile poligonului determin apartenena punctului s la interiorul poligonului P.

46

dreapta l conine latura pi pi+1 a poligonului P la stnga de s. Vrfurile pi 1 i pi + 2 se afl de pri diferite ale dreptei l. Numrul de intersecii se incrementeaz cu 1. dreapta l trece prin un vrf pi al poligonului P la stnga de s. Vrfurile pi 1 i pi +1 se afl de aceeai parte a dreptei l. Numrul intersecii nu se incrementeaz. de

dreapta l conine latura pi pi+1 a poligonului P la stnga de s. Vrfurile pi 1 i pi + 2 se afl de aceeai parte a dreptei l. Numrul de intersecii nu se incrementeaz.

Numrul de laturi procesate este N. Determinarea interseciei laturii cu dreapta l este realizat ntr-un numr constant de operaii. Procesarea cazurilor speciale este realizat de asemenea ntr-un numr de operaii mrginit de o constant. Prin urmare, complexitatea algoritmului este O( N ) .

47

5.4. Nuclee
Printre problemele geometrice de calcul se numr i problema nucleului poligonului simplu. Nucleul unui poligon simplu P este, n general, format din mulimea de puncte astfel nct: x Q,y P,[ x, y ] P Cu alte cuvinte, nucleul poligonului este mulimea de puncte ale poligonului, care, fiind unite cu orice alt punct al poli-gonului, formeaz un segment ce aparine interiorului poligonului (fig. 5.15a). Nu ntotdeauna un poligon simplu are nucleu nevid (fig. 5.15.b). Nucleul poligonului (dac el exist) este i el un poligon, dar, spre deosebire de poligonul iniial, este ntotdeauna convex.

Q P,

Fig. 5.15. a) Poligon simplu cu nucleu, b) poligon simplu fr nucleu

Algoritmul pentru determinarea nucleului unui poligon simplu


Date iniiale. Fie un poligon simplu P cu N vrfuri. Se consider c poligonul este descris prin lista vrfurilor sale ( p1 , p2 ,..., pN 1 , pN ) , parcurse n direcia micrii acelor de ceasornic. Fiecare vrf pi este descris de coordonatele sale
( xi , yi ) .

Algoritmul de determinare a nucleului necesit o construcie secundar: un poligon convex Q care, iniial, conine poligonul P . Pentru determinarea poligonului Q pot fi abordate dou metode:
48

a) construirea nfurtorii convexe pentru P ; b) construirea unui dreptunghi care conine poligonul
n interiorul su.

Metoda a doua este mult mai simpl. Ea se reduce la determinarea, pentru coordonatele vrfurilor poligonului, a valorilor minime i maxime ale abscisei i ale ordonatei. n calitate de Q poate fi considerat dreptunghiul cu vrfurile ( xmax + 1, ymax + 1) , ( xmax + 1, y min 1) , ( xmin 1, y min 1) , ( xmin 1, y max + 1) . Extinderea valorilor extreme nu este o condiie obligatorie. Dup construcia poligonului Q poate fi realizat nemijlocit determinarea nucleului. Metoda (sau cel puin descrierea ei n limbajul uman) este foarte simpl: Se analizeaz consecutiv laturile poligonului P , fiind parcurse n direcia micrii acelor de ceasornic. Latura curent ( pi , pi+1 ) se cerceteaz ca o dreapt l. Se determin partea poligonului Q , care se afl n stnga vectorului pi pi +1 i se exclude din Q . Dac poligonul Q se este situat integral n stnga de vectorul pi pi +1 , cercetarea ia sfrit poligonul P nu are nucleu. Procedeul se repet pn nu sunt analizate toate laturile poligonului P . n final, Q conine nucleul lui P . (fig. 5.16).
uuu u uu r uuu u uu r

49

Fig. 5.16. Construirea consecutiv a nucleului poligonului simplu

50

Pseudocod Pas 1. Iniializare La sfritul listei de vrfuri (dup pN ) se adaug vrful virtual pN +1 = p1 . Se construiete poligonul Q (nucleul ini-ial), conform uneia din metodele descrise anterior. i 1;

Pas 2.

Procesarea laturii i. Fie Q = ( q1 , q2 ,...qk ) . Pentru dreapta l ce conine latura i a poligonului

P definit de vrfurile ( pi , pi+1 ) se

determin punctele de intersecie cu poligonul Q , precum i laturile intersectate. Fie d1 , d 2 punctele de intersecie a dreptei l cu Q , iar laturile intersectate:
( q j , q j +1 ) i ( qk , qk +1 ) 14.

a. Se formeaz poligoanele
Q2 = (d 2 , q k +1 , ... , q N , q1 , ... , q j , d1 )

Q1 = (d1 , q j +1 , ... , q k , d 2 ) i

b. Se determin
c. Pas 3.
Q Q*

Q* {Q1 , Q2 } care uuuu u u uu r dreapta vectorului ( pi pi +1 ) .

se

afl

Repetare if i < N then begin i goto pas 2 end else STOP Q este nucleul.
O( N 2 ) . Se Complexitatea algoritmului este de prelucreaz N laturi ale poligonului P . Pentru fiecare latur se verific intersecia cu maximum N laturi ale poligonului Q . Fiecare intersecie este determinat ntr-un numr de operaii mrginit de o constant.
14

Dac dreapta nu intersecteaz poligonul

fa de pi pi +1 . Dac poligonul e poziionat n stnga, nucleul final este vid, altfel

uuu u uu r

Q , se verific doar poziia Q

Q nu se modific la acest pas.


51

6. Probleme geometrice de concurs


6.1 Robot
Un robot punctiform poate executa instruciuni de deplasare n 8 direcii (1 nord, 2 nord-est, 3 est, 4 sud-est, 5 sud, 6 sud-vest, 7 vest, 8 nord-vest). Lungimea pasului robotului este 1 pentru direciile 1, 3, 5, 7 i 2 pentru direciile 2, 4, 6, 8. Numrul de pai efectuai n direcia aleas este un parametru al instruciunii de deplasare. Fiind dat un set de instruciuni, s se determine coordonatele punctului final n care se va deplasa robotul. Astfel, pentru setul (1, 3) (3, 1) (1, 1) (3, 3) (5, 2) (7, 1) coordonatele finale vor fi (3, 2) . Cerin S se scrie un program care, dup un set de instruciuni, s determine coordonatele punctului final n care se va deplasa robotul. Se consider c axa Ox e orientat spre est, iar Oy spre nord. Iniial robotul se afl n originea sistemului de coordonate (0, 0). Date de intrare Prima linie a fiierului de intrare conine numrul N numrul de instruciuni (1N40). Urmtoarele N linii conin instruciunile propriu-zise numrul direciei (un numr ntreg de la 1 la 8) i numrul de pai (un numr ntreg de la 1 la 1000), separate prin spaiu.
52

Date de ieire Unica linie a fiierul de ieire va conine dou numere ntregi X i Y separate prin spaiu coordonatele punctului final n care se deplaseaz robotul. Exemple
date.in 6 1 3 1 3 5 7 1 8 3 2 3 1 1 3 2 1 -10 10 10 date.out

Rezolvare
program p01; var I,N:integer; D,L,X,Y:Longint; begin assign(Input,'date.in'); reset(Input); read(N); X:=0; Y:=0; {fixarea pozitiei initiale} for I:=1 to N do begin {modelarea deplasarii} read(D,L); case D of 1: Y:=Y+L; { deplasare nord cu L} 2: begin X:=X+L; Y:=Y+L; end; {nord-est cu L} 3: X:=X+L; {est cu L} 4: begin X:=X+L; Y:=Y-L; end; {sud-est cu L} 5: Y:=Y-L; {sud cu L} 6: begin X:=X-L; Y:=Y-L; end; {sud-vest cu L} 7: X:=X-L; {vest cu L} 8: begin X:=X-L; Y:=Y+L; end; {nord-vest cu L} end; end; assign(Output,'date.out'); rewrite(Output); write(X,' ',Y); close(Input); close(Output); end. 53

6.2.Robot II

Sistemul de comand al unui robot care poate executa ins-truciuni de deplasare s-a deteriorat. Robotul continu s pri-measc instruciuni, dar le interpreteaz nu ntotdeauna corect. Fiecare instruciune este un triplet de numere

(u,vx,vy) ntregi, poziti-ve. Dac u > 90, atunci robotul se


depla-seaz cu vx dup axa Ox i cu vy dup axa Oy. Dac, ns u 90, robotul se depla-seaz pe un arc de msura u a cercului de (vx,vy) mpotriva micrii acelor de ceasornic. Raza cercului este segmentul care unete robotul cu centrul cercului. Cerin S se scrie un program care, dup coordonatele iniiale ale robotului i un set dat de instruciuni, determin punctul final n care va fi poziionat acesta. Date de intrare Prima linie a fiierului de intrare conine dou numere ntregi coordonatele iniiale ale robotului. Urmtoarele linii conin cte o instruciune, format din trei numere ntregi, separate prin spaiu. Date de ieire Unica linie a fiierul de ieire va conine dou numere X i Y, separate prin spaiu coordonatele finale ale robotului, indicate cu cel puin 3 cifre dup virgul.

54

Exemplu
date.in 3 2 130 4 1 45 1 7 91 0 3 60 0 6 date.out -0.653 15.697

Rezolvare
program p02; const pi=3.141592; type point=record x,y : real; end; var P: point; alfa,xn,yn:real; procedure move(var P:point; vx,vy:real); begin P.x:=P.x+vx; P.y:=P.y+vy; end; procedure rotate (var P:point; u,vx,vy:real); var old:point; begin old:=P; P.x:=vx+(old.x-vx)*cos(u*pi/180)(old.y-vy)*sin(u*pi/180); P.y:=vy +(old.x-vx)*sin(u*pi/180)+ (old.y-vy)*cos(u*pi/180); end; begin assign(input,'data.in'); reset(input); assign(output,'data.out'); rewrite(output); readln(P.x,P.y); while not eof do begin readln(alfa,xn,yn); if alfa>90 then move(P,xn,yn) else rotate(P,alfa,xn,yn); end; writeln(P.x:10:3,' ',P.y:10:3); close(input); close(output); end. 55

6.3. Piatra
... i unde nu pornete stnca la vale, sltnd tot mai sus de un stat de om; i trece prin gardul i prin tinda Irinuci, pe la capre, i se duce drept n Bistria, de clocotea apa! Ion Creang. Amintiri din copilrie

Piatra pornit de Ion Creang se rostogolea n linie dreapt, drmnd totul n calea sa. Casa Irinuci are muli perei, unii nimerind n calea pietrei. Fiind date coordonatele a dou puncte prin care trece piatra i extremitile segmentelor care descriu baza pereilor casei, s se determine, ci perei vor fi drmai de piatra n cdere. Peretele atins ntr-un punct extrem rmne ntreg. Cerin Scriei un program care determin numrul de perei drmai de piatr. Date de intrare Fiierul de intrare conine N (N < 1000) linii a cte patru numere ntregi. Prima linie conine descrierea a dou puncte prin care trece piatra, n forma x1 , y1 , x2 , y2
xi , yi < 500 .

Urmtoarele N-1 linii conin descrierea coordonatelor extremitilor bazelor pereilor, n aceeai consecutivitate, cu aceleai restricii de valori. Date de ieire Unica linie a fiierul de ieire va conine un numr ntreg numrul de perei drmai de piatr.

56

Exemplu
date.in 2 1 9 14 2 4 1 8 1 12 3 9 4 14 6 11 7 14 9 10 9 14 7 16 6 10 8 8 3 6 6 6 4 2 4 5 11 10 12 14 8 6 10 8 12 8 14 4 date.out 4

Rezolvare
program p03; type point=record x,y: real; segment=record e1,e2: point; var g: array[1..1000] of segment; l: segment; n,i,k: integer; end; end;

function sarrus(p1,p2,p3:point): real; begin sarrus:=p1.x*p2.y+p2.x*p3.y+p1.y*p3.x -p3.x*p2.y-p3.y*p1.x-p1.y*p2.x; end; begin assign(input, 'date.in'); reset(input); n:=0; readln(l.e1.x,l.e1.y,l.e2.x,l.e2.y); while not eof do begin inc(n); readln( g[n].e1.x, g[n].e1.y,g[n].e2.x,g[n].e2.y); end; k:=0; for i:=1 to n do if sarrus(l.e1,l.e2,g[i].e1)*sarrus(l.e1,l.e2,g[i].e2) < 0 then inc(k); assign(output, 'date.out'); rewrite(output); writeln(k); close(input); close(output); end.

57

6.4 Carcase
Fie o carcas, avnd forma unui poligon simplu. Pentru a fi poziionat vertical pe o suprafa plan, carcasa trebuie s aib centrul de mas situat strict ntre 2 puncte de contact cu suprafaa. Centrul de mas este ntotdeauna un punct interior al carcasei i nu coincide cu nici un vrf al ei. Cerin S se scrie un program care va determina numrul poziiilor n care poate fi stabilizat vertical carcasa Date de intrare Prima linie a fiierului de intrare conine trei numere ntregi, separate prin spaiu: N (3 N 1000) - numrul de vrfuri ale carcasei i xc, yc (1000 xc, yc 1000 ) coordonatele centrului de mas. Urmeaz N linii ce conin cte 2 numere ntregi xi, yi (1000 xi, yi 1000), separate prin spaiu, coordonatele vrfurilor poligonului n ordinea parcurgerii lor. Date de ieire Fiierul de ieire va conine un numr ntreg numrul de poziii n care poate fi stabilizat vertical carcasa.

58

Exemplu
drag.in 10 6 16 3 14 13 4 23 14 33 4 33 14 23 24 13 14 3 24 -7 14 -7 4 drag.out 3

Rezolvare Deoarece carcasa se sprijin pe careva puncte extreme ale poligonului, problema poate fi divizat n dou subprobleme relativ simple:

1) determinarea

nfurtoarei convexe a vrfurilor poligonului; 2) verificarea dac un triunghi conine un unghi obtuz. Prima subproblem este rezolvat cu ajutorul algoritmului descris anterior ( 3.2). Dup determinarea nfurtoarei convexe, problema poate fi reformulat n felul urmtor: Fie un poligon convex P i un punct interior c, unit prin linii drepte cu vrfurile poligonului. n cte dintre triunghiurile formate nlimea construit din punctul c se proiecteaz ntr-un punct interior al laturii poligonului care aparine triunghiului? Evident, nlimea construit din c se proiecteaz pe latur dac nici unul dintre unghiurile alturate laturii poligonului nu este obtuz. Verificarea unghiurilor se realizeaz elementar cu ajutorul teoremei cosinusurilor. Complexitatea etapei este liniar dup numrul de vrfuri.
59

6.5. Turnuri
Bitlanda este o ar care se extinde permanent. Pentru a apra frontierele sale, dup fiecare extindere, n noile puncte extreme ale frontierei se construiesc turnuri de veghe. Exist N turnuri de veghe, date prin coordonatele lor (xi, yi) numere ntregi. Regele Bitlandei, Bytezar, a decis sa trimit la vatr garnizoanele turnurilor care nu se mai afl la hotarele rii. Cerin Scriei un program, care va determina cte turnuri vor fi lipsite de garnizoane. Date de intrare Prima linie a fiierului de intrare conine un numr ntreg: N (1 N 10000) numrul de turnuri de veghe n Bitlanda. Urmeaz N linii ce conin cte dou numere ntregi xi,yi (1000 xi, yi 1000), separate prin spaiu coordonatele turnu-rilor de veghe. Date de ieire Fiierul de ieire va conine un numr ntreg numrul de turnuri care pot fi lipsite de garnizoane. Exemplu
turn.in 10 2 1 3 4 6 3 6 6 8 5 10 3 11 7 12 6 9 11 15 8 Turn.out 5

60

6.6

Atac

Agenia Spaial a planetei Bitterra (ASB) a recepionat un roi meteoritic, care se apropie de planet. Fiecare stat de pe Bitterra a fost anunat despre pericol i a primit lista punctelor de cdere a meteoriilor, calculate de ASB. Serviciile pentru situaii excepionale ale fiecrui stat urmeaz s determine, ci meteorii vor cdea pe teritoriul rii. Frontiera oricrui stat de pe Bitterra este un poligon convex; meteoriii sunt punctiformi. Punctele de pe frontier nu se consider aparinnd statului. Frontiera poate conine mai multe vrfuri consecutive coliniare. Cerin S se scrie un program care va determina numrul de meteorii, ce cad pe teritoriul unui stat dat. Date de intrare Prima linie a fiierului de intrare atac.in conine numrul n numrul de vrfuri ale poligonului, care descrie frontiera unui stat. Urmtoarele n linii conin descrierea consecutiv a vrfurilor frontierei: fiecare linie va conine cte o pereche de numere separate prin spaiu coordonatele unui vrf. Urmeaz o linie care conine un numr ntreg m numrul de meteorii, apoi M linii, care conin cte dou numere, separate prin spaiu, coordonatele punctelor de cdere a meteoriilor. Date de ieire Fiierul de ieire atac.out va conine un singur numr ntreg cel al meteoriilor care cad pe teritoriul statului dat. Restricii 1. Coordonatele vrfurilor poligonului i a punctelor de cdere a meteoriilor sunt numere ntregi din intervalul [-1000000, 1000000]
61

3 n 20000 3. 2 m 20000 Exemplu


atac.in 4 2 8 6 4 4 3 4 5 6 4 4 8 6 5 7 5 7 atac.out 2 Explicaie

2.

Soluie: Formularea abstract a problemei este urmtoarea: Fie n plan un poligon convex P cu n vrfuri. n acelai plan este dat o mulime din m puncte M. Se cere s se determine cte puncte din M aparin interiorului P. Rezolvarea se divide n cteva etape.

1. Determinarea

unui punct intern al poligonului (centrul de mas). Fiind date coordonatele ( xi , yi ) ,


i = 1, n ale vrfurilor poligonului P,

coordo-natele centrului de mas pot fi calcu-late dup formula:


xcm =

xi
i =1

ycm =

y
i =1

62

2. Fiind dat un punct intern (xcm, ycm) al poligonului, se


calculeaz unghiurile, pe care le formeaz cu axa Ox semidreptele duse din acesta prin vrfurile (cx, cy).
function angle(cx,cy:real): real; begin sinus:=(cy -ycm)/ sqrt(sqr(cy-ycm)+sqr(cx-xcm)); cosinus:= (cx -xcm)/ sqrt(sqr(cy-ycm)+sqr(cx-xcm)); if cosinus=0 then if sinus>0 then angle:= pi/2 else if sinus<0 then angle:=3*pi/2 else begin if (sinus>0) and (cosinus>0) then angle:=arctan(sinus/cosinus); if (sinus>0) and (cosinus<0) then angle:=pi-arctan(abs(sinus/cosinus)); if (sinus<=0)and (cosinus<0) then angle:=pi+arctan(abs(sinus/cosinus)); if (sinus<=0) and (cosinus>0) then angle:=2*pi-arctan(abs(sinus/cosinus)); end; end;

3. Pentru un punct dat din M


se calculeaz unghiul format de semidreapta determinnat de acesta i centrul de mas al poligonului cu axa Ox. Se folosete aceeai funcie de la etapa 2.
alfa:=angle(b[i].x,b[i].y)

4. Se determin muchia poligonului, intersectat de


semidreap-ta determinat la pasul 3. Pentru optimizarea acestui pas se folosete cutarea binar.
63

k:=1; {determinarea vrfului 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) then begin st:=k; dr:=k+1; end else begin if (alfa < a[1].u) then begin st:=k+1; dr:=n+1; end else begin st:=1; dr:=k; end; repeat mj:=(st + dr) div 2; if a[mj].u >alfa then dr:=mj else st:=mj until dr=st+1; end;

5. Se determin poziia centrului de mas i a punctului


curent din M fa de muchia determinat. Dac sunt de aceeai parte, punctul curent este n interior. Pentru determinarea poziiei se folosete semnul determinantului
x1 x2 x3 y1 1 y2 1 y3 1

unde

( x1 , y1 ), ( x2 , y2 )

sunt

coordonatele vrfurilor care determin muchia, iar ( x3 , y3 ) coordonatele punctului cercetat (respectiv coordonatele centrului de mas).
q:=semn(a[st].x,a[st].y,a[dr].x,a[dr].y,b[i].x,b[i].y); p:=semn(a[st].x,a[st].y,a[dr].x,a[dr].y,xcm,ycm); if p*q>0 then inc(s);

64

6.7. Evadare
Un grup de pinguini a decis s evadeze din grdina zoologic. n acest scop ei au spat un tunel liniar. Din nefericire, zidul grdinii zoologice formeaz un poligon simplu cu N (3 N 10000) laturi, astfel nct, ieind din tunel, pinguinii nu pot afirma cu certitudine dac se afl n interiorul grdinii zoologice sau n afara ei. Cerin S se scrie un program care, dup coordonatele punctelor extreme ale tunelului i coordonatele vrfurilor poligonului ce stabilete perimetrul grdinii zoologice, va determina dac evada-rea s-a soldat cu succes sau nu. Date de intrare Prima linie a fiierului de intrare evadare.in conine patru numere ntregi, separate prin spaiu, coordonatele punctelor ex-treme ale tunelului. Urmtoarele linii conin descrierea conse-cutiv a vrfurilor zidului: fiecare linie va conine cte o pereche de numere, separate prin spaiu, coordonatele unui vrf. Date de ieire Fiierul de ieire evadare.out va conine un singur cuvnt DA n cazul n care punctul final al tunelului este n afara grdinii zoologice; NU n caz contrar. Restricii Coordonatele vrfurilor poligonului i ale punctelor extreme ale tunelului sunt numere ntregi din intervalul [1000, 1000]

65

Exemplu
evadare.in 5 3 7 7 1 2 2 6 6 4 6 7 7 5 10 4 7 2 3 1 evadare.out DA Explicaie
7 5 3 1 1 3 5

6.8. Arcai
Secretul victoriilor faimosului comandant de oti MegaFlop este strategia lui de alegere a poziiei arcailor pe cmpul de lupt. Cmpul are forma unui poligon simplu i e nconjurat de pduri. MegaFlop plaseaz arcaii doar pe poziii din care este vzut tot cmpul de lupt. Se consider c arcaii vd tot cmpul, dac din orice punct care aparine poziiei lor de tragere se poate trage cu sgeata n orice alt punct al cmpului. Traiectoria sgeii este liniar. Nimerind n pdure, sgeata se pierde. Pentru tragere, fiecare arca are nevoie de o unitate de suprafa. Astfel, numrul maxim de arcai, care pot fi plasai pe poziii este determinat de aria poligonului din care este vzut toat cmpia. Cerin S se scrie un program care determin numrul maxim de arcai care pot fi plasai pe poziii de tragere n cmpul de lupt.

66

Date de intrare Fiierul de intrare arcas.in va conine pe prima linie un numr ntreg N numrul de vrfuri ale poligonului simplu, care descrie perimetrul cmpului de lupt. Urmeaz N linii care conin coordonatele vrfurilor poligonului parcurse n sensul acelor de ceasornic, cte un vrf pe linie. Linia i+1 conine dou numere ntregi xi, yi, separate prin spaiu coordonatele vrfului i. Date de ieire Fiierul de ieire arcas.out va conine un singur numr ntreg: numrul maxim de arcai, care pot fi plasai pe poziii. Restricii
3 N 1000 0 < xi, yi 10000

Exemplu
arcas.in 9 2 5 3 6 2 7 4 7 6 9 8 6 7 2 5 4 3 4 arcas.out 11

Rezolvare
program p68; type lat=record x,y:real; end; pol=array[0..1001] of lat; var nuc,camp:pol; i,nnuc,ncamp:integer; xint,yint:real; 67

procedure init; var square : array[1..5,1..2] of integer; i: integer; begin {initializare nucleu} nuc[1].x:=0; nuc[1].y:=0; nuc[2].x:=0; nuc[2].y:=10001; nuc[3].x:=10001; nuc[3].y:=10001; nuc[4].x:=10001; nuc[4].y:= 0; nuc[5].x:=nuc[1].x; nuc[5].y:= nuc[1].y; nnuc:=4; { si initializare poligon} readln(ncamp); for i:=1 to ncamp do readln(camp[i].x,camp[i].y); camp[ncamp+1].x:=camp[1].x;camp[ncamp+1].y:=camp[1].y; end; function intersect (al,bl,cl,ad,bd,cd:real;i,j:integer): boolean; {determin intersecia dreptei i laturii + coordonate punctului de intersecie} begin {1. dreapta i latura sunt paralele} if Ad*Bl=Bd*Al then begin intersect:=false; exit; end; {2. dreapta intersecteaz 2 laturi adiacente n punct extrem} if (camp[j+1].x=nuc[i].x) and (camp[j+1].y=nuc[i].y) then begin intersect:=true; xint:=nuc[i].x; yint:=nuc[i].y; exit; end; if (camp[j].x=nuc[i+1].x) and (camp[j].y=nuc[i+1].y) then begin intersect:=true; xint:=nuc[i+1].x; yint:=nuc[i+1].y; exit; 68

end;

69

{3. Dreapta i latura nu sunt paralele} if (Ad*Bl<>Bd*Al) then if Al<>0 then begin yint:=(Ad*Cl-Cd*Al)/(Bd*Al-Ad*Bl); xint:=(-Bl*yint-Cl)/Al; end else begin yint:=-Cl/Bl; xint:=(-Bd*yint-Cd)/Ad; end; if (((xint>=nuc[i].x) and (xint<=nuc[i+1].x)) or ((xint>=nuc[i+1].x) and (xint<=nuc[i].x))) and(((yint>=nuc[i].y) and (yint<=nuc[i+1].y)) or ((yint>=nuc[i+1].y) and (yint<=nuc[i].y))) then intersect:=true else intersect:=false; end; function sarrus(a,b,c:lat):real; 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; end; procedure cut(j:integer); { Proceseaz latura j a poligonului P} var al,bl,cl,ad,bd,cd:real; inter: array[1..4] of lat; index: array[1..4] of integer; k,ii,i,nr:integer; copy: pol; begin Ad:=camp[j+1].y - camp[j].y; Bd:=camp[j].x-camp[j+1].x; Cd:=camp[j+1].x*camp[j].y-camp[j].x*camp[j+1].y; nr:=0; for i:=1 to nnuc do begin Al:=nuc[i+1].y -nuc[i].y; Bl:=nuc[i].x-nuc[i+1].x; 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) then

70

begin nr:=nr+1; inter[nr].x:=xint; inter[nr].y:=yint; index[nr]:=i; end; end; if nr>=2 then begin if sarrus(camp[j],camp[j+1],nuc[index[1]])>=0 then begin ii:=1; copy[1].x:=inter[1].x; copy[1].y:=inter[1].y; for k:=index[1]+1 to index[2] do begin inc(ii); copy[ii]:=nuc[k]; end; inc(ii); copy[ii].x:=inter[2].x; copy[ii].y:=inter[2].y; nnuc:=ii; inc(ii); copy[ii].x:=inter[1].x; 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 else if sarrus(camp[j],camp[j+1],nuc[1])>=0 then

71

begin writeln(0); close(output); halt; end; end; function area(a:pol;n:integer):real; {aria poligonului simplu} var s:real; i:integer; begin s:=0; 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; end; {programul principal} begin assign(input,'arcas.in'); reset(input); assign(output,'arcas.out'); rewrite(output); init; for i:=1 to ncamp do cut(i); writeln(area(nuc,nnuc)); close(input); close(output); end.

72

6.9. Cetate
Arheologii din Bitlanda n timpul spturilor au descoperit nite pietre aezate oarecum straniu. Dup studiere au ajuns la concluzia ca acestea for-meaz fragmente ale unui zid circular, care nconjura o cetate veche. Pentru a proteja de turiti i de curi-oi fragmentele descoperite arheologii au decis s nconjoare fragmentele desco-perite cu un gard din plas metalic. nconjurarea fiecrui fragment este destul de complicat i puin comod, de aceea sa hot-rt s se mprejmuiasc toate fragmentele mpreun. Cerin S se scrie un program care s determine lungimea minim a plasei necesare pentru a ngrdi fragmentele zidului. Date de intrare Prima linie a fiierului de intrare conine dou numere: n (1 n 180) a fragmentelor de zid i r (1 r 100) raza zidului. Urmeaz n perechi de numere ntregi, care descriu fragmentele de zid: ai, bi mrimea unghiurilor n grade, care descriu nceputul i sfritul fragmentului. Unghiurile se msoar ncepnd cu direcia nord de la centrul cetii, mpotriva direciei de micare a acelor de ceasornic (0 ai; bi < 360, ai bi). Fiecare fragment este descris la fel mpotriva direciei de micare a acelor de ceasornic. Fragmentele de zid nu au puncte comune. Date de ieire Fiierul de ieire va conine lungimea minim a plasei necesare, cu trei cifre dup virgul. Exemplu
cetate.in 2 10 cetate.out 61.888

73

330 30 90 270

6.10. Druizi
Ruinele din Stonehenge se afl ntr-un loc special, unde se inter-secteaz M linii energetice ale P-mntului. Liniile energetice mpart cmpia Stonehenge n sectoare. n fiecare an, n cea mai scurt zi a anului, N druizi se adun n cmpie pentru un ritual, ce asigur o road bogat pentru anul urmtor. Pentru succesul ritualului este necesar ca n fiecare sector al cmpiei, delimitat de liniile energetice, s se afle nu mai mult dect un druid. Cmpia are forma unui ptrat cu centrul n originea sistemului de coordonate i are lungimea laturii L. Liniile energetice sunt linii drepte. Druizii sunt punctiformi i nu se pot afla pe liniile energetice. Cerin S se scrie un program care determin dac exist sectoare ale cmpiei n care se afl 2 sau mai muli druizi. Date de intrare Fiierul de intrare conine cteva (cel mult 5) seturi de date, separate prin cte o linie ce conine semnul # Prima linie a fiecrui set de date conine numerele N, M i L (1 N 1000, 0 M 1000, 1 L 2000). Urmeaz N linii ce conin cte 2 numere ntregi xi; yi coordonatele druizilor. Toi druizii se afl n interiorul cmpiei, ori care doi druizi nu coincid. Urmtoarele M linii ale setului de date conin cte un triplet de numere ntregi ai, bi, ci. Numerele corespund coeficienilor ecuaiei aix + biy + ci = 0, care descrie linia
74

energetic i. Nici un druid nu se afl pe o careva linie. Ori care dou linii nu coincid. Valorile ai, bi, ci nu depesc 10000 dup modul. Date de ieire Fiierul de ieire va conine pentru fiecare set de date cuvntul YES dac exist cel puin un sector n care se afl doi sau mai muli druizi, NO, n caz contrar. Fiecare rspuns se va scrie ntr-o linie aparte, n ordinea apariiei seturilor de date n fiierul de intrare. Exemplu
druizi.in 3 2 3 2 2 1 -1 -2 0 1 1 -1 0 1 -1 # 1 0 100 0 0 druizi.out YES NO

Soluie Pentru implementare vor fi definite tipurile i structurile:


type pt=record x,y,a:real; T:char; end; dr=array[1..3003] of pt; var d:dr; n,m,i:integer; int,xint,r,a,b,c,ae,be,ce,de, l1a,l2a,l1b,l2b,l1c,l2c: real;

Pentru citirea i preprocesarea datelor va fi utilizat procedura readdata:


procedure readdata; begin readln(n,m,r); for i:=1 to n do 75

begin readln(d[i].x,d[i].y); d[i].t:='L'; end; for i:=1 to m do begin readln(a,b,c); if i=1 then begin l1a:=a; l1b:=b; l1c:=c; end; if i=2 then begin l2a:=a; l2b:=b; l2c:=c; end; ae:=b*b+a*a; be:=2*b*c; ce:=c*c-a*a*2*r*r; de:=be*be-4*ae*ce; if a<>0 then begin inc(n); d[n].y:=(-be-sqrt(de))/2/ae; d[n].x:=(-b*d[n].y-c)/a; d[n].t:='D'; inc(n); d[n].y:=(-be+sqrt(de))/2/ae; d[n].x:=(-b*d[n].y-c)/a; d[n].t:='D'; end else begin inc(n); d[n].y:=-c/b; d[n].x:=sqrt(2*r*r-c*c/b/b); d[n].t:='D'; inc(n); d[n].y:=d[n-1].y; d[n].x:=-d[n-1].x; d[n].t:='D'; end; end; end; {readdata}

n rezolvare vor fi parcurse urmtoarele etape:

1. Toate liniile se intersecteaz ntr-un punct, care trebuie


determinat. Dac numrul de linii e 0 sau 1, sunt cteva cazuri elementare, care se cerceteaz aparte. Dac numrul de linii e mai mare sau egal cu doi, atunci se
76

folosesc oricare 2 linii pentru a determina coordonatele punctului de intersecie.

2. Druizii se afl n interiorul ptratului cu latura 2L i


centul n originea sistemului de coordonate. Ei se afl i n interiorul cercului cu raza 2L i centrul n originea sistemului de coordonate. Pentru fiecare din liniile energetice se deter-min punctele ei de intersecie cu cercul cu raza 2L i centrul n originea coordonatelor. Aceste puncte se marcheaz aparinnd dreptelor (D) de separare a sectoarelor.

3. Originea sistemului de coordonate se deplaseaz n punctul de intersecie a dreptelor (liniilor energetice). Apoi se trece la coor-donatele polare pentru punctele ce reprezint druizii i inter-seciile liniilor energetice cu cer-cul. (realizare procedura movecenter)
procedure movecenter; begin {se determin punctul de intersectie al dreptelor} if l1a<>0 then begin yint:=(l1c*l2a-l1a*l2c)/(l2b*l1a-l2a*l1b); xint:=(-l1b*yint-l1c)/l1a; end else begin yint:=-l1c/l1b; 77

xint:=(-l2b*yint-l2c)/l2a; end; for i:=1 to n do begin {se transfer originea..} d[i].x:=d[i].x - xint; d[i].y:=d[i].y - yint; { ... si se determin coordonatele polare - unghiul!} if d[i].x<>0 then begin d[i].a:=180/pi*arctan(abs(d[i].y/d[i].x)); if (d[i].x<0) and (d[i].y>0) then d[i].a:=180-d[i].a; if (d[i].x<0) and (d[i].y<=0) then d[i].a:=d[i].a+180; if (d[i].x>0) and (d[i].y<0) then d[i].a:=360-d[i].a; end else begin if d[i].y> 0 then d[i].a:=90; if d[i].y<0 then d[i].a:=270; end; end end; {movecenter}

4. Se sorteaz sistemul de puncte dup creterea unghiului


pe care l formeaz fiecare punct cu axa Ox.

5. Dac dup sortare exist cel puin 2 puncte vecine,


reprezentnd druizi, rezult existena unui sector al cmpiei cu aceeai 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 {se determin pozitia druizilor fata de dreapta} 78

if sarrus(d[3],d[4],d[1])*sarrus(d[3],d[4],d[2]) < 0 then writeln('NO') else writeln('YES'); end; if m>=2 then begin {... si cazul general} movecenter; qsort(d,1,n); vec:=FALSE; for i:=1 to n-1 do if (d[i].t='L') and (d[i+1].t='L') then vec:=TRUE; if vec then writeln('YES') else writeln('NO'); end; end; {solve}

79

Notaii
u uu uu r p1 p2
-

segment orientat (vector) cu originea punctul p1

n
S = { p1 ,..., p N }
S
-

mulimea S, cu elementele p1 ,, pN cardinalul mulimii S incrementarea valorii k cu 1 variabilei k i se atribuie valoarea variabilei m segment cu extremitile a i b. triunghi cu vrfuri n punctele a, b, c diagrama Voronoi pentru mulimea S triangularizarea mulimii S nfurtoarea convex a mulimii S din A rezult B. A este echivalent cu B x aparine X (x nu aparine X) submulimea elementelor x din X, care satisfac condiia Q

k k m

[ a, b ]
Vabc
DV ( S ) T (S ) Q(S ) A B A B x X , x X

{ x X : Q}

A B

A se conine n B (A este submulime a mulimii B)

qsort(A,n) apel al procedurii pentru sortarea structurii de

date A din n elemente.

80

Bibliografie
1. Ammeraal Leen. Programming Principles in Computer Graphics. John Wiley and Sons, 1986. Ammeraal Leen. Computer Graphics for the IBM PC. John Wiley and Sons, 1986. Cerchez Emanuela. Programarea n limbajul C/C++ pentru liceu. Vol III. Polirom, Iai, 2007. Cormen Thomas. Introducere n algoritmi. Agora, Cluj. Foley James, Andries Van Dam. Fundamentals of Interactive Computer Graphics. Addison-Wesley Publishing, 1984. Giumale Cristian. Introducere n analiza algoritmilor. Polirom, Iai, 2004. Sedgewick, Th.; Algorithms in C. Addison Wesley, 2001 Williamson Gill. Combinatorics for Computer Science. Dover publications. New York, 2002. . ++. , , 1997.

2.

3.

4. 5.

6.

7. 8.

9.

10. . . , , 1986. 11. .. . , , 2001.


81

12. . . . , , 1985.

13. , .; , . . . : , 1989.

82

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