Janilabo

Untitled

Sep 13th, 2013
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 4.48 KB | None | 0 0
  1. function TPABounds(TPA: TPointArray): TBox;
  2. var
  3.   h, i: Integer;
  4. begin
  5.   h := High(TPA);
  6.   if (h > -1) then
  7.   begin
  8.     Result.X1 := TPA[0].X; Result.X2 := TPA[0].X;
  9.     Result.Y2 := TPA[0].Y; Result.Y2 := TPA[0].Y;
  10.     if (h > 0) then
  11.     for i := 1 to h do
  12.     begin
  13.       if (TPA[i].X < Result.X1) then
  14.         Result.X1 := TPA[i].X
  15.       else if (TPA[i].X > Result.X2) then
  16.         Result.X2 := TPA[i].X;
  17.       if (TPA[i].Y < Result.Y1) then
  18.         Result.Y1 := TPA[i].Y
  19.       else if (TPA[i].Y > Result.Y2) then
  20.         Result.Y2 := TPA[i].Y;
  21.     end;
  22.   end;
  23. end;
  24.  
  25. procedure ConvexHull(var TPA: TPointArray);
  26. var
  27.   p, Lower: TPointArray;
  28.   LH, H, I, UH, c, j, idx, x, y: Integer;
  29.   area: TBox;
  30.   m: array of TBoolArray;
  31.   b: Boolean;
  32. begin
  33.   h := High(TPA);
  34.   if (h > 0) then
  35.   begin
  36.     area := TPABounds(TPA); // Replace with GetTPABounds ...
  37.     SetLength(m, ((area.Y2 - area.Y1) + 1));
  38.     for i := 0 to area.y2 do
  39.       SetLength(m[i], ((area.X2 - area.X1) + 1));
  40.     C := 0;
  41.     for i := 0 to h do
  42.     begin
  43.       x := (TPA[i].X - area.X1);
  44.       y := (TPA[i].Y - area.Y1);
  45.       if m[y][x] then
  46.         Continue;
  47.       m[y][x] := True;
  48.       Inc(C);
  49.     end;
  50.     SetLength(p, C);
  51.     idx := 0;
  52.     b := False;
  53.     for x := area.X1 to area.X2 do
  54.     begin
  55.       for y := area.Y1 to area.Y2 do
  56.         if m[(y - area.Y1)][(x - area.X1)] then
  57.         begin
  58.           p[idx] := Point(x, y);
  59.           Inc(idx);
  60.           b := (idx >= C);
  61.           if b then
  62.             Break;
  63.         end;
  64.       if b then
  65.         Break;
  66.     end;
  67.     h := High(p);
  68.     if (h > 0) then
  69.     begin
  70.       UH := 2;
  71.       SetLength(TPA, (h + 1));
  72.       TPA[0] := p[0];
  73.       TPA[1] := p[1];
  74.       for i := 2 to h do
  75.       begin
  76.         TPA[UH] := p[i];
  77.         Inc(UH);
  78.         while ((UH > 2) and not (((TPA[(UH - 2)].x * TPA[(UH - 1)].y + TPA[(UH - 3)].x * TPA[(UH - 2)].y + TPA[(UH - 1)].x * TPA[(UH - 3)].y) - (TPA[(UH - 2)].x * TPA[(UH - 3)].y + TPA[(UH - 1)].x * TPA[(UH - 2)].y + TPA[(UH - 3)].x * TPA[(UH - 1)].y)) < 0)) do
  79.         begin
  80.           Dec(UH);
  81.           TPA[(UH - 1)] := TPA[UH];
  82.         end;
  83.       end;
  84.       LH := 2;
  85.       SetLength(Lower, (h + 1));
  86.       Lower[0] := p[h];
  87.       Lower[1] := p[(h - 1)];
  88.       for i := 2 to h do
  89.       begin
  90.         Lower[LH] := p[(h - i)];
  91.         Inc(LH);
  92.         while ((LH > 2) and not (((Lower[(LH - 2)].x * Lower[(LH - 1)].y + Lower[(LH - 3)].x * Lower[(LH - 2)].y + Lower[(LH - 1)].x * Lower[(LH - 3)].y) - (Lower[(LH - 2)].x * Lower[(LH - 3)].y + Lower[(LH - 1)].x * Lower[(LH - 2)].y + Lower[(LH - 3)].x * Lower[(LH - 1)].y)) < 0)) do
  93.         begin
  94.           Dec(LH);
  95.           Lower[(LH - 1)] := Lower[LH];
  96.         end;
  97.       end;
  98.       Dec(LH);
  99.       SetLength(TPA, (UH + LH));
  100.       for i := UH to ((UH + LH) - 1) do
  101.         TPA[i] := Lower[(i - UH)];
  102.     end;
  103.   end;
  104. end;
  105.  
  106. function SamePoints(P1, P2:TPoint):Boolean;
  107. begin
  108.   Result := False;
  109.   if ((P1.x = P2.x) and (P1.y = P2.y)) then
  110.     Result := True;
  111. end;
  112.  
  113. { Given a TPA - This function will connect each point, from first to last }
  114. function ConnectPts(Pts:TPointArray):TPointArray;
  115. var
  116.   i,j,h,l,rl,a: Integer;
  117.   f,t:TPoint;
  118.   AdivL: Extended;
  119. begin
  120.   h := high(pts);
  121.   for i:=0 to h do
  122.   begin
  123.     j := i+1;
  124.     if i=h then
  125.       j:=0;
  126.     f := pts[i];
  127.     t := pts[j];
  128.     rl := length(Result);
  129.     if not(SamePoints(f, t)) then
  130.     begin
  131.       l := Max(Round(Abs(f.X - t.X)), Round(Abs(f.Y - t.Y)));
  132.       SetLength(Result, rl+l+1);
  133.       for a := 0 to l do begin
  134.         AdivL := a / Extended(l);
  135.         Result[rl+a] := Point(f.X + Round((t.X - f.X) * AdivL), f.Y + Round((t.Y - f.Y) * AdivL));
  136.       end;
  137.     end
  138.     else
  139.     begin
  140.       SetLength(Result,rl + 1);
  141.       Result[rl] := f
  142.     end;
  143.   end;
  144. end;
  145.  
  146. function RandomTPA(Amount:Integer; MinX,MinY,MaxX,MaxY:Integer): TPointArray;
  147. var i:Integer;
  148. begin
  149.   SetLength(Result, Amount+1);
  150.   for i:=0 to Amount do
  151.   begin
  152.     Result[i] := Point(RandomRange(MinX, MaxX), RandomRange(MinY, MaxY));
  153.   end;
  154. end;
  155.  
  156. //******* Plot a few shapes using this algorithm *******//
  157. var
  158.   TPA,CTPA: TPointArray;
  159.   bmp: Integer;
  160. begin
  161.   bmp := CreateBitmap(700, 700);
  162.  
  163.   TPA := RandomTPA(10000, 100,100,595,595);
  164.   CTPA := CopyTPA(TPA);
  165.   ConvexHull(CTPA);
  166.   //pp_TPAConvexHull(CTPA);
  167.   CTPA := ConnectPts(CTPA);
  168.  
  169.   DrawTPABitmap(bmp, TPA, 357435);
  170.   DrawTPABitmap(bmp, CTPA, 255);
  171.  
  172.   DisplayDebugImgWindow(700,700);
  173.   DrawBitmapDebugImg(bmp);
  174.   FreeBitmap(bmp);
  175. end.
Advertisement
Add Comment
Please, Sign In to add comment