Janilabo

border tracing

Sep 18th, 2013
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.31 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. // V== CODE FOR GENERATING RANDOM SHAPE ==V
  96.  
  97. procedure TPALine(var TPA:TPointArray; P1, P2: TPoint);
  98. var
  99.   dx,dy,step,I,H: Integer;
  100.   rx,ry,x,y: Extended;
  101. begin
  102.   H := Length(TPA);
  103.   if (p1.x = p2.x) and (p2.y = p1.y) then
  104.   begin
  105.     SetLength(TPA, H+1);
  106.     TPA[H] := P1;
  107.     Exit;
  108.   end;
  109.  
  110.   dx := (P2.x - P1.x);
  111.   dy := (P2.y - P1.y);
  112.   if (Abs(dx) > Abs(dy)) then step := Abs(dx)
  113.   else step := Abs(dy);
  114.   SetLength(TPA, (H+step+1));
  115.  
  116.   rx := dx / step;
  117.   ry := dy / step;
  118.   x := P1.x;
  119.   y := P1.y;
  120.  
  121.   TPA[H] := Point(P1.x, P1.y);
  122.   for I:=1 to step do
  123.   begin
  124.     x := x + rx;
  125.     y := y + ry;
  126.     TPA[(H+i)] := Point(Round(x),Round(y));
  127.   end;
  128. end;
  129.  
  130. function lines(TPA:TPointArray; Distance:Integer): TPointArray;
  131. var
  132.   i,h,x,y,lx,hx,ly,hy:Integer;
  133.   Matrix:Array of TBoolArray;
  134.   Area: TBox;
  135.   pt:TPoint;
  136.  
  137. begin
  138.   Area := GetTPABounds(TPA);
  139.   Area.X2 := (Area.X2 - Area.X1) + 1;  //Width
  140.   Area.Y2 := (Area.Y2 - Area.Y1) + 1;  //Height
  141.   H := High(TPA);
  142.  
  143.   SetLength(Matrix, Area.Y2);
  144.   for i:=0 to (Area.Y2-1) do
  145.     SetLength(Matrix[i], Area.X2);
  146.  
  147.   for i:=0 to H do
  148.     Matrix[(TPA[i].y-Area.Y1)][(TPA[i].x-Area.X1)] := True;
  149.  
  150.   for i:=0 to H do
  151.   begin
  152.     pt.x := TPA[i].x-Area.X1;
  153.     pt.y := TPA[i].y-Area.Y1;
  154.     if Matrix[pt.y][pt.x] = True then
  155.     begin
  156.       Matrix[pt.y][pt.x] := False;
  157.       lx := Max(pt.x - Distance, 0);
  158.       hx := Min(pt.x + Distance, Area.X2-1);
  159.       ly := Max(pt.y - Distance, 0);
  160.       hy := Min(pt.y + Distance, Area.Y2-1);
  161.       for x:=lx to hx do
  162.         for y:=ly to hy do
  163.           if Matrix[y][x] = True then
  164.             TPALine(Result, Point((pt.x+Area.X1),(pt.y+Area.y1)), point(x+Area.x1,y+Area.y1));
  165.     end;
  166.   end;
  167.   SetLength(Matrix, 0);
  168. end;
  169.  
  170. function RandomTPA(Amount:Integer; MinX,MinY,MaxX,MaxY:Integer): TPointArray;
  171. var i:Integer;
  172. begin
  173.   SetLength(Result, Amount);
  174.   for i:=0 to Amount-1 do
  175.     Result[i] := Point(RandomRange(MinX, MaxX), RandomRange(MinY, MaxY));
  176. end;
  177.  
  178. procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
  179. var
  180.   a, z, w, h: Integer;
  181. begin
  182.   z := High(TPA);
  183.   if (z > -1) then
  184.   begin
  185.     GetBitmapSize(bmp, w, h);
  186.     for a := 0 to z do
  187.       if ((TPA[a].X >= 0) and (TPA[a].Y >= 0) and (TPA[a].X < w) and (TPA[a].Y < h)) then
  188.         FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
  189.   end;
  190. end;
  191.  
  192. function BuildShape: TPointArray;
  193. var
  194.   shape: TPointArray;
  195. begin
  196.   shape := RandomTPA(50, 50,50, 250,250);
  197.   Result := lines(shape, 100);
  198. end;
  199.  
  200. // ^== CODE FOR GENERATING RANDOM SHAPE ==^
  201.  
  202. procedure Test;
  203. var
  204.   TPA: TPointArray;
  205.   bmp, t, h, i: Integer;
  206. begin
  207.   ClearDebug;
  208.   bmp := CreateBitmap(500, 500);
  209.   DisplayDebugImgWindow(500, 500);
  210.   TPA := BuildShape;
  211.   DrawTPABitmap(bmp, TPA, 5367616);
  212.   DrawBitmapDebugImg(bmp);
  213.   t := GetSystemTime;
  214.   TPABorder(TPA);
  215.   WriteLn('TPABorder took ' + IntToStr(GetSystemTime - t) + ' ms.');
  216.   h := High(TPA);
  217.   Wait(DELAY);
  218.   for i := 0 to h do
  219.   begin
  220.     Wait(0);
  221.     FastSetPixel(bmp, TPA[i].X, TPA[i].Y, 255);
  222.     DrawBitmapDebugImg(bmp);
  223.   end;
  224. end;
  225.  
  226. begin
  227.   Test;
  228. end.
Advertisement
Add Comment
Please, Sign In to add comment