Janilabo

border+polygon

Sep 18th, 2013
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.76 KB | None | 0 0
  1. {$loadlib pumbaa.dll}
  2.  
  3. const
  4.   DELAY = 2500; // Delay for drawing detected border points.
  5.  
  6. procedure TPABorder(var TPA: TPointArray);
  7. var
  8.   a: TPointArray;
  9.   b: TBox;
  10.   w, h, c, l, i, o, n, x, y, z: Integer;
  11.   m: T2DIntegerArray;
  12.   d, s: TPoint;
  13.   f: Boolean;
  14. begin
  15.   l := High(TPA);
  16.   if (l > 0) then
  17.   begin
  18.     s := TPA[0];
  19.     b := pp_Box(TPA[0].X, TPA[0].Y, TPA[0].X, TPA[0].Y);
  20.     for i := 1 to l do
  21.     begin
  22.       if (TPA[i].Y < s.Y) then
  23.         s := TPA[i]
  24.       else
  25.         if (TPA[i].Y = s.Y) then
  26.           if (TPA[i].X < s.X) then
  27.             s := TPA[i];
  28.       if (TPA[i].X < b.X1) then
  29.         b.X1 := TPA[i].X
  30.       else
  31.         if (TPA[i].X > b.X2) then
  32.           b.X2 := TPA[i].X;
  33.       if (TPA[i].Y < b.Y1) then
  34.         b.Y1 := TPA[i].Y
  35.       else
  36.         if (TPA[i].Y > b.Y2) then
  37.           b.Y2 := TPA[i].Y;
  38.     end;
  39.     w := ((b.X2 - b.X1) + 1);
  40.     h := ((b.Y2 - b.Y1) + 1);
  41.     pp_Create(-1, w, h, m);
  42.     for i := 0 to l do
  43.       m[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)] := 0;
  44.     SetLength(a, 8);
  45.     a[0] := Point(-1, -1);
  46.     a[1] := Point(0, -1);
  47.     a[2] := Point(1, -1);
  48.     a[3] := Point(1, 0);
  49.     a[4] := Point(1, 1);
  50.     a[5] := Point(0, 1);
  51.     a[6] := Point(-1, 1);
  52.     a[7] := Point(-1, 0);
  53.     c := 5;
  54.     f := False;
  55.     m[(s.X - b.X1)][(s.Y - b.Y1)] := 1;
  56.     TPA[0] := s;
  57.     z := 1;
  58.     repeat
  59.       if (c > 3) then
  60.         c := (c - 4)
  61.       else
  62.         c := (c + 4);
  63.       for i := 0 to 7 do
  64.       begin
  65.         if (c < 7) then
  66.           c := (c + 1)
  67.         else
  68.           c := 0;
  69.         x := ((s.X + a[c].X) - b.X1);
  70.         y := ((s.Y + a[c].Y) - b.Y1);
  71.         if ((x > -1) and (y > -1) and (x < w) and (y < h)) then
  72.           if (m[x][y] > -1) then
  73.           begin
  74.             f := (m[x][y] > 1);
  75.             if not f then
  76.             begin
  77.               m[x][y] := (m[x][y] + 1);
  78.               if (m[x][y] = 1) then
  79.               begin
  80.                 TPA[z].X := (x + b.X1);
  81.                 TPA[z].Y := (y + b.Y1);
  82.                 z := (z + 1);
  83.               end;
  84.               s.X := (x + b.X1);
  85.               s.Y := (y + b.Y1);
  86.             end;
  87.             Break;
  88.           end;
  89.       end;
  90.     until f;
  91.     SetLength(TPA, z);
  92.   end;
  93. end;
  94.  
  95. procedure TPABorders(var TPA: TPointArray);
  96. var
  97.   h, i: Integer;
  98.   a, b: T2DPointArray;
  99. begin
  100.   pp_TPABlob(TPA, sd8ways, a);
  101.   WriteLn(Length(a));
  102.   SetLength(b, Length(a));
  103.   h := High(a);
  104.   for i := 0 to h do
  105.     pp_TPAFromPolygon(a[i], b[i]);
  106.   SetLength(TPA, 0);
  107.   pp_Merge(b, TPA);
  108.   SetLength(b, 0);
  109.   pp_TPABlob(TPA, sd8ways, b);
  110.   h := High(b);
  111.   for i := 0 to h do
  112.     TPABorder(b[i]);
  113.   SetLength(TPA, 0);
  114.   pp_Merge(b, TPA);
  115. end;
  116.  
  117. // V== CODE FOR GENERATING RANDOM SHAPE ==V
  118.  
  119. procedure TPALine(var TPA:TPointArray; P1, P2: TPoint);
  120. var
  121.   dx,dy,step,I,H: Integer;
  122.   rx,ry,x,y: Extended;
  123. begin
  124.   H := Length(TPA);
  125.   if (p1.x = p2.x) and (p2.y = p1.y) then
  126.   begin
  127.     SetLength(TPA, H+1);
  128.     TPA[H] := P1;
  129.     Exit;
  130.   end;
  131.  
  132.   dx := (P2.x - P1.x);
  133.   dy := (P2.y - P1.y);
  134.   if (Abs(dx) > Abs(dy)) then step := Abs(dx)
  135.   else step := Abs(dy);
  136.   SetLength(TPA, (H+step+1));
  137.  
  138.   rx := dx / step;
  139.   ry := dy / step;
  140.   x := P1.x;
  141.   y := P1.y;
  142.  
  143.   TPA[H] := Point(P1.x, P1.y);
  144.   for I:=1 to step do
  145.   begin
  146.     x := x + rx;
  147.     y := y + ry;
  148.     TPA[(H+i)] := Point(Round(x),Round(y));
  149.   end;
  150. end;
  151.  
  152. function lines(TPA:TPointArray; Distance:Integer): TPointArray;
  153. var
  154.   i,h,x,y,lx,hx,ly,hy:Integer;
  155.   Matrix:Array of TBoolArray;
  156.   Area: TBox;
  157.   pt:TPoint;
  158.  
  159. begin
  160.   Area := GetTPABounds(TPA);
  161.   Area.X2 := (Area.X2 - Area.X1) + 1;  //Width
  162.   Area.Y2 := (Area.Y2 - Area.Y1) + 1;  //Height
  163.   H := High(TPA);
  164.  
  165.   SetLength(Matrix, Area.Y2);
  166.   for i:=0 to (Area.Y2-1) do
  167.     SetLength(Matrix[i], Area.X2);
  168.  
  169.   for i:=0 to H do
  170.     Matrix[(TPA[i].y-Area.Y1)][(TPA[i].x-Area.X1)] := True;
  171.  
  172.   for i:=0 to H do
  173.   begin
  174.     pt.x := TPA[i].x-Area.X1;
  175.     pt.y := TPA[i].y-Area.Y1;
  176.     if Matrix[pt.y][pt.x] = True then
  177.     begin
  178.       Matrix[pt.y][pt.x] := False;
  179.       lx := Max(pt.x - Distance, 0);
  180.       hx := Min(pt.x + Distance, Area.X2-1);
  181.       ly := Max(pt.y - Distance, 0);
  182.       hy := Min(pt.y + Distance, Area.Y2-1);
  183.       for x:=lx to hx do
  184.         for y:=ly to hy do
  185.           if Matrix[y][x] = True then
  186.             TPALine(Result, Point((pt.x+Area.X1),(pt.y+Area.y1)), point(x+Area.x1,y+Area.y1));
  187.     end;
  188.   end;
  189.   SetLength(Matrix, 0);
  190. end;
  191.  
  192. function RandomTPA(Amount:Integer; MinX,MinY,MaxX,MaxY:Integer): TPointArray;
  193. var i:Integer;
  194. begin
  195.   SetLength(Result, Amount);
  196.   for i:=0 to Amount-1 do
  197.     Result[i] := Point(RandomRange(MinX, MaxX), RandomRange(MinY, MaxY));
  198. end;
  199.  
  200. procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
  201. var
  202.   a, z, w, h: Integer;
  203. begin
  204.   z := High(TPA);
  205.   if (z > -1) then
  206.   begin
  207.     GetBitmapSize(bmp, w, h);
  208.     for a := 0 to z do
  209.       if ((TPA[a].X >= 0) and (TPA[a].Y >= 0) and (TPA[a].X < w) and (TPA[a].Y < h)) then
  210.         FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
  211.   end;
  212. end;
  213.  
  214. function BuildShape: TPointArray;
  215. var
  216.   shape: TPointArray;
  217. begin
  218.   shape := RandomTPA(500, 50,50, 400,400);
  219.   Result := lines(shape, 15);
  220. end;
  221.  
  222. // ^== CODE FOR GENERATING RANDOM SHAPE ==^
  223.  
  224. procedure Test;
  225. var
  226.   TPA: TPointArray;
  227.   bmp, t, h, i: Integer;
  228. begin
  229.   ClearDebug;
  230.   bmp := CreateBitmap(500, 500);
  231.   DisplayDebugImgWindow(500, 500);
  232.   TPA := BuildShape;
  233.   DrawTPABitmap(bmp, TPA, 5367616);
  234.   DrawBitmapDebugImg(bmp);
  235.   t := GetSystemTime;
  236.   TPABorders(TPA);
  237.   WriteLn('TPABorder took ' + IntToStr(GetSystemTime - t) + ' ms.');
  238.   h := High(TPA);
  239.   Wait(DELAY);
  240.   for i := 0 to h do
  241.   begin
  242.     Wait(0);
  243.     FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 255);
  244.     DrawBitmapDebugImg(bmp);
  245.   end;
  246. end;
  247.  
  248. begin
  249.   Test;
  250. end.
Advertisement
Add Comment
Please, Sign In to add comment