Janilabo

TPADistributeEx

Aug 29th, 2013
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 6.47 KB | None | 0 0
  1. {==============================================================================]
  2.  Splits TPA with minDist, maxDist.
  3. [==============================================================================}
  4. function TPADistributeEx(TPA: TPointArray; minDist, maxDist: Extended): T2DPointArray; stdcall;
  5. type
  6.   TPointScan = record
  7.     skipArea, skipRow: Boolean;
  8.     count: Integer;
  9.   end;
  10. var
  11.   h, i, l, c, s, x, y, o, r, d, m, t: Integer;
  12.   p: array of array of TPointScan;
  13.   q: TPointArray;
  14.   a, b: TBox;
  15.   e: Extended;
  16.   z: TPoint;
  17.   v, w: Boolean;
  18. begin
  19.   SetLength(Result, 0);
  20.   h := High(TPA);
  21.   if ((minDist <= maxDist) and (h > -1)) then
  22.     if (h > 0) then
  23.     begin
  24.       b.X1 := TPA[0].X;
  25.       b.Y1 := TPA[0].Y;
  26.       b.X2 := TPA[0].X;
  27.       b.Y2 := TPA[0].Y;
  28.       r := 0;
  29.       for i := 1 to h do
  30.       begin
  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.       SetLength(p, ((b.X2 - b.X1) + 1));
  43.       for i := 0 to (b.X2 - b.X1) do
  44.       begin
  45.         SetLength(p[i], ((b.Y2 - b.Y1) + 1));
  46.         for c := 0 to (b.Y2 - b.Y1) do
  47.         begin
  48.           p[i][c].count := 0;
  49.           p[i][c].skipArea := False;
  50.           p[i][c].skipRow := False;
  51.         end;
  52.       end;
  53.       if (maxDist < 0.0) then
  54.         maxDist := 0.0;
  55.       d := Ceil(maxDist);
  56.       m := Max(((b.X2 - b.X1) + 1), ((b.Y2 - b.Y1) + 1));
  57.       if (d > m) then
  58.         d := m;
  59.       for i := 0 to h do
  60.         Inc(p[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)].count);
  61.       for i := 0 to h do
  62.         if (p[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)].count > 0) then
  63.         begin
  64.           c := Length(Result);
  65.           SetLength(Result, (c + 1));
  66.           SetLength(Result[c], p[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)].count);
  67.           for o := 0 to (p[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)].count - 1) do
  68.             Result[c][o] := TPA[i];
  69.           r := (r + p[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)].count);
  70.           if (r > h) then
  71.             Exit;
  72.           SetLength(q, 1);
  73.           q[0] := TPA[i];
  74.           p[(TPA[i].X - b.X1)][(TPA[i].Y - b.Y1)].count := 0;
  75.           s := 1;
  76.           while (s > 0) do
  77.           begin
  78.             s := High(q);
  79.             z := q[s];
  80.             a.X1 := (z.X - d);
  81.             a.Y1 := (z.Y - d);
  82.             a.X2 := (z.X + d);
  83.             a.Y2 := (z.Y + d);
  84.             t := a.X1;
  85.             SetLength(q, s);
  86.             if (a.X1 < b.X1) then
  87.               a.X1 := b.X1
  88.             else
  89.               if (a.X1 > b.X2) then
  90.                 a.X1 := b.X2;
  91.             if (a.Y1 < b.Y1) then
  92.               a.Y1 := b.Y1
  93.             else
  94.               if (a.Y1 > b.Y2) then
  95.                 a.Y1 := b.Y2;
  96.             if (a.X2 < b.X1) then
  97.               a.X2 := b.X1
  98.             else
  99.               if (a.X2 > b.X2) then
  100.                 a.X2 := b.X2;
  101.             if (a.Y2 < b.Y1) then
  102.               a.Y2 := b.Y1
  103.             else
  104.               if (a.Y2 > b.Y2) then
  105.                 a.Y2 := b.Y2;
  106.             if not p[(a.X1 - b.X1)][(a.Y1 - b.Y1)].skipArea then
  107.             case (t <> a.X1) of
  108.               True:
  109.               begin
  110.                 w := True;
  111.                 for y := a.Y1 to a.Y2 do
  112.                   if not p[(a.X2 - b.X1)][(y - b.Y1)].skipRow then
  113.                   for x := a.X1 to a.X2 do
  114.                     if (p[(x - b.X1)][(y - b.Y1)].count > 0) then
  115.                     begin
  116.                       e := Sqrt(Sqr(z.X - x) + Sqr(z.Y - y));
  117.                       if ((e >= minDist) and (e <= maxDist)) then
  118.                       begin
  119.                         l := Length(Result[c]);
  120.                         SetLength(Result[c], (l + p[(x - b.X1)][(y - b.Y1)].count));
  121.                         for o := 0 to (p[(x - b.X1)][(y - b.Y1)].count - 1) do
  122.                         begin
  123.                           Result[c][(l + o)].X := x;
  124.                           Result[c][(l + o)].Y := y;
  125.                         end;
  126.                         r := (r + p[(x - b.X1)][(y - b.Y1)].count);
  127.                         if (r > h) then
  128.                           Exit;
  129.                         p[(x - b.X1)][(y - b.Y1)].count := 0;
  130.                         SetLength(q, (s + 1));
  131.                         q[s] := Result[c][l];
  132.                         Inc(s);
  133.                       end else
  134.                         w := False;
  135.                     end;
  136.                 if w then
  137.                   p[(a.X1 - b.X1)][(a.Y1 - b.Y1)].skipArea := True;
  138.               end;
  139.               False:
  140.               begin
  141.                 w := True;
  142.                 for y := a.Y1 to a.Y2 do
  143.                   if not p[(a.X2 - b.X1)][(y - b.Y1)].skipRow then
  144.                   begin
  145.                     v := True;
  146.                     for x := a.X1 to a.X2 do
  147.                       if (p[(x - b.X1)][(y - b.Y1)].count > 0) then
  148.                       begin
  149.                         e := Sqrt(Sqr(z.X - x) + Sqr(z.Y - y));
  150.                         if ((e >= minDist) and (e <= maxDist)) then
  151.                         begin
  152.                           l := Length(Result[c]);
  153.                           SetLength(Result[c], (l + p[(x - b.X1)][(y - b.Y1)].count));
  154.                           for o := 0 to (p[(x - b.X1)][(y - b.Y1)].count - 1) do
  155.                           begin
  156.                             Result[c][(l + o)].X := x;
  157.                             Result[c][(l + o)].Y := y;
  158.                           end;
  159.                           r := (r + p[(x - b.X1)][(y - b.Y1)].count);
  160.                           if (r > h) then
  161.                             Exit;
  162.                           p[(x - b.X1)][(y - b.Y1)].count := 0;
  163.                           SetLength(q, (s + 1));
  164.                           q[s] := Result[c][l];
  165.                           Inc(s);
  166.                         end else
  167.                           v := False;
  168.                       end;
  169.                     if v then
  170.                       p[(a.X2 - b.X1)][(y - b.Y1)].skipRow := True
  171.                     else
  172.                       w := False;
  173.                   end;
  174.                 if w then
  175.                   p[(a.X1 - b.X1)][(a.Y1 - b.Y1)].skipArea := True;
  176.               end;
  177.             end;
  178.           end;
  179.         end;
  180.     end else
  181.     begin
  182.       SetLength(Result, 1);
  183.       SetLength(Result[0], 1);
  184.       Result[0][0] := TPA[0];
  185.     end;
  186. end;
Advertisement
Add Comment
Please, Sign In to add comment