debstats est un utilitaire pour debian qui permet de faire un diagnostic des paquets installés sur un tel système en donnant quelques statistiques. Il est écrit en perl et disponible ici : (html |texte).
Voici une exemple de rendu de ce script dans un terminal :
$ debstats ----- Priority Size(Mo) Packages standard 145 87 required 48 50 extra 23 19 optional 1155 744 important 31 60 ------ Section Size(Mo) Packages games 3.75 4 otherosfs 8 6 oldlibs 2.44 10 net 17 40 web 46 11 interpreters 6 4 x11 157 46 contrib/misc 0.07 1 text 56 33 doc 58 28 devel 111 42 libdevel 94 81 mail 7 9 sound 10 15 base 109 56 admin 27 27 python 30 23 math 28 5 utils 22 38 libs 218 349 shells 1.41 2 perl 28 25 graphics 60 17 gnome 232 62 misc 19 17 editors 41 8 non-free/utils 0.17 1 -------- Total 1403 960
Cette unité écrite en Pascal propose une classe objet pour trouver des points remarquables d'un polygone comme : le centre de gravite, l'isobarycentre, le point isolé...
Elle est téléchargeable ici : Polygones.pas
// This unit give several features to work on polygons such as // found particular points of the polygon. // Copyright (C) 2005 Pierre Chignac aka peyo // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. This program // is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. You should have received a copy of the GNU // General Public License along with this program; if not, write to the // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. unit Polygones; interface uses Classes, SysUtils, Math; type _Ppoint = ^poly_point; poly_point = record x,y : real; next : _Ppoint; island : integer; end; TPolygone = class(TObject) public id : string; count : integer; private first_item : _Ppoint; last_item: _Ppoint; maxx, maxy, minx, miny : real; public constructor Create; destructor Destroy;override; // ajoute un point au polygone procedure AddItem(x,y:real); // calcule la surface du ploygone function Surface : real; // trouvre les coordonées du centre de gravité function centre_gravite : poly_point; // pareil pour l'isobarycentre function isoberycentre : poly_point; // et le point isolé function point_isole(epsilon : integer) : poly_point; // retire tous les points d'un polygone procedure Clear; private function Item(index : integer) : _Ppoint; // renvoie l'abscisse du ième point function x(index : integer) : real; // renvoie l'ordonnée du ième point function y(index : integer) : real; //inverse la description du polygone par ses points procedure Reverse; //renvoie 1 si le polynome est décrit dans le sens trigo positif, 0 sinon function sens_trigo : boolean; //renvoie 1 si p est dans le polynome, 0 sinon function inclus(p : poly_point) : boolean; //renvoie la distance de p a un polygone; function distance(p : poly_point) : real; procedure DeleteItem(index : integer); end; implementation //========================================================================== // renvoie la disantance Euclidienne entre deux points A & B function distance_point_point(xa,ya,xb,yb : real) : real; begin result:=sqrt(sqr(xa-xb)+sqr(ya-yb)); end; //========================================================================== function distance_point_segment(xp,yp,xa,ya,xb,yb : real) : real; var tmp, xo, yo, lambda : real; begin Result:=-1; //--------------------segment vertical------------------ if xa=xb then begin // 1 - le point est sur la droite if xp=xa then begin if ((yp<=max(ya,yb)) and (yp>=min(ya,yb))) then result:=0 else result:=min(abs(yp-ya),abs(yp-yb)); exit; end // 2 - le point n'est pas sur la droite else begin if ((yp<=max(ya,yb)) and (yp>=min(ya,yb))) then result:=abs(xa-xp) else result:=min(distance_point_point(xp,yp,xa,ya),distance_point_point(xp,yp,xb,yb)); exit; end; end;//seg vert //--------------------segment horizontal------------------ if ya=yb then begin // 1 - le point est sur la droite if yp=ya then begin if ((xp<=max(xa,xb)) and (xp>=min(xa,xb))) then result:=0 else result:=min(abs(xp-xa),abs(xp-xb)); exit; end // 2 - le point n'est pas sur la droite else begin if ((xp<=max(xa,xb)) and (xp>=min(xa,xb))) then result:=abs(ya-yp) else result:=min(distance_point_point(xp,yp,xa,ya),distance_point_point(xp,yp,xb,yb)); exit; end; end;//seg hor //--------------------segment quelconque------------------ if xa>xb then begin tmp:=xa;xa:=xb;xb:=tmp; tmp:=ya;ya:=yb;yb:=tmp; end; //lambda = coefficient directeur de la droite (AB) lambda:=(ya-yb)/(xa-xb); // O de coordonnées (xo,yo) est le projeté orthogonal // de P sur la droite (AB) xo:=(lambda*xa-ya+1/lambda*xp+yp)/(lambda+1/lambda); yo:=-1/lambda*(xo-xp)+yp; //si O est sur le segment [AB] alors la distance de P à [AB] est OP if ((xo>xa)and(xo<xb)) then result:=distance_point_point(xp,yp,xo,yo) //sinon c'est la plus petite distance de P aux extrémités du segment else result:=min(distance_point_point(xp,yp,xa,ya),distance_point_point(xp,yp,xb,yb)); //----------------------------------------------------------- end; //========================================================================== constructor TPolygone.Create; begin inherited create; count:=0; first_item:=Nil; last_item:=Nil; end; //========================================================================== destructor TPolygone.Destroy; var i : integer; tmp_item : _Ppoint; del_item : _Ppoint; begin if count > 0 then begin tmp_item := first_item.next; del_item:=first_item; for i := 1 to count-1 do begin freemem(del_item); del_item:=tmp_item; tmp_item:=tmp_item.next; end; freemem(tmp_item); count:=0; first_item:=Nil; last_item:=Nil; end; inherited Destroy; end; //========================================================================== function TPolygone.Surface : real; var i : integer; mx, my : real; tmp_item : _Ppoint; begin tmp_item := first_item; mx:=minx; my:=miny; for i := 0 to count-1 do begin tmp_item.x:=tmp_item.x-mx+10; tmp_item.y:=tmp_item.y-my+10; if tmp_item.next<>Nil then tmp_item:=tmp_item.next; end; tmp_item:=first_item; case count of 1 : Result := -1; 2 : Result := -2; else begin Result:=0; repeat begin Result:=Result+ ((tmp_item.x-minx)+(tmp_item.next.x-minx))* ((tmp_item.next.y-miny)-(tmp_item.y-miny)); tmp_item:=tmp_item.next end; until tmp_item.next=Nil; Result:=Result/2; end; end; tmp_item := first_item; for i := 0 to count-1 do begin tmp_item.x:=tmp_item.x+mx-10; tmp_item.y:=tmp_item.y+my-10; if tmp_item.next<>Nil then tmp_item:=tmp_item.next; end; end; //========================================================================== function TPolygone.isoberycentre : poly_point; var i : integer; begin result.x:=0; result.y:=0; for i := 1 to count-1 do begin result.x:=result.x+x(i-1); result.y:=result.y+y(i-1); end; result.x:=result.x/(count-1); result.y:=result.y/(count-1); end; //========================================================================== function TPolygone.inclus(p : poly_point) : boolean; var i, n_coupes :integer; xa, ya, xb, yb: real; _A, _B : _Ppoint; begin result:=false; _A:=first_item; n_coupes:=0; for i := 0 to count-2 do begin _B:=_A.next; //mettre A à gauche et B à droite if _A.x<_B.x then begin xa:=_A.x; ya:=_A.y; xb:=_B.x; yb:=_B.y; end else begin xa:=_B.x; ya:=_B.y; xb:=_A.x; yb:=_A.y; end; //vérifier l'intersection if ((xa=p.x) or (xb=p.x)) then p.x:=p.x+p.x/10000000000; if ( (xa<>xb) and (xa<p.x) and (xb>p.x) and ((ya-yb)/(xa-xb)*(p.x-xb)+yb > p.y) ) then inc(n_coupes); //initialiser le segment suivant _A:=_A.next; end; if n_coupes mod 2 = 0 then result:=false else result:=true; end; //========================================================================== function TPolygone.distance(p : poly_point) : real; var i:integer; tmp:real; _A, _B : _Ppoint; begin _A:=first_item; _B:=_A.next; result:=distance_point_segment(p.x,p.y,_A.x,_A.y,_B.x,_B.y); for i := 0 to count-2 do begin _B:=_A.next; tmp:=distance_point_segment(p.x,p.y,_A.x,_A.y,_B.x,_B.y); if tmp < result then result:=tmp; _A:=_A.next; end; end; //========================================================================== function TPolygone.point_isole(epsilon : integer) : poly_point; var i, j : integer; meilleur_distance : real; tmp : real; test : poly_point; tutu, titi : tstringlist; begin // tutu:=tstringlist.create; // titi:=tstringlist.create; // tutu.loadfromfile('D:/home/Delphi_Projects/polygones/data/ilots_insee/ilots_light/test.mif'); // titi.loadfromfile('D:/home/Delphi_Projects/polygones/data/ilots_insee/ilots_light/test.mid'); meilleur_distance:=0; for i := 1 to epsilon-1 do begin test.x:=minx+i*((maxx-minx)/epsilon); for j := 1 to epsilon-1 do begin test.y:=miny+j*((maxy-miny)/epsilon); if inclus(test) then begin tmp:=distance(test); // tutu.Add('point '+floattostr(test.x)+' '+floattostr(test.y)); // titi.add('"'+floattostr(tmp)+'"'); if tmp>meilleur_distance then begin meilleur_distance:=tmp; result.x:=test.x; result.y:=test.y; end; end; end; end; // tutu.savetofile('D:/home/Delphi_Projects/polygones/data/ilots_insee/ilots_light/test.mif'); // titi.savetofile('D:/home/Delphi_Projects/polygones/data/ilots_insee/ilots_light/test.mid'); end; //========================================================================== function TPolygone.centre_gravite: poly_point; var i : integer; p : poly_point; mx, my : real; tmp_item : _Ppoint; begin tmp_item := first_item; p.x:=0; p.y:=0; mx:=minx; my:=miny; for i := 0 to count-1 do begin tmp_item.x:=tmp_item.x-mx+10; tmp_item.y:=tmp_item.y-my+10; if tmp_item.next<>Nil then tmp_item:=tmp_item.next; end; for i := 1 to count-1 do begin p.x:=p.x+(y(i)-y(i-1))*(x(i)*x(i)+x(i)*x(i-1)+x(i-1)*x(i-1)); p.y:=p.y+(x(i-1)-x(i))*(y(i)*y(i)+y(i)*y(i-1)+y(i-1)*y(i-1)); end; p.x:=p.x/(6*surface); p.y:=p.y/(6*surface); if (p.x<0) and (p.y<0) then begin p.x:=p.x*(-1); p.y:=p.y*(-1); end; p.x:=p.x+mx-10; p.y:=p.y+my-10; tmp_item := first_item; for i := 0 to count-1 do begin tmp_item.x:=tmp_item.x+mx-10; tmp_item.y:=tmp_item.y+my-10; if tmp_item.next<>Nil then tmp_item:=tmp_item.next; end; result:=p; end; //========================================================================== function TPolygone.x(index : integer) : real; var i : integer; tmp_item : _Ppoint; begin tmp_item := first_item; if index > 0 then for i := 1 to index do tmp_item:=tmp_item.next; result:=tmp_item.x; end; //========================================================================== function TPolygone.y(index : integer) : real; var i : integer; tmp_item : _Ppoint; begin tmp_item := first_item; if index > 0 then for i := 1 to index do tmp_item:=tmp_item.next; result:=tmp_item.y; end; //========================================================================== procedure TPolygone.Clear; var i : integer; begin for i := 0 to count-1 do DeleteItem(0); end; //========================================================================== procedure TPolygone.AddItem(x,y:real); var tmp_item : _Ppoint; begin tmp_item:=allocmem(sizeof(poly_point)); tmp_item.x:=x; tmp_item.y:=y; tmp_item.next:=Nil; if count=0 then begin minx:=x;miny:=y;maxx:=x;maxy:=y; first_item:=tmp_item end else begin if x<minx then minx:=x; if x>maxx then maxx:=x; if y<miny then miny:=y; if y>maxy then maxy:=y; last_item.next:=tmp_item; end; last_item:=tmp_item; inc(count); end; //========================================================================== procedure TPolygone.DeleteItem(index : integer); var i : integer; tmp_item, tmp_item2 : _Ppoint; begin tmp_item:=first_item; case count of 0 : exit; 1 : begin if index =0 then begin first_item:=nil; last_item:=nil; end; end;//fin case count =1 2 : begin case index of 0 : first_item:=last_item; 1 : begin tmp_item:=last_item; last_item:=first_item; first_item.next:=nil; end; end; end;//fin case count = 2 else begin case index of 0 : first_item:=first_item.next; 1 : begin tmp_item:=first_item.next; first_item.next:=first_item.next.next; end; else begin for i := 0 to index-2 do tmp_item:=tmp_item.next; if tmp_item.next.next=nil then begin last_item:=tmp_item; tmp_item:=tmp_item.next; last_item.next:=nil; end else begin tmp_item2:=tmp_item.next; tmp_item.next:=tmp_item.next.next; tmp_item:=tmp_item2; end; end; end; end;//fin case count else end; freemem(tmp_item); dec(count); end; //========================================================================== function TPolygone.Item(index : integer) : _Ppoint; var i : integer; tmp_item : _Ppoint; begin tmp_item := first_item; if index > 0 then for i := 1 to index do tmp_item:=tmp_item.next; result:=tmp_item; end; //========================================================================== function TPolygone.sens_trigo : boolean; begin if surface>0 then Result := True else Result:=False; end; //========================================================================== procedure TPolygone.Reverse; var i : integer; tmp_x, tmp_y : real; begin for i := 0 to floor(count/2)-1 do begin tmp_x:=x(i); tmp_y:=y(i); Item(i).x:=x(count-i-1); Item(i).y:=y(count-i-1); Item(count-i-1).x:=tmp_x; Item(count-i-1).y:=tmp_y; end; end; //========================================================================== end.