Janilabo

polygon test

Sep 18th, 2013
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 7.00 KB | None | 0 0
  1. // Original algorithms by slacky, optimized by Janilabo
  2.  
  3. const
  4.   POLYGON_EXAMPLE = 1; // 0-9.
  5.   DISPLAY_MAINPOINTS = True; // True or False.
  6.   OFFSET = 5; // Used for debug image..
  7.  
  8. function TPAFromPolygon(shape: TPointArray): TPointArray;
  9. var
  10.   b: TBox;
  11.   x, y, h, i, l, r, z: Integer;
  12.   o: TPointArray;
  13.   f: Boolean;
  14.   t: array of TBoolArray;
  15.   e: Extended;
  16.   q, p, d: TPoint;
  17. begin
  18.   h := High(shape);
  19.   if (h > -1) then
  20.   begin
  21.     SetLength(o, 0);
  22.     b := IntToBox(shape[0].X, shape[0].Y, shape[0].X, shape[0].Y);
  23.     for i := 0 to h do
  24.     begin
  25.       q := shape[i];
  26.       if (i < h) then
  27.         p := shape[(i + 1)]
  28.       else
  29.         p := shape[0];
  30.       r := Length(o);
  31.       if ((q.X <> p.X) or (q.Y <> p.Y)) then
  32.       begin
  33.         l := Max(Round(Abs(q.X - p.X)), Round(Abs(q.Y - p.Y)));
  34.         SetLength(o, ((r + l) + 1));
  35.         for z := 0 to l do
  36.           o[(r + z)] := Point((q.X + Round((p.X - q.X) * (z / Extended(l)))), (q.Y + Round((p.Y - q.Y) * (z / Extended(l)))));
  37.       end else
  38.       begin
  39.         SetLength(o, (r + 1));
  40.         o[r] := q;
  41.       end;
  42.       if (shape[i].X < b.X1) then
  43.         b.X1 := shape[i].X
  44.       else
  45.         if (shape[i].X > b.X2) then
  46.           b.X2 := shape[i].X;
  47.       if (shape[i].Y < b.Y1) then
  48.         b.Y1 := shape[i].Y
  49.       else
  50.         if (shape[i].Y > b.Y2) then
  51.           b.Y2 := shape[i].Y;
  52.     end;
  53.     SetLength(t, ((b.X2 - b.X1) + 1));
  54.     for i := 0 to (b.X2 - b.X1) do
  55.       SetLength(t[i], ((b.Y2 - b.Y1) + 1));
  56.     l := Length(o);
  57.     for i := 0 to (l - 1) do
  58.       if not t[(o[i].X - b.X1)][(o[i].Y - b.Y1)] then
  59.         t[(o[i].X - b.X1)][(o[i].Y - b.Y1)] := True;
  60.     for y := 0 to (b.Y2 - b.Y1) do
  61.       for x := 0 to (b.X2 - b.X1) do
  62.       begin
  63.         f := t[x][y];
  64.         if not f then
  65.         begin
  66.           d := Point((x + b.X1), (y + b.Y1));
  67.           q := shape[0];
  68.           for i := 0 to (h + 1) do
  69.           begin
  70.             p := shape[(i mod (h + 1))];
  71.             if (d.Y > Min(q.Y, p.Y)) then
  72.               if (d.Y <= Max(q.Y, p.Y)) then
  73.                 if (d.X <= Max(q.X, p.X)) then
  74.                 begin
  75.                   if (q.y <> p.y) then
  76.                     e := ((d.Y - q.Y) * (p.X - q.X) / Extended((p.Y - q.Y)) + q.X);
  77.                   if ((q.X = p.X) or (d.X < e)) then
  78.                     f := not f;
  79.                 end;
  80.             q := p;
  81.           end;
  82.         end;
  83.         if f then
  84.         begin
  85.           l := Length(Result);
  86.           SetLength(Result, (l + 1));
  87.           Result[l] := Point((x + b.X1), (y + b.Y1));
  88.         end;
  89.       end;
  90.   end else
  91.     SetLength(Result, 0);
  92. end;
  93.  
  94. {==============================================================================]
  95.   Explanation: Creates all the points needed to define a simple polygon
  96.   NOTE: Original algorithm by slacky (warpie)
  97. [==============================================================================}
  98. function TPAXagon(sides: Integer; C, S: TPoint): TPointArray;
  99. var
  100.   x, y, a, b, v: Integer;
  101.   n, m: Extended;
  102. begin
  103.   if (sides > 2) then
  104.   begin
  105.     SetLength(Result, sides);
  106.     x := S.x;
  107.     y := S.y;
  108.     n := Sin(Radians(360.0 / sides));
  109.     m := Cos(Radians(360.0 / sides));
  110.     for v := 0 to (sides - 1) do
  111.     begin
  112.       a := (x - C.x);
  113.       b := (y - C.y);
  114.       x := Round(((b * n) + (a * m) + C.x));
  115.       y := Round(((b * m) - (a * n) + C.y));
  116.       Result[v] := Point(x, y);
  117.     end;
  118.   end else
  119.     SetLength(Result, 0);
  120. end;
  121.  
  122. //******* DIRTY EXAMPLE BELLOW: *******//
  123. procedure SetPixels(bmp: Integer; TPA: TPointArray; color: Integer);
  124. var
  125.   a, z, w, h: Integer;
  126. begin
  127.   z := High(TPA);
  128.   if (z > -1) then
  129.   begin
  130.     GetBitmapSize(bmp, w, h);
  131.     for a := 0 to z do
  132.       if ((TPA[a].X >= 0) and (TPA[a].Y >= 0) and (TPA[a].X < w) and (TPA[a].Y < h)) then
  133.         FastSetPixel(bmp, TPA[a].X, TPA[a].Y, color);
  134.   end;
  135. end;
  136.  
  137. procedure SetPixelsMP(bmp: Integer; TPA: TPointArray; color: Integer);
  138. var
  139.   a, z, w, h: Integer;
  140. begin
  141.   z := High(TPA);
  142.   if (z > -1) then
  143.   begin
  144.     GetBitmapSize(bmp, w, h);
  145.     for a := 0 to z do
  146.       if ((TPA[a].X > 0) and (TPA[a].Y > 0) and (TPA[a].X < (w - 1)) and (TPA[a].Y < (h - 1))) then
  147.       begin
  148.         FastSetPixel(bmp, (TPA[a].X - 1), TPA[a].Y, color);
  149.         FastSetPixel(bmp, (TPA[a].X + 1), TPA[a].Y, color);
  150.         FastSetPixel(bmp, TPA[a].X, (TPA[a].Y + 1), color);
  151.         FastSetPixel(bmp, TPA[a].X, (TPA[a].Y - 1), color);
  152.       end;
  153.   end;
  154. end;
  155.  
  156. procedure Setup;
  157. var
  158.   shape, TPA: TPointArray;
  159.   bmp, t, o: Integer;
  160.   v: Boolean;
  161.   a: TBox;
  162. begin
  163.   //Dynamic shapes from Example 6 and down:
  164.   v := True;
  165.   case POLYGON_EXAMPLE of
  166.     // Microshape ------//
  167.     //           TOP           LEFT           BOTTOM          RIGHT
  168.     0: shape := [Point(20,20), Point(20,120), Point(120,120), Point(120,20)];
  169.     // Arrow like shape //
  170.     1: shape := [Point(70,90),Point(185,90),Point(185,116), Point(70,116), //Square +
  171.                  Point(70,140),Point(35,105),Point(70,70)];                //Triangle
  172.     // Triangle --------//
  173.     2: shape := [Point(50,50),Point(0,100),Point(100,150)];
  174.     // Raped pentagon --//
  175.     3: shape := [Point(10,25),Point(35,5),Point(82,22),Point(50,90),Point(4,60)];
  176.     // Octagon ---------//
  177.     4: shape := [Point(100,30), Point(155,50),  //Top-Right
  178.                  Point(180,110),Point(155,160), //Right-Bottom
  179.                  Point(100,180),Point(45,160),  //Bottom-Left
  180.                  Point(20,100), Point(45,50)];  //Left-Top
  181.     // S-shape ---------//
  182.     5: shape := [Point(135,50),Point(123,70),Point(103,58),Point(85,70),Point(85,85),
  183.                  Point(122,105),Point(132,125),Point(120,155),Point(78,164),Point(55,147),
  184.                  Point(64,128),Point(80,140),Point(100,140),Point(96,116),Point(62,98),
  185.                  Point(60,55),Point(111,35)];
  186.     // Xagon: 15 corners //
  187.     6: shape := TPAXagon(15, Point(100,100), Point(60,100));
  188.     // Xagon: 9 corners //
  189.     7: shape := TPAXagon(9, Point(100,100), Point(60,50));
  190.     // Xagon: 5 corners AKA Pentagon //
  191.     8: shape := TPAXagon(5, Point(100,100), Point(74,50));
  192.     // Xagon: 3 corners AKA Triangle //
  193.     9: shape := TPAXagon(3, Point(100,100), Point(48,48));
  194.   else
  195.     v := False;
  196.   end;
  197.   if v then
  198.   begin
  199.     if ((a.X1 > -1) and (a.Y1 > -1)) then
  200.     begin
  201.       if (OFFSET > 0) then
  202.         o := OFFSET;
  203.       t := GetSystemTime;
  204.       if (o > 0) then
  205.         OffsetTPA(shape, Point(o, o));
  206.       TPA := TPAFromPolygon(shape);
  207.       a := GetTPABounds(TPA);
  208.       bmp := CreateBitmap((a.X2 + o), (a.Y2 + o));
  209.       WriteLn(IntToStr(GetSystemTime - t) + ' ms.');
  210.       SetPixels(bmp, TPA, 357435);
  211.       if DISPLAY_MAINPOINTS then
  212.         SetPixelsMP(bmp, shape, 16777215);
  213.       DisplayDebugImgWindow((a.X2 + a.X1), (a.Y2 + a.Y1));
  214.       DrawBitmapDebugImg(bmp);
  215.       FreeBitmap(bmp);
  216.       SetLength(TPA, 0);
  217.     end else
  218.       WriteLn('Invalid TPA! Negative points found...');
  219.   end else
  220.     WriteLn('Invalid polygon ID!');
  221. end;
  222.  
  223. begin
  224.   ClearDebug;
  225.   Setup;
  226. end.
Advertisement
Add Comment
Please, Sign In to add comment