MainUnit.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. unit MainUnit;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is GR32_Clipper Example
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Angus Johnson
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2012
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$include GR32.inc}
  35. uses
  36. {$IFNDEF FPC}Windows, {$ELSE} LCLIntf, LCLType, {$ENDIF} SysUtils, Classes,
  37. Types, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Math,
  38. GR32, GR32_Image, GR32_Polygons, GR32_Layers, GR32_Geometry,
  39. GR32_Math, GR32_VectorUtils, GR32_Clipper;
  40. type
  41. TFrmClipper = class(TForm)
  42. BtnClear: TButton;
  43. BtnExit: TButton;
  44. ImgView32: TImgView32;
  45. PnlControl: TPanel;
  46. rgClipping: TRadioGroup;
  47. RgpObject: TRadioGroup;
  48. BtnInflate: TButton;
  49. BtnDeflate: TButton;
  50. procedure FormCreate(Sender: TObject);
  51. procedure BtnExitClick(Sender: TObject);
  52. procedure ImgView32MouseMove(Sender: TObject; Shift: TShiftState; X,
  53. Y: Integer; Layer: TCustomLayer);
  54. procedure ImgView32MouseDown(Sender: TObject; Button: TMouseButton;
  55. Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
  56. procedure BtnClearClick(Sender: TObject);
  57. procedure ImgView32MouseLeave(Sender: TObject);
  58. procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  59. procedure BtnInflateClick(Sender: TObject);
  60. procedure BtnDeflateClick(Sender: TObject);
  61. private
  62. Polys: TArrayOfArrayOfFloatPoint;
  63. OutlinePolygon: TArrayOfFloatPoint;
  64. procedure AddPolygon(const Pts: TArrayOfFloatPoint);
  65. function MakeRectangle(const NewPoint: TPoint): TArrayOfFloatPoint;
  66. function MakeEllipse(const NewPoint: TPoint): TArrayOfFloatPoint;
  67. function MakeStar(const NewPoint: TPoint): TArrayOfFloatPoint;
  68. procedure DrawPolygons;
  69. end;
  70. var
  71. FrmClipper: TFrmClipper;
  72. implementation
  73. {$R *.dfm}
  74. procedure DrawStippled(Bitmap: TBitmap32;
  75. const Afp: TArrayOfFloatPoint;
  76. StippleColors: array of TColor32; StippleStep: TFloat);
  77. var
  78. i: Integer;
  79. begin
  80. if Afp = nil then Exit;
  81. Bitmap.StippleStep := StippleStep;
  82. Bitmap.SetStipple(StippleColors);
  83. Bitmap.MoveToF(Afp[0].X, Afp[0].Y);
  84. for i := 1 to High(Afp) do
  85. Bitmap.LineToFSP(Afp[i].X, Afp[i].Y);
  86. Bitmap.LineToFSP(Afp[0].X, Afp[0].Y);
  87. end;
  88. { TFrmClipper methods }
  89. procedure TFrmClipper.FormCreate(Sender: TObject);
  90. begin
  91. ImgView32.SetupBitmap(true);
  92. AddPolygon(MakeStar(GR32.Point(125, 150)));
  93. ImgView32.ScrollToCenter(0, 0);
  94. end;
  95. procedure TFrmClipper.FormKeyDown(Sender: TObject; var Key: Word;
  96. Shift: TShiftState);
  97. begin
  98. if Key = 27 then
  99. Exit;
  100. end;
  101. procedure TFrmClipper.AddPolygon(const Pts: TArrayOfFloatPoint);
  102. var
  103. ct: TClipType;
  104. Clipper: TClipper32;
  105. begin
  106. Clipper := TClipper32.Create;
  107. try
  108. //add multiple contours of existing polygons as subject polygons ...
  109. Clipper.AddPaths(Polys, ptSubject);
  110. //add the single contour of the new polygon as the clipping polygon ...
  111. Clipper.AddPath(Pts, ptClip);
  112. //do the clipping operation (result => Polys) ...
  113. case rgClipping.ItemIndex of
  114. 0: ct := ctIntersection;
  115. 1: ct := ctUnion;
  116. 2: ct := ctDifference;
  117. else ct := ctXor;
  118. end;
  119. Clipper.Execute(ct, frNonZero, Polys);
  120. finally
  121. Clipper.Free;
  122. end;
  123. DrawPolygons;
  124. end;
  125. function TFrmClipper.MakeRectangle(const NewPoint: TPoint): TArrayOfFloatPoint;
  126. begin
  127. SetLength(Result, 4);
  128. Result[0] := FloatPoint(NewPoint.X - 50, NewPoint.Y - 30);
  129. Result[1] := FloatPoint(NewPoint.X + 50, NewPoint.Y - 30);
  130. Result[2] := FloatPoint(NewPoint.X + 50, NewPoint.Y + 30);
  131. Result[3] := FloatPoint(NewPoint.X - 50, NewPoint.Y + 30);
  132. end;
  133. function TFrmClipper.MakeEllipse(const NewPoint: TPoint): TArrayOfFloatPoint;
  134. begin
  135. Result := Ellipse(FloatPoint(NewPoint), FloatPoint(60,40));
  136. end;
  137. function TFrmClipper.MakeStar(const NewPoint: TPoint): TArrayOfFloatPoint;
  138. begin
  139. Result := Star(FloatPoint(NewPoint), 40.0, 60.0, 7);
  140. end;
  141. procedure TFrmClipper.DrawPolygons;
  142. begin
  143. ImgView32.Bitmap.FillRectS(ImgView32.Bitmap.BoundsRect, clWhite32);
  144. PolyPolyLineFS(ImgView32.Bitmap, Polys, clRed32, True, 2);
  145. PolyPolygonFS(ImgView32.Bitmap, Polys, $40FF0000, pfWinding);
  146. DrawStippled(ImgView32.Bitmap,
  147. OutlinePolygon, [clBlue32, clBlue32, $000000FF], 0.35);
  148. end;
  149. procedure TFrmClipper.ImgView32MouseDown(Sender: TObject;
  150. Button: TMouseButton; Shift: TShiftState; X, Y: Integer;
  151. Layer: TCustomLayer);
  152. begin
  153. AddPolygon(OutlinePolygon);
  154. end;
  155. procedure TFrmClipper.ImgView32MouseMove(Sender: TObject;
  156. Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
  157. var
  158. NewPt: TPoint;
  159. begin
  160. NewPt := ImgView32.ControlToBitmap(GR32.Point(X, Y));
  161. case RgpObject.ItemIndex of
  162. 0: OutlinePolygon := MakeStar(NewPt);
  163. 1: OutlinePolygon := MakeEllipse(NewPt);
  164. else OutlinePolygon := MakeRectangle(NewPt);
  165. end;
  166. DrawPolygons;
  167. end;
  168. procedure TFrmClipper.ImgView32MouseLeave(Sender: TObject);
  169. begin
  170. OutlinePolygon := nil;
  171. DrawPolygons;
  172. end;
  173. procedure TFrmClipper.BtnExitClick(Sender: TObject);
  174. begin
  175. Close;
  176. end;
  177. procedure TFrmClipper.BtnClearClick(Sender: TObject);
  178. begin
  179. Polys := nil;
  180. DrawPolygons;
  181. end;
  182. procedure TFrmClipper.BtnInflateClick(Sender: TObject);
  183. begin
  184. Polys := InflatePaths(Polys, 10, jtRound, etPolygon);
  185. DrawPolygons;
  186. end;
  187. procedure TFrmClipper.BtnDeflateClick(Sender: TObject);
  188. begin
  189. Polys := InflatePaths(Polys, -10, jtRound, etPolygon);
  190. DrawPolygons;
  191. end;
  192. end.