Janilabo

ClusterTPA Integer Distance

Sep 25th, 2013
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.48 KB | None | 0 0
  1. {/\
  2. Splits TPA with dist. Alternative to SplitTPA.
  3. /\}
  4. function ClusterTPA(const TPA: TPointArray; dist: Integer): T2DPointArray;
  5. type
  6.   TPointScan = record
  7.     skipRow: Boolean;
  8.     count: Integer;
  9.   end;
  10. var
  11.   h, i, l, c, s, x, y, o, r, d, m: Integer;
  12.   p: array of array of TPointScan;
  13.   q: TPointArray;
  14.   a, b, t: TBox;
  15.   e: Extended;
  16.   z: TPoint;
  17.   v: Boolean;
  18. begin
  19.   SetLength(Result, 0);
  20.   h := High(TPA);
  21.   if (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].skipRow := False;
  50.         end;
  51.       end;
  52.       e := Extended(dist);
  53.       if (e < 0.0) then
  54.         e := 0.0;
  55.       d := Ceil(e);
  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;
  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.             case ((t.X1 <> a.X1) or (t.X2 <> a.X2)) of
  107.               True:
  108.               for y := a.Y1 to a.Y2 do
  109.                 if not p[(a.X2 - b.X1)][(y - b.Y1)].skipRow then
  110.                 for x := a.X1 to a.X2 do
  111.                   if (p[(x - b.X1)][(y - b.Y1)].count > 0) then
  112.                     if (Round(Sqrt(Sqr(z.X - x) + Sqr(z.Y - y))) <= dist) then
  113.                     begin
  114.                       l := Length(Result[c]);
  115.                       SetLength(Result[c], (l + p[(x - b.X1)][(y - b.Y1)].count));
  116.                       for o := 0 to (p[(x - b.X1)][(y - b.Y1)].count - 1) do
  117.                       begin
  118.                         Result[c][(l + o)].X := x;
  119.                         Result[c][(l + o)].Y := y;
  120.                       end;
  121.                       r := (r + p[(x - b.X1)][(y - b.Y1)].count);
  122.                       if (r > h) then
  123.                         Exit;
  124.                       p[(x - b.X1)][(y - b.Y1)].count := 0;
  125.                       SetLength(q, (s + 1));
  126.                       q[s] := Result[c][l];
  127.                       Inc(s);
  128.                     end;
  129.               False:
  130.               for y := a.Y1 to a.Y2 do
  131.                 if not p[(a.X2 - b.X1)][(y - b.Y1)].skipRow then
  132.                 begin
  133.                   v := True;
  134.                   for x := a.X1 to a.X2 do
  135.                     if (p[(x - b.X1)][(y - b.Y1)].count > 0) then
  136.                       if (Round(Sqrt(Sqr(z.X - x) + Sqr(z.Y - y))) <= dist) then
  137.                       begin
  138.                         l := Length(Result[c]);
  139.                         SetLength(Result[c], (l + p[(x - b.X1)][(y - b.Y1)].count));
  140.                         for o := 0 to (p[(x - b.X1)][(y - b.Y1)].count - 1) do
  141.                         begin
  142.                           Result[c][(l + o)].X := x;
  143.                           Result[c][(l + o)].Y := y;
  144.                         end;
  145.                         r := (r + p[(x - b.X1)][(y - b.Y1)].count);
  146.                         if (r > h) then
  147.                           Exit;
  148.                         p[(x - b.X1)][(y - b.Y1)].count := 0;
  149.                         SetLength(q, (s + 1));
  150.                         q[s] := Result[c][l];
  151.                         Inc(s);
  152.                       end else
  153.                         v := False;
  154.                   if v then
  155.                     p[(a.X2 - b.X1)][(y - b.Y1)].skipRow := True;
  156.                 end;
  157.             end;
  158.           end;
  159.         end;
  160.     end else
  161.     begin
  162.       SetLength(Result, 1);
  163.       SetLength(Result[0], 1);
  164.       Result[0][0] := TPA[0];
  165.     end;
  166. end;
Advertisement
Add Comment
Please, Sign In to add comment