Janilabo

tpafrompolygon

Sep 18th, 2013
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.41 KB | None | 0 0
  1. const
  2.   DELAY = 2000; // Delay before displaying the ellipse after main points (by convex hull)..
  3.  
  4. function TPAFromPolygon2(shape: TPointArray): TPointArray;
  5. var
  6.   b: TBox;
  7.   x, y, h, i, l, r, z: Integer;
  8.   o: TPointArray;
  9.   f: Boolean;
  10.   t: array of TBoolArray;
  11.   e: Extended;
  12.   q, p, d: TPoint;
  13. begin
  14.   h := High(shape);
  15.   if (h > -1) then
  16.   begin
  17.     SetLength(o, 0);
  18.     b := IntToBox(shape[0].X, shape[0].Y, shape[0].X, shape[0].Y);
  19.     for i := 0 to h do
  20.     begin
  21.       q := shape[i];
  22.       if (i < h) then
  23.         p := shape[(i + 1)]
  24.       else
  25.         p := shape[0];
  26.       r := Length(o);
  27.       if ((q.X <> p.X) or (q.Y <> p.Y)) then
  28.       begin
  29.         l := Max(Round(Abs(q.X - p.X)), Round(Abs(q.Y - p.Y)));
  30.         SetLength(o, ((r + l) + 1));
  31.         for z := 0 to l do
  32.           o[(r + z)] := Point((q.X + Round((p.X - q.X) * (z / Extended(l)))), (q.Y + Round((p.Y - q.Y) * (z / Extended(l)))));
  33.       end else
  34.       begin
  35.         SetLength(o, (r + 1));
  36.         o[r] := q;
  37.       end;
  38.       if (shape[i].X < b.X1) then
  39.         b.X1 := shape[i].X
  40.       else
  41.         if (shape[i].X > b.X2) then
  42.           b.X2 := shape[i].X;
  43.       if (shape[i].Y < b.Y1) then
  44.         b.Y1 := shape[i].Y
  45.       else
  46.         if (shape[i].Y > b.Y2) then
  47.           b.Y2 := shape[i].Y;
  48.     end;
  49.     SetLength(t, ((b.X2 - b.X1) + 1));
  50.     for i := 0 to (b.X2 - b.X1) do
  51.       SetLength(t[i], ((b.Y2 - b.Y1) + 1));
  52.     l := Length(o);
  53.     for i := 0 to (l - 1) do
  54.       if not t[(o[i].X - b.X1)][(o[i].Y - b.Y1)] then
  55.         t[(o[i].X - b.X1)][(o[i].Y - b.Y1)] := True;
  56.     for y := 0 to (b.Y2 - b.Y1) do
  57.       for x := 0 to (b.X2 - b.X1) do
  58.       begin
  59.         f := t[x][y];
  60.         if not f then
  61.         begin
  62.           d := Point((x + b.X1), (y + b.Y1));
  63.           q := shape[0];
  64.           for i := 0 to (h + 1) do
  65.           begin
  66.             p := shape[(i mod (h + 1))];
  67.             if (d.Y > Min(q.Y, p.Y)) then
  68.               if (d.Y <= Max(q.Y, p.Y)) then
  69.                 if (d.X <= Max(q.X, p.X)) then
  70.                 begin
  71.                   if (q.y <> p.y) then
  72.                     e := ((d.Y - q.Y) * (p.X - q.X) / Extended((p.Y - q.Y)) + q.X);
  73.                   if ((q.X = p.X) or (d.X < e)) then
  74.                     f := not f;
  75.                 end;
  76.             q := p;
  77.           end;
  78.         end;
  79.         if f then
  80.         begin
  81.           l := Length(Result);
  82.           SetLength(Result, (l + 1));
  83.           Result[l] := Point((x + b.X1), (y + b.Y1));
  84.         end;
  85.       end;
  86.   end else
  87.     SetLength(Result, 0);
  88. end;
  89.  
  90. procedure TPAConvexHull(var TPA: TPointArray);
  91. var
  92.   p, Lower: TPointArray;
  93.   LH, H, I, UH, c, j, idx, x, y: Integer;
  94.   area: TBox;
  95.   m: array of TBoolArray;
  96.   b: Boolean;
  97. begin
  98.   h := High(TPA);
  99.   if (h > 0) then
  100.   begin
  101.     area := GetTPABounds(TPA);
  102.     SetLength(m, ((area.X2 - area.X1) + 1));
  103.     for i := 0 to (area.X2 - area.X1) do
  104.       SetLength(m[i], ((area.Y2 - area.Y1) + 1));
  105.     C := 0;
  106.     for i := 0 to h do
  107.     begin
  108.       x := (TPA[i].X - area.X1);
  109.       y := (TPA[i].Y - area.Y1);
  110.       if m[x][y] then
  111.         Continue;
  112.       m[x][y] := True;
  113.       Inc(C);
  114.     end;
  115.     SetLength(p, C);
  116.     idx := 0;
  117.     b := False;
  118.     for y := area.Y1 to area.Y2 do
  119.     begin
  120.       for x := area.X1 to area.X2 do
  121.         if m[(x - area.X1)][(y - area.Y1)] then
  122.         begin
  123.           p[idx] := Point(x, y);
  124.           Inc(idx);
  125.           b := (idx >= C);
  126.           if b then
  127.             Break;
  128.         end;
  129.       if b then
  130.         Break;
  131.     end;
  132.     h := High(p);
  133.     if (h > 0) then
  134.     begin
  135.       UH := 2;
  136.       SetLength(TPA, (h + 1));
  137.       TPA[0] := p[0];
  138.       TPA[1] := p[1];
  139.       for i := 2 to h do
  140.       begin
  141.         TPA[UH] := p[i];
  142.         Inc(UH);
  143.         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
  144.         begin
  145.           Dec(UH);
  146.           TPA[(UH - 1)] := TPA[UH];
  147.         end;
  148.       end;
  149.       LH := 2;
  150.       SetLength(Lower, (h + 1));
  151.       Lower[0] := p[h];
  152.       Lower[1] := p[(h - 1)];
  153.       for i := 2 to h do
  154.       begin
  155.         Lower[LH] := p[(h - i)];
  156.         Inc(LH);
  157.         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
  158.         begin
  159.           Dec(LH);
  160.           Lower[(LH - 1)] := Lower[LH];
  161.         end;
  162.       end;
  163.       Dec(LH);
  164.       SetLength(TPA, (UH + LH));
  165.       for i := UH to ((UH + LH) - 1) do
  166.         TPA[i] := Lower[(i - UH)];
  167.     end;
  168.   end;
  169. end;
  170.  
  171. procedure Setup;
  172. var
  173.   shape, TPA: TPointArray;
  174.   bmp: Integer;
  175.   a: TBox;
  176. begin
  177.   shape := TPAFromEllipse(350, 350, 100, 150);
  178.   TPAConvexHull(shape);
  179.   a := GetTPABounds(shape);
  180.   bmp := CreateBitmap(((a.X2 + a.X1) + 1), ((a.Y2 + a.Y1) + 1));
  181.   DisplayDebugImgWindow(((a.X2 + a.X1) + 1), ((a.Y2 + a.Y1) + 1));
  182.   DrawTPABitmap(bmp, shape, 16777215);
  183.   DrawBitmapDebugImg(bmp);
  184.   Wait(DELAY);
  185.   TPA := TPAFromPolygon2(shape);
  186.   DrawTPABitmap(bmp, TPA, 357435);
  187.   DrawTPABitmap(bmp, shape, 16777215);
  188.   DrawBitmapDebugImg(bmp);
  189.   FreeBitmap(bmp);
  190. end;
  191.  
  192. begin
  193.   ClearDebug;
  194.   Setup;
  195. end.
Advertisement
Add Comment
Please, Sign In to add comment