Janilabo

ATPASortSpiralEx

Aug 18th, 2013
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 3.73 KB | None | 0 0
  1. {==============================================================================]
  2.  @action: Sorts ATPA to order in a spiral pattern, spiraling out from the origin TPoint.
  3.  @note: Doesn't touch the index items (points), will keep them at same order as they were.
  4.  @contributors: Janilabo, slacky
  5. [==============================================================================}
  6. procedure ATPASortSpiralEx(var ATPA: T2DPointArray; origin: TPoint); callconv
  7. var
  8.   h, r, i, d, g, s, n, x, y, z: Integer;
  9.   p: T3DBoolArray;
  10.   c: T2DPointArray;
  11.   a: TBoolArray;
  12.   bx: TBox;
  13.   v: Boolean;
  14. begin;
  15.   h := High(ATPA);
  16.   if (h > 0) then
  17.   begin
  18.     SetLength(c, (h + 1));
  19.     v := False;
  20.     for i := 0 to h do
  21.     begin
  22.       y := High(ATPA[i]);
  23.       SetLength(c[i], (y + 1));
  24.       if (y > -1) then
  25.       case v of
  26.         False:
  27.         begin
  28.           v := True;
  29.           bx := Box(ATPA[i][0].X, ATPA[i][0].Y, ATPA[i][0].X, ATPA[i][0].Y);
  30.           c[i][0] := ATPA[i][0];
  31.           if (y > 0) then
  32.           for x := 1 to y do
  33.           begin
  34.             c[i][x] := ATPA[i][x];
  35.             if (ATPA[i][x].X < bx.X1) then
  36.               bx.X1 := ATPA[i][x].X
  37.             else
  38.               if (ATPA[i][x].X > bx.X2) then
  39.                 bx.X2 := ATPA[i][x].X;
  40.             if (ATPA[i][x].Y < bx.Y1) then
  41.               bx.Y1 := ATPA[i][x].Y
  42.             else
  43.               if (ATPA[i][x].Y > bx.Y2) then
  44.                 bx.Y2 := ATPA[i][x].Y;
  45.           end;
  46.         end;
  47.         True:
  48.         for x := 0 to y do
  49.         begin
  50.           c[i][x] := ATPA[i][x];
  51.           if (ATPA[i][x].X < bx.X1) then
  52.             bx.X1 := ATPA[i][x].X
  53.           else
  54.             if (ATPA[i][x].X > bx.X2) then
  55.               bx.X2 := ATPA[i][x].X;
  56.           if (ATPA[i][x].Y < bx.Y1) then
  57.             bx.Y1 := ATPA[i][x].Y
  58.           else
  59.             if (ATPA[i][x].Y > bx.Y2) then
  60.               bx.Y2 := ATPA[i][x].Y;
  61.         end;
  62.       end;
  63.     end;
  64.     if v then
  65.     begin
  66.       z := (h + 1);
  67.       CreateTBoA(False, (h + 1), a);
  68.       r := 0;
  69.       for i := h downto 0 do
  70.         if (Length(c[i]) = 0) then
  71.         begin
  72.           SetLength(ATPA[(h - r)], 0);
  73.           a[i] := True;
  74.           Dec(z);
  75.         end;
  76.       SetLength(p, ((bx.X2 - bx.X1) + 1));
  77.       for x := 0 to (bx.X2 - bx.X1) do
  78.       begin
  79.         SetLength(p[x], ((bx.Y2 - bx.Y1) + 1));
  80.         for y := 0 to (bx.Y2 - bx.Y1) do
  81.         begin
  82.           SetLength(p[x][y], (h + 1));
  83.           for i := 0 to h do
  84.             p[x][y][i] := False;
  85.         end;
  86.       end;
  87.       for i := 0 to h do
  88.       begin
  89.         y := High(ATPA[i]);
  90.         for x := 0 to y do
  91.           p[(ATPA[i][x].X - bx.X1)][(ATPA[i][x].Y - bx.Y1)][i] := True;
  92.       end;
  93.       d := 0;
  94.       s := 1;
  95.       g := 1;
  96.       r := 0;
  97.       n := 0;
  98.       repeat
  99.         if ((origin.X >= bx.X1) and (origin.Y >= bx.Y1) and (origin.X <= bx.X2) and (origin.Y <= bx.Y2)) then
  100.           for i := 0 to h do
  101.             if not a[i] then
  102.               if p[(origin.X - bx.X1)][(origin.Y - bx.Y1)][i] then
  103.               begin
  104.                 y := High(c[i]);
  105.                 SetLength(ATPA[n], (y + 1));
  106.                 for x := 0 to y do
  107.                   ATPA[n][x] := c[i][x];
  108.                 a[i] := True;
  109.                 Inc(n);
  110.                 Dec(z);
  111.               end;
  112.         case (d mod 4) of
  113.           0: origin.Y := (origin.Y - 1);
  114.           1: origin.X := (origin.X + 1);
  115.           2: origin.Y := (origin.Y + 1);
  116.           3: origin.X := (origin.X - 1);
  117.         end;
  118.         if (g = s) then
  119.         begin
  120.           Inc(d);
  121.           if ((d mod 2) = 0) then
  122.             Inc(s);
  123.           g := 0;
  124.         end;
  125.         Inc(g);
  126.       until ((z <= 0) or (n > h));
  127.     end;
  128.   end;
  129. end;
Advertisement
Add Comment
Please, Sign In to add comment