rbclipper 6.4.2.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,406 @@
1
+ /*******************************************************************************
2
+ * *
3
+ * Author : Angus Johnson *
4
+ * Version : 6.4.2 *
5
+ * Date : 27 February 2017 *
6
+ * Website : http://www.angusj.com *
7
+ * Copyright : Angus Johnson 2010-2017 *
8
+ * *
9
+ * License: *
10
+ * Use, modification & distribution is subject to Boost Software License Ver 1. *
11
+ * http://www.boost.org/LICENSE_1_0.txt *
12
+ * *
13
+ * Attributions: *
14
+ * The code in this library is an extension of Bala Vatti's clipping algorithm: *
15
+ * "A generic solution to polygon clipping" *
16
+ * Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
17
+ * http://portal.acm.org/citation.cfm?id=129906 *
18
+ * *
19
+ * Computer graphics and geometric modeling: implementation and algorithms *
20
+ * By Max K. Agoston *
21
+ * Springer; 1 edition (January 4, 2005) *
22
+ * http://books.google.com/books?q=vatti+clipping+agoston *
23
+ * *
24
+ * See also: *
25
+ * "Polygon Offsetting by Computing Winding Numbers" *
26
+ * Paper no. DETC2005-85513 pp. 565-575 *
27
+ * ASME 2005 International Design Engineering Technical Conferences *
28
+ * and Computers and Information in Engineering Conference (IDETC/CIE2005) *
29
+ * September 24-28, 2005 , Long Beach, California, USA *
30
+ * http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
31
+ * *
32
+ *******************************************************************************/
33
+
34
+ #ifndef clipper_hpp
35
+ #define clipper_hpp
36
+
37
+ #define CLIPPER_VERSION "6.4.2"
38
+
39
+ //use_int32: When enabled 32bit ints are used instead of 64bit ints. This
40
+ //improve performance but coordinate values are limited to the range +/- 46340
41
+ //#define use_int32
42
+
43
+ //use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
44
+ //#define use_xyz
45
+
46
+ //use_lines: Enables line clipping. Adds a very minor cost to performance.
47
+ #define use_lines
48
+
49
+ //use_deprecated: Enables temporary support for the obsolete functions
50
+ //#define use_deprecated
51
+
52
+ #include <vector>
53
+ #include <list>
54
+ #include <set>
55
+ #include <stdexcept>
56
+ #include <cstring>
57
+ #include <cstdlib>
58
+ #include <ostream>
59
+ #include <functional>
60
+ #include <queue>
61
+
62
+ namespace ClipperLib {
63
+
64
+ enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
65
+ enum PolyType { ptSubject, ptClip };
66
+ //By far the most widely used winding rules for polygon filling are
67
+ //EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
68
+ //Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
69
+ //see http://glprogramming.com/red/chapter11.html
70
+ enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
71
+
72
+ #ifdef use_int32
73
+ typedef int cInt;
74
+ static cInt const loRange = 0x7FFF;
75
+ static cInt const hiRange = 0x7FFF;
76
+ #else
77
+ typedef signed long long cInt;
78
+ static cInt const loRange = 0x3FFFFFFF;
79
+ static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
80
+ typedef signed long long long64; //used by Int128 class
81
+ typedef unsigned long long ulong64;
82
+
83
+ #endif
84
+
85
+ struct IntPoint {
86
+ cInt X;
87
+ cInt Y;
88
+ #ifdef use_xyz
89
+ cInt Z;
90
+ IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
91
+ #else
92
+ IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
93
+ #endif
94
+
95
+ friend inline bool operator== (const IntPoint& a, const IntPoint& b)
96
+ {
97
+ return a.X == b.X && a.Y == b.Y;
98
+ }
99
+ friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
100
+ {
101
+ return a.X != b.X || a.Y != b.Y;
102
+ }
103
+ };
104
+ //------------------------------------------------------------------------------
105
+
106
+ typedef std::vector< IntPoint > Path;
107
+ typedef std::vector< Path > Paths;
108
+
109
+ inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
110
+ inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
111
+
112
+ std::ostream& operator <<(std::ostream &s, const IntPoint &p);
113
+ std::ostream& operator <<(std::ostream &s, const Path &p);
114
+ std::ostream& operator <<(std::ostream &s, const Paths &p);
115
+
116
+ struct DoublePoint
117
+ {
118
+ double X;
119
+ double Y;
120
+ DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
121
+ DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
122
+ };
123
+ //------------------------------------------------------------------------------
124
+
125
+ #ifdef use_xyz
126
+ typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
127
+ #endif
128
+
129
+ enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
130
+ enum JoinType {jtSquare, jtRound, jtMiter};
131
+ enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
132
+
133
+ class PolyNode;
134
+ typedef std::vector< PolyNode* > PolyNodes;
135
+
136
+ class PolyNode
137
+ {
138
+ public:
139
+ PolyNode();
140
+ virtual ~PolyNode(){};
141
+ Path Contour;
142
+ PolyNodes Childs;
143
+ PolyNode* Parent;
144
+ PolyNode* GetNext() const;
145
+ bool IsHole() const;
146
+ bool IsOpen() const;
147
+ int ChildCount() const;
148
+ private:
149
+ //PolyNode& operator =(PolyNode& other);
150
+ unsigned Index; //node index in Parent.Childs
151
+ bool m_IsOpen;
152
+ JoinType m_jointype;
153
+ EndType m_endtype;
154
+ PolyNode* GetNextSiblingUp() const;
155
+ void AddChild(PolyNode& child);
156
+ friend class Clipper; //to access Index
157
+ friend class ClipperOffset;
158
+ };
159
+
160
+ class PolyTree: public PolyNode
161
+ {
162
+ public:
163
+ ~PolyTree(){ Clear(); };
164
+ PolyNode* GetFirst() const;
165
+ void Clear();
166
+ int Total() const;
167
+ private:
168
+ //PolyTree& operator =(PolyTree& other);
169
+ PolyNodes AllNodes;
170
+ friend class Clipper; //to access AllNodes
171
+ };
172
+
173
+ bool Orientation(const Path &poly);
174
+ double Area(const Path &poly);
175
+ int PointInPolygon(const IntPoint &pt, const Path &path);
176
+
177
+ void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
178
+ void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
179
+ void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
180
+
181
+ void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
182
+ void CleanPolygon(Path& poly, double distance = 1.415);
183
+ void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
184
+ void CleanPolygons(Paths& polys, double distance = 1.415);
185
+
186
+ void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
187
+ void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
188
+ void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
189
+
190
+ void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
191
+ void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
192
+ void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
193
+
194
+ void ReversePath(Path& p);
195
+ void ReversePaths(Paths& p);
196
+
197
+ struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
198
+
199
+ //enums that are used internally ...
200
+ enum EdgeSide { esLeft = 1, esRight = 2};
201
+
202
+ //forward declarations (for stuff used internally) ...
203
+ struct TEdge;
204
+ struct IntersectNode;
205
+ struct LocalMinimum;
206
+ struct OutPt;
207
+ struct OutRec;
208
+ struct Join;
209
+
210
+ typedef std::vector < OutRec* > PolyOutList;
211
+ typedef std::vector < TEdge* > EdgeList;
212
+ typedef std::vector < Join* > JoinList;
213
+ typedef std::vector < IntersectNode* > IntersectList;
214
+
215
+ //------------------------------------------------------------------------------
216
+
217
+ //ClipperBase is the ancestor to the Clipper class. It should not be
218
+ //instantiated directly. This class simply abstracts the conversion of sets of
219
+ //polygon coordinates into edge objects that are stored in a LocalMinima list.
220
+ class ClipperBase
221
+ {
222
+ public:
223
+ ClipperBase();
224
+ virtual ~ClipperBase();
225
+ virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
226
+ bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
227
+ virtual void Clear();
228
+ IntRect GetBounds();
229
+ bool PreserveCollinear() {return m_PreserveCollinear;};
230
+ void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
231
+ protected:
232
+ void DisposeLocalMinimaList();
233
+ TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
234
+ virtual void Reset();
235
+ TEdge* ProcessBound(TEdge* E, bool IsClockwise);
236
+ void InsertScanbeam(const cInt Y);
237
+ bool PopScanbeam(cInt &Y);
238
+ bool LocalMinimaPending();
239
+ bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
240
+ OutRec* CreateOutRec();
241
+ void DisposeAllOutRecs();
242
+ void DisposeOutRec(PolyOutList::size_type index);
243
+ void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
244
+ void DeleteFromAEL(TEdge *e);
245
+ void UpdateEdgeIntoAEL(TEdge *&e);
246
+
247
+ typedef std::vector<LocalMinimum> MinimaList;
248
+ MinimaList::iterator m_CurrentLM;
249
+ MinimaList m_MinimaList;
250
+
251
+ bool m_UseFullRange;
252
+ EdgeList m_edges;
253
+ bool m_PreserveCollinear;
254
+ bool m_HasOpenPaths;
255
+ PolyOutList m_PolyOuts;
256
+ TEdge *m_ActiveEdges;
257
+
258
+ typedef std::priority_queue<cInt> ScanbeamList;
259
+ ScanbeamList m_Scanbeam;
260
+ };
261
+ //------------------------------------------------------------------------------
262
+
263
+ class Clipper : public virtual ClipperBase
264
+ {
265
+ public:
266
+ Clipper(int initOptions = 0);
267
+ bool Execute(ClipType clipType,
268
+ Paths &solution,
269
+ PolyFillType fillType = pftEvenOdd);
270
+ bool Execute(ClipType clipType,
271
+ Paths &solution,
272
+ PolyFillType subjFillType,
273
+ PolyFillType clipFillType);
274
+ bool Execute(ClipType clipType,
275
+ PolyTree &polytree,
276
+ PolyFillType fillType = pftEvenOdd);
277
+ bool Execute(ClipType clipType,
278
+ PolyTree &polytree,
279
+ PolyFillType subjFillType,
280
+ PolyFillType clipFillType);
281
+ bool ReverseSolution() { return m_ReverseOutput; };
282
+ void ReverseSolution(bool value) {m_ReverseOutput = value;};
283
+ bool StrictlySimple() {return m_StrictSimple;};
284
+ void StrictlySimple(bool value) {m_StrictSimple = value;};
285
+ //set the callback function for z value filling on intersections (otherwise Z is 0)
286
+ #ifdef use_xyz
287
+ void ZFillFunction(ZFillCallback zFillFunc);
288
+ #endif
289
+ protected:
290
+ virtual bool ExecuteInternal();
291
+ private:
292
+ JoinList m_Joins;
293
+ JoinList m_GhostJoins;
294
+ IntersectList m_IntersectList;
295
+ ClipType m_ClipType;
296
+ typedef std::list<cInt> MaximaList;
297
+ MaximaList m_Maxima;
298
+ TEdge *m_SortedEdges;
299
+ bool m_ExecuteLocked;
300
+ PolyFillType m_ClipFillType;
301
+ PolyFillType m_SubjFillType;
302
+ bool m_ReverseOutput;
303
+ bool m_UsingPolyTree;
304
+ bool m_StrictSimple;
305
+ #ifdef use_xyz
306
+ ZFillCallback m_ZFill; //custom callback
307
+ #endif
308
+ void SetWindingCount(TEdge& edge);
309
+ bool IsEvenOddFillType(const TEdge& edge) const;
310
+ bool IsEvenOddAltFillType(const TEdge& edge) const;
311
+ void InsertLocalMinimaIntoAEL(const cInt botY);
312
+ void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
313
+ void AddEdgeToSEL(TEdge *edge);
314
+ bool PopEdgeFromSEL(TEdge *&edge);
315
+ void CopyAELToSEL();
316
+ void DeleteFromSEL(TEdge *e);
317
+ void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
318
+ bool IsContributing(const TEdge& edge) const;
319
+ bool IsTopHorz(const cInt XPos);
320
+ void DoMaxima(TEdge *e);
321
+ void ProcessHorizontals();
322
+ void ProcessHorizontal(TEdge *horzEdge);
323
+ void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
324
+ OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
325
+ OutRec* GetOutRec(int idx);
326
+ void AppendPolygon(TEdge *e1, TEdge *e2);
327
+ void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
328
+ OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
329
+ OutPt* GetLastOutPt(TEdge *e);
330
+ bool ProcessIntersections(const cInt topY);
331
+ void BuildIntersectList(const cInt topY);
332
+ void ProcessIntersectList();
333
+ void ProcessEdgesAtTopOfScanbeam(const cInt topY);
334
+ void BuildResult(Paths& polys);
335
+ void BuildResult2(PolyTree& polytree);
336
+ void SetHoleState(TEdge *e, OutRec *outrec);
337
+ void DisposeIntersectNodes();
338
+ bool FixupIntersectionOrder();
339
+ void FixupOutPolygon(OutRec &outrec);
340
+ void FixupOutPolyline(OutRec &outrec);
341
+ bool IsHole(TEdge *e);
342
+ bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
343
+ void FixHoleLinkage(OutRec &outrec);
344
+ void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
345
+ void ClearJoins();
346
+ void ClearGhostJoins();
347
+ void AddGhostJoin(OutPt *op, const IntPoint offPt);
348
+ bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
349
+ void JoinCommonEdges();
350
+ void DoSimplePolygons();
351
+ void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
352
+ void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
353
+ void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
354
+ #ifdef use_xyz
355
+ void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
356
+ #endif
357
+ };
358
+ //------------------------------------------------------------------------------
359
+
360
+ class ClipperOffset
361
+ {
362
+ public:
363
+ ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
364
+ ~ClipperOffset();
365
+ void AddPath(const Path& path, JoinType joinType, EndType endType);
366
+ void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
367
+ void Execute(Paths& solution, double delta);
368
+ void Execute(PolyTree& solution, double delta);
369
+ void Clear();
370
+ double MiterLimit;
371
+ double ArcTolerance;
372
+ private:
373
+ Paths m_destPolys;
374
+ Path m_srcPoly;
375
+ Path m_destPoly;
376
+ std::vector<DoublePoint> m_normals;
377
+ double m_delta, m_sinA, m_sin, m_cos;
378
+ double m_miterLim, m_StepsPerRad;
379
+ IntPoint m_lowest;
380
+ PolyNode m_polyNodes;
381
+
382
+ void FixOrientations();
383
+ void DoOffset(double delta);
384
+ void OffsetPoint(int j, int& k, JoinType jointype);
385
+ void DoSquare(int j, int k);
386
+ void DoMiter(int j, int k, double r);
387
+ void DoRound(int j, int k);
388
+ };
389
+ //------------------------------------------------------------------------------
390
+
391
+ class clipperException : public std::exception
392
+ {
393
+ public:
394
+ clipperException(const char* description): m_descr(description) {}
395
+ virtual ~clipperException() throw() {}
396
+ virtual const char* what() const throw() {return m_descr.c_str();}
397
+ private:
398
+ std::string m_descr;
399
+ };
400
+ //------------------------------------------------------------------------------
401
+
402
+ } //ClipperLib namespace
403
+
404
+ #endif //clipper_hpp
405
+
406
+
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
4
+
5
+ dir_config('clipper')
6
+ create_makefile('clipper')