DUzun's Web
Programare, proiecte personale, divertisment

DUzun it's ME
 
\ 09 aprilie 2025, 06:18:15 \  
Conținut

OPolig.pas

x
 
{$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.

arr_d Limba / Language


 


arr_r Login
 
 
Loading...