Janilabo

borders

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