|
|
Conținut
OPolig.pasx {$N+} unit OPolig; (*----------------------------------------------------------------*) interface uses Types; (*----------------------------------------------------------------*) type TIndici = Word; TPerm = array[TNrElem] of TIndici; PPerm = ^TPerm; TPoligon = object nr: TIndici; {Nr de puncte in P^} P: PTabelPuncte; {Tabelul de puncte} nm: TIndici; {Nr de elemente in m^} m: PPerm; {Tabelul de permutari, folosit pu infasuratoare} lx, ly: TIndici; {Indicii punctelor extreme de minim} hx, hy: TIndici; {Indicii punctelor extreme de maxim} {Initializare si distrugere} constructor Init(size: TIndici); constructor Twin(list: PTabelPuncte; n: TIndici); destructor Done; {Redimensionare} function SetSize(size: TIndici): boolean; function Resize(size: TIndici): boolean; function SetSizeM(size: TIndici): boolean; function ResizeM(size: TIndici): boolean; function Generate(size: TIndici; mx, my: Integer): TIndici; function GenStel(size: TIndici; raz: Integer; c: TPunct): TIndici; function GenConv(size: TIndici; raz: Integer; c: TPunct): TIndici; {Citire/Scriere} function QueryInput(size: TIndici): TIndici; {Dialogul de introducere a coordonatelor} function Input(size: TIndici): TIndici; {Citire de la tastatura} function Output: TIndici; {Afisare pe ecran} function QueryFile: TIndici; {Cere numele fisierului si citeste din el punctele} function QuerySize(size: TIndici): TIndici; {Cere nr de puncte si seteaza acest nr} function LoadFromFile(FileName: string): TIndici; {Citire din fisierul FileName} function SaveToFile(FileName: string): TIndici; {Scriere in fisierul FileName} function SaveMToFile(FileName: string): TIndici; {Scriere infasuratoarea in fisierul FileName} function CopyFromTabel(t: PTabelPuncte; n: TIndici): TIndici; function CopyToTabel(var t: TabelPuncte): TIndici; {t trebuie sa contina suficient spatiu} function CopyMToTabel(var t: TabelPuncte): TIndici; {Transformati} {O(nr)} procedure Center(var g: TPunct); {g - centrul de masa} {O(nr)} function Move(dx, dy: TCoord): TNumber; {Deplaseaza originii in (dx,dy) } {O(nr)} function MoveRel(v: TPunct): TNumber; {Deplaseaza originii sistemului: O -> v } {O(nr)} procedure MoveTo(c: TPunct); {Deplaseaza centrului de masa: G -> c } {O(nr)} procedure Rotate(alfa: TNumber; o: TPunct); {Rotirea cu alfa radiani in jurul punctului o } {O(nr)} procedure RotateGrad(alfa: TNumber; o: TPunct); {Rotirea cu alfa grade in jurul punctului o } {O(NlogN)} function Infasa: TIndici; {Determinarea infasuratoarei convexe in permutarile m (Algoritmul Andrew)} {O(nr)} function Interior(s: TPunct): boolean; {Determina daca punctul s apartine interiorului poligonului} {O(nr)} function InRect(s: TPunct): boolean; {Determina daca punctul s apartine dreptunghiului cadru al poligonului} function Extrem(var l, h: TPunct): boolean; {Determina valorile extreme ale P^ (l - minime, h - maxime)} function AbsExtrem(var e: TPunct): boolean; {Determina valorile absolute extreme ale P^} {Grafica} procedure DrowPoints(color: Integer); procedure DrowPoligon(color: Integer); procedure DrowM(color: Integer); procedure DrowMPoints(color: Integer); procedure DrowRect(color: Integer); procedure FillRect(outCl, inCl: Integer); {Implementare} function GetExtrem: boolean; function GetExtremM: boolean; function IsNilExtrem: boolean; {Verifica daca punctele extreme au fost detectate} procedure NilExtrem; {Sterge indicii punctelor extreme} function IsSimplu: boolean; {Determina daca poligonul este simplu} function OnlyM: TIndici; end; (*----------------------------------------------------------------*) implementation uses CRT, IOGeom, Punct, Poligon, Graph, GrGeom; (*----------------------------------------------------------------*) {Sorteaza elementele p[m[left]..m[right]] dupa permutarile m} procedure QSort_y(p: PTabelPuncte; left, right: TIndici; var m: PPerm); var u, v, j, b: TIndici; procedure sort(e: TIndici); var i: TIndici; begin if b >= e then exit; i := b; j := e; u := m^[(b+e) div 2]; repeat with P^[u] do while (P^[m^[i]].y < y) or ((P^[m^[i]].y = y)and(P^[m^[i]].x < x)) do inc(i); with P^[u] do while (y < P^[m^[j]].y) or ((y = P^[m^[j]].y)and(x < P^[m^[j]].x)) do dec(j); if i<=j then begin v:=m^[i]; m^[i]:=m^[j]; m^[j]:=v; inc(i); dec(j); end; until i>j; sort(j); b := i; sort(e); end; begin b := left; sort(right) end; (*----------------------------------------------------------------*) procedure TPoligon.DrowPoints(color: Integer); begin drow_set_puncte(P^, nr, Color) end; (*----------------------------------------------------------------*) procedure TPoligon.DrowPoligon(color: Integer); begin drow_poligon(P^, nr, Color) end; (*----------------------------------------------------------------*) procedure TPoligon.DrowRect(color: Integer); var l, h: TPunct; begin Extrem(l, h); drow_drept(l, h, color); end; (*----------------------------------------------------------------*) procedure TPoligon.FillRect(outCl, inCl: Integer); var l, h, t: TPunct; delta, u: TNumber; begin if not Extrem(l, h) then Exit; if not GrInited then InitGr(0); AbsExtrem(t); with t do detect_ratio(x, y); delta := 1/Ratio; t.x := l.x; with t do while (x < h.x) do begin y := l.y; while (y < h.y) do begin if Interior(t) then drow_punct(t, inCl) else drow_punct(t, outCl); u := y*Ratio; repeat y := y + delta until Int(u) <> Int(y*Ratio); end; u := x*Ratio; repeat x := x + delta until Int(u) <> Int(x*Ratio); end; end; (*----------------------------------------------------------------*) procedure TPoligon.DrowMPoints(color: Integer); var i: integer; e: TPunct; begin if m = nil then Infasa; if not GrInited then InitGr(0); AbsExtrem(e); with e do detect_ratio(x, y); for i := 0 to nm-1 do drow_punct(p^[m^[i]], color); end; (*----------------------------------------------------------------*) procedure TPoligon.DrowM(color: Integer); var i, j: integer; e: TPunct; begin if m = nil then Infasa; if not GrInited then InitGr(0); SetColor(color); AbsExtrem(e); with e do detect_ratio(x, y); j := nm-1; for i := 0 to nm-1 do begin drow_segment(p^[m^[i]], p^[m^[j]]); j := i; end end; (*----------------------------------------------------------------*) function TPoligon.GetExtrem: boolean; var i: TIndici; begin GetExtrem := false; if nr < 1 then Exit; GetExtrem := true; {Determinam punctele de ordonata si abscisa minima si maxima (P^[lx], P^[ly], P^[hx], P^[hy]) } i := nr - 1; lx := i; ly := lx; hx := lx; hy := hx; while i > 0 do begin dec(i); if P^[i].x < P^[lx].x then lx := i; if P^[i].y < P^[ly].y then ly := i; if P^[hx].x < P^[i].x then hx := i; if P^[hy].y < P^[i].y then hy := i; end; end; (*----------------------------------------------------------------*) function TPoligon.GetExtremM: boolean; var i: TIndici; begin GetExtremM := false; if nm < 1 then Exit; GetExtremM := true; i := nm - 1; lx := m^[i]; ly := lx; hx := lx; hy := hx; while i > 0 do begin dec(i); if P^[m^[i]].x < P^[lx].x then lx := m^[i]; if P^[m^[i]].y < P^[ly].y then ly := m^[i]; if P^[hx].x < P^[m^[i]].x then hx := m^[i]; if P^[hy].y < P^[m^[i]].y then hy := m^[i]; end; end; (*----------------------------------------------------------------*) function TPoligon.Extrem(var l, h: TPunct): boolean; begin if IsNilExtrem and not (GetExtremM or GetExtrem) then Extrem := false else begin l.x := (P^[lx].x); h.x := (P^[hx].x); l.y := (P^[ly].y); h.y := (P^[hy].y); Extrem := true; end; end; (*----------------------------------------------------------------*) function TPoligon.AbsExtrem(var e: TPunct): boolean; var l: TPunct; begin if IsNilExtrem and not (GetExtremM or GetExtrem) then AbsExtrem := false else with e do begin x := abs(P^[lx].x); y := abs(P^[ly].y); with l do begin x := abs(P^[hx].x); y := abs(P^[hy].y); if e.x < x then e.x := x; if e.y < y then e.y := y; end; AbsExtrem := true; end; end; (*----------------------------------------------------------------*) function TPoligon.IsSimplu: boolean; var u, v, i, j: TIndici; begin if nr > 3 then begin v := 0; IsSimplu := false; for u := nr-1 downto 2 do begin j := u-1; for i := u-2 downto 0 do begin if i <> v then if intersect(P^[v], P^[u], P^[j], P^[i]) then Exit; j := i; end; v := u; end; end; IsSimplu := true; end; (*----------------------------------------------------------------*) function TPoligon.Infasa: TIndici; var i, j, u, v, a, b: TIndici; r: TNumber; begin Infasa := 0; if not SetSizeM(nr) then exit; {Alocam spatiu pentru lista de permutari} {1. Determinam punctele de ordonata minima si maxima (P^[ly], P^[hy]) } GetExtrem; {2. Separam P^ in doua submultimi, in functie de pozitia fata de vectorul (P^[a],P^[b])} u := 0; v := nr; {Amplasam punctele de ordonata minima/maxima la capetele listei} m^[u] := ly; {Sfirsitul S1} m^[v] := hy; {Inceputul S2} for i := nr-1 downto 0 do if(i<>ly)and(i<>hy)then begin r := sarrus(P^[ly], P^[hy], P^[i]); {S1} if r > 0 then begin inc(u); m^[u] := i; end else {S2} if r < 0 then begin dec(v); m^[v] := i; end else {Punctele de pe dreapta (P^[a], P^[b]) sunt ignorate (r=0)} end; {Acum P^[m^[0]..m^[u]] = S1, P^[m^[v]..m^[nr]] = S2} {3. Sortarea dupa ordonata} QSort_y(P, 1, u, m); QSort_y(P, v, nr-1, m); {4. Excludem punctele care nu sunt pe infasuratoare} {a. Verificam tripletele formate din S1} m^[u+1] := m^[nr]; {Punctul cu ordonata maxima} a := 0; {Ultimul element din infasuratoare} i := a+1; {Punctul care se verifica} j := i+1; {Un punct oarecare din S1} while i <= u do {Se verifica toate punctele pana la u, inclusiv} begin if sarrus(P^[m^[a]], P^[m^[j]], P^[m^[i]]) > 0 then begin {Miscarea inainte} inc(a); if a <> i then m^[a] := m^[i]; i := j; inc(j); end else {Miscarea inapoi} if a > 0 then begin {Daca nu s-a ajuns la primul element} i := a; dec(a); end else begin {Daca a e primul element, mergem tot inainte} i := j; inc(j); end; end; {b. Verificam tripletele formate din S2} m^[v-1] := m^[0]; {Punctul cu ordonata minima} b := nr; {Ultimul element din infasuratoare} i := b-1; {Punctul care se verifica} j := i-1; {Un punct oarecare din S2} while i >= v do {Se verifica toate punctele pana la v, inclusiv} begin if sarrus(P^[m^[b]], P^[m^[j]], P^[m^[i]]) > 0 then begin {Miscarea inainte} dec(b); if b <> i then m^[b] := m^[i]; i := j; dec(j); end else {Miscarea inapoi} if b < nr then begin {Daca nu s-a ajuns la primul element} i := b; inc(b); end else begin {Daca b e primul element, mergem tot inainte} i := j; dec(j); end; end; {5. Formam solutia: S1 + S2} inc(a); {Nr. nr de elemente din S1} for i := nr downto b do m^[a+nr-i] := m^[i]; dec(b); {Omologul lui a} ResizeM(a + nr - b); Infasa := nm; {Nr. de puncte din infasuratoare} end; (*----------------------------------------------------------------*) procedure TPoligon.Rotate(alfa: TNumber; o: TPunct); {Rotirea cu alfa radiani in jurul punctului c} var c, s: TNumber; i: TIndici; u, v: TCoord; begin if alfa = 0 then exit; c := cos(alfa); s := sin(alfa); i := 0; while i < nr do with P^[i] do begin u := x - o.x; {skimbam originea de coordonate in o} v := y - o.y; x := c * u - s * v + o.x; y := s * u + c * v + o.y; inc(i); end; NilExtrem; {La rotire punctele extreme se skimba} end; (*----------------------------------------------------------------*) procedure TPoligon.RotateGrad(alfa: TNumber; o: TPunct); begin Rotate(alfa*pi/180, o) end; (*----------------------------------------------------------------*) function TPoligon.Move(dx, dy: TCoord): TNumber; var i: TIndici; r: TNumber; begin r := sqrt(sqr(dx)+sqr(dy)); Move := r; if r = 0 then exit; i := 0; while i < nr do with P^[i] do begin x := x + dx; y := y + dy; inc(i); end; end; (*----------------------------------------------------------------*) function TPoligon.MoveRel(v: TPunct): TNumber; begin MoveRel := Move(v.x, v.y) end; {O -> v} (*----------------------------------------------------------------*) procedure TPoligon.MoveTo(c: TPunct); {G -> c} var g: TPunct; begin Center(g); dif_vec(c, c, g); with c do Move(x, y); end; (*----------------------------------------------------------------*) procedure TPoligon.Center(var g: TPunct); var i: TIndici; {g - centrul de masa al poligonului} begin g.x := 0; g.y := 0; i := 0; while i < nr do with P^[i] do begin g.x := g.x + x; g.y := g.y + y; inc(i); end; g.y := g.y / nr; g.x := g.x / nr; end; (*----------------------------------------------------------------*) function TPoligon.SetSize(size: TIndici): boolean; begin if size <> nr then begin Done; GetMem(P, (size+1)*SizeOf(TPunct)); if P = nil then nr := 0 else nr := size; end; SetSize := size = nr; end; (*----------------------------------------------------------------*) function TPoligon.Resize(size: TIndici): boolean; var t: PTabelPuncte; i: TIndici; begin if P = nil then SetSize(size); if size <> nr then begin Resize := false; SetSizeM(0); GetMem(t, (size+1)*SizeOf(TPunct)); if t = nil then exit; if P <> nil then begin if size > nr then i := nr else i := size; while i > 0 do begin dec(i); t^[i] := P^[i]; end; FreeMem(P, (nr+1)*SizeOf(TPunct)); end; P := t; nr := size; if(lx>=nr)or(ly>=nr)or(hx>=nr)or(hy>=nr)then NilExtrem; end; Resize := true; end; (*----------------------------------------------------------------*) function TPoligon.SetSizeM(size: TIndici): boolean; begin if size <> nm then begin if m <> nil then FreeMem(m, (nm+1)*SizeOf(TIndici)); GetMem(m, (size+1)*SizeOf(TIndici)); if m = nil then nm := 0 else nm := size; end; SetSizeM := size = nm; end; (*----------------------------------------------------------------*) function TPoligon.ResizeM(size: TIndici): boolean; var t: PPerm; i: TIndici; begin if size <> nm then begin; ResizeM := false; GetMem(t, (size+1)*SizeOf(TIndici)); if t = nil then exit; if m <> nil then begin if size > nm then i := nm else i := size; while i > 0 do begin dec(i); t^[i] := m^[i]; end; FreeMem(m, (nm+1)*SizeOf(TIndici)); end; m := t; nm := size; end; ResizeM := true; end; (*----------------------------------------------------------------*) function TPoligon.OnlyM: TIndici; var t: PTabelPuncte; i: TIndici; begin if (P <> nil) and (m <> nil) then begin GetMem(t, (nm+1)*SizeOf(TPunct)); i := nm; while i > 0 do begin dec(i); t^[m^[i]] := P^[i]; end; FreeMem(P, (nr+1)*SizeOf(TPunct)); P := t; nr := nm; end; OnlyM := nr; if(lx>=nr)or(ly>=nr)or(hx>=nr)or(hy>=nr)then NilExtrem; end; (*----------------------------------------------------------------*) constructor TPoligon.Init(size: TIndici); begin nr := 0; P := nil; m := nil; if not SetSize(size) then Fail; end; (*----------------------------------------------------------------*) constructor TPoligon.Twin(list: PTabelPuncte; n: TIndici); begin if list = nil then n := 0; Init(n); while n > 0 do begin dec(n); P^[n] := list^[n]; end; end; (*----------------------------------------------------------------*) destructor TPoligon.Done; begin if P <> nil then FreeMem(P, (nr+1)*SizeOf(TPunct)); if m <> nil then FreeMem(m, (nm+1)*SizeOf(TIndici)); nr := 0; P := nil; m := nil; NilExtrem; end; (*----------------------------------------------------------------*) procedure TPoligon.NilExtrem; begin lx := 0; ly := 0; hx := 0; hy := 0; end; function TPoligon.IsNilExtrem: boolean; begin IsNilExtrem := lx or ly or hx or hy = 0; end; (*----------------------------------------------------------------*) function TPoligon.QueryInput(size: TIndici): TIndici; {Dialogul de introducere a coordonatelor} var s: string; r: TNumber; v: boolean; begin PauseGr; v := true; repeat if not v then writeln('Optiune invalida! Mai incearca o data...'+endl); writeln; writeln('Alege o optiune prin tastarea literei corespunzatoare:'+endl); writeln(' I: Introducerea coordonatelor manual (implicit)'+endl + ' F: Citirea din fisier'+endl + ' G: Generarea unei multimi aleatoare de puncte'+endl + ' S: Generarea unui poligon stelat'+endl + ' C: Generarea unui poligon convex'+endl); case UpCase(ReadKey) of 'I': Input(size); 'F': QueryFile; 'G': begin write('Raza: '); readln(r); Generate(size, abs(Trunc(r)), abs(Trunc(r))) end; 'S': begin write('Raza: '); readln(r); GenStel(size, abs(Trunc(r)), ZeroP) end; 'C': begin write('Raza: '); readln(r); GenConv(size, abs(Trunc(r)), ZeroP) end; else v := false; end; clrscr; until v; ResumeGr; end; (*----------------------------------------------------------------*) function TPoligon.QueryFile: TIndici; {Cere numele fisierului si citeste din el punctele} var s: string; begin QueryFile := 0; s := ''; repeat if s <> '' then writeln('Fisierul "' + s + '" nu e valid!'); write('Nume fisier: '); readln(s); until (s = '') or (LoadFromFile(s) <> 0); QueryFile := nr; end; (*----------------------------------------------------------------*) function TPoligon.QuerySize(size: TIndici): TIndici; {Cere nr de puncte si seteaza acest nr} begin if(size = 0) then begin writeln; writeln('Introdu nr de puncte: '); readln(size); end; while not SetSize(size) do dec(size); writeln('Spatiu alocat petru ', size, ' puncte!'); QuerySize := nr; end; (*----------------------------------------------------------------*) function TPoligon.Input(size: TIndici): TIndici; var i: TIndici; begin PauseGr; QuerySize(size); i := 0; while i < nr do with P^[i] do begin write('p[',i,'](x,y): '); readln(x, y); inc(i); end; Input := nr; ResumeGr; end; (*----------------------------------------------------------------*) function TPoligon.Output: TIndici; var i: TIndici; begin PauseGr; writeln; i := 0; while i < nr do with P^[i] do begin writeln('p',i,'(x, y): (', x:8:2, ',', y:8:2,')'); inc(i); if i mod WindMax = 0 then readkey; end; Output := nr; ResumeGr; end; (*----------------------------------------------------------------*) function TPoligon.LoadFromFile(FileName: string): TIndici; var f: text; l, c: ListPuncte; i: TIndici; begin LoadFromFile := 0; if not open_file(f, FileName, 'r') then exit; Done; {Stergem punctele existente} new(l); {Cream lista de puncte} c := l; i := 0; while(not eof(f))do begin {Citirea punctelor din fisier} with c^.p do readln(f, x, y); new(c^.urm); c := c^.urm; inc(i); end; c^.urm := nil; Close(f); SetSize(i); c := l; i := 0; while c^.urm <> nil do begin {Transferul din lista in tabel} P^[i] := c^.p; c := c^.urm; Dispose(l); l := c; inc(i); end; Dispose(l); LoadFromFile := nr; {Nr de puncte citite} end; (*----------------------------------------------------------------*) function TPoligon.SaveToFile(FileName: string): TIndici; var f: text; i: TIndici; begin SaveToFile := 0; if (P=nil)or(nr=0) or not open_file(f, FileName, 'w') then exit; for i := 0 to nr-1 do with P^[i] do writeln(f, x:8:2,' ',y:8:2); close(f); SaveToFile := nr-1; end; (*----------------------------------------------------------------*) function TPoligon.SaveMToFile(FileName: string): TIndici; var f: text; i: TIndici; begin if m = nil then Infasa; SaveMToFile := 0; if (m=nil)or(nm=0) or not open_file(f, FileName, 'w') then exit; for i := 0 to nm-1 do with P^[m^[i]] do writeln(f, x:8:2,' ',y:8:2); close(f); SaveMToFile := nm-1; end; (*----------------------------------------------------------------*) function TPoligon.CopyToTabel(var t: TabelPuncte): TIndici; var i: TIndici; begin if P = nil then CopyToTabel := 0 else begin CopyToTabel := nr; i := nr; while i > 0 do begin dec(i); t[i] := P^[i]; end; end; end; (*----------------------------------------------------------------*) function TPoligon.CopyMToTabel(var t: TabelPuncte): TIndici; var i: TIndici; begin if (m = nil)and(Infasa = 0) then CopyMToTabel := 0 else begin CopyMToTabel := nm; i := nm; while i > 0 do begin dec(i); t[i] := P^[m^[i]]; end; end; end; (*----------------------------------------------------------------*) function TPoligon.CopyFromTabel(t: PTabelPuncte; n: TIndici): TIndici; begin if t = nil then n := 0; Resize(n); while n > 0 do begin dec(n); P^[n] := t^[n]; end; end; (*----------------------------------------------------------------*) function TPoligon.Generate(size: TIndici; mx, my: Integer): TIndici; begin Generate := QuerySize(size); size := nr; while size > 0 do begin dec(size); with P^[size] do begin x := random(2*mx)-mx; y := random(2*my)-my; end; end; end; (*----------------------------------------------------------------*) function TPoligon.GenStel(size: TIndici; raz: Integer; c: TPunct): TIndici; var pas: TNumber; t: TPunct; begin GenStel := 0; repeat QuerySize(size); size := 0; until nr > 3; P^[nr] := c; pas := 2 * pi / nr; {Pasul unghiular mediu de la un varf la altul} size := nr; while size > 0 do with t do begin dec(size); x := raz * 0.1 + rand_real(raz * 0.9); {ro} y := size * pas + rand_real(pas); {fi} cartez_punct(t, t); {Trecem la coordonate carteziene} sum_vec(P^[size], t, c); {Transformam punctul in sistemul de coordonate cu centrul c} end; GenStel := nr; end; (*----------------------------------------------------------------*) function TPoligon.GenConv(size: TIndici; raz: Integer; c: TPunct): TIndici; var lat, pas: TNumber; t: TPunct; u, v: TNumber; begin GenConv := 0; repeat QuerySize(size); size := 0; until nr > 3; { gen_puncte(p, nr, max_x, max_y); gen_polig_conv := Infasa(p, p, nr); } u := pi * (nr-2) / nr; {Unghiul poligonului regulat cu nr laturi} lat := (raz) * sqrt(2*(1-cos(u))); {Latura poligonului regulat de raza raz} pas := pi - u; P^[0] := ZeroP; P^[1].x := rand_real(lat)+1; P^[1].y := rand_real(lat)+1; with P^[1] do v := ArcTan2(y, x); for size := 2 to nr-1 do with t do begin y := abs(u - unghi_puncte(P^[size-2], P^[size-1], P^[0])); if pas < y then y := pas; y := v - M_PI + u + (rand_real(2*y)-y); {fi} x := lat / 10 + rand_real(lat - lat / 10); {ro} v := y; cartez_punct(t, t); {Obtinem coordonatele carteziene} sum_vec(P^[size], P^[size-1], t); {Apmlasam varful la locul sau, dupa varful precedent} end; Infasa; {Pentru orice eventualitate determinam infasuratoarea convexa} for size := 0 to nm-1 do P^[size] := P^[m^[size]]; Resize(nm); MoveTo(c); GenConv := nr; end; (*----------------------------------------------------------------*) function TPoligon.InRect(s: TPunct): boolean; begin if IsNilExtrem and not (GetExtremM or GetExtrem) then InRect := false else with s do InRect := (P^[lx].x < x)and(x < P^[hx].x)and(y < P^[ly].y)and(y < P^[hy].y) end; (*----------------------------------------------------------------*) function TPoligon.Interior(s: TPunct): boolean; var i, j, k: integer; t, u, v: TCoord; begin Interior := false; if IsNilExtrem then Interior := true; { Fie l dreapta ce trece prin s, paralela la Ox } k := 0; {Numarul de intersectii cu dreapta l la stanga lui s} j := 0; {Ultimul punct analizat} u := P^[j].y - s.y; {Ultima ordonata care nu se afla pe l} for i := nr-1 downto 0 do with P^[i] do begin if y = s.y then {P^[i] se afla pe l} if (P^[j].y = s.y) and intre_val(s.x, P^[j].x, x) then Exit else {s se afla pe latura P^[j]P^[i]} else begin {P^[i] nu se afla pe l} v := y - s.y; if u*v < 0 then begin {Domeniul a fost intersectat de dreapta l} if P^[j].y = s.y then t := P^[j].x {intersectat intr-un varf al poligonului} else t := x + (P^[j].x-x)*(s.y-y)/(P^[j].y-y); {intersectat pe o latura a poligonului} {t este abscisa punctului de intersectie cu l} with s do if t < x then inc(k) {Daca a fost intersectat la stanga de s} else if t = x then Exit; {s se afla pe latura P^[j]P^[i]} end; u := v; end; j := i; end; Interior := k and 1 <> 0; end; (*----------------------------------------------------------------*) (*----------------------------------------------------------------*) begin randomize; end. Aici acumulez programe şi algoritmi interesanti alcătuiţi de mine (cu mici excepţii) pe parcursul studierii unor limbaje de programare. Cea mai mare parte din ele sunt realizate în Pascal. Nu am scopul creării unui curs specializat sau a descrierii detaliate a anumitor limbaje, ci doar prezint informaţii utile, plus ceva exemple interesante...
Răsfoitorul de fișiere (File Browser):Codul sursă al programelor este organizat în mape şi fişiere. Paginile care conțin cod sursă de programe de regulă au un răsfoitor de fișiere în partea stangă a paginii reprezentat de un bloc cu titlul „File Browser”. Pentru a vizualiza un program sau conţinutul unei mape, faceţi click pe numele fişierului / mapei. Dacă fişierul nu este textual, el se va descărca automat, iar dacă este textual, conținutul lui se va afișa într-un bloc pe centrul paginii. Pentru a descărca un fişier, faceţi click pe dimensiunea (size) lui.
Căutare
|