ruby_clipper 5.0.3 → 6.2.1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +20 -22
- data/ext/clipper/clipper.cpp +3018 -1882
- data/ext/clipper/clipper.hpp +246 -159
- data/ext/clipper/rbclipper.cpp +119 -58
- data/lib/clipper/version.rb +1 -1
- metadata +7 -6
data/ext/clipper/clipper.hpp
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
/*******************************************************************************
|
2
2
|
* *
|
3
3
|
* Author : Angus Johnson *
|
4
|
-
* Version :
|
5
|
-
* Date :
|
4
|
+
* Version : 6.2.1 *
|
5
|
+
* Date : 31 October 2014 *
|
6
6
|
* Website : http://www.angusj.com *
|
7
|
-
* Copyright : Angus Johnson 2010-
|
7
|
+
* Copyright : Angus Johnson 2010-2014 *
|
8
8
|
* *
|
9
9
|
* License: *
|
10
10
|
* Use, modification & distribution is subject to Boost Software License Ver 1. *
|
@@ -26,7 +26,7 @@
|
|
26
26
|
* Paper no. DETC2005-85513 pp. 565-575 *
|
27
27
|
* ASME 2005 International Design Engineering Technical Conferences *
|
28
28
|
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
|
29
|
-
* September 24
|
29
|
+
* September 24-28, 2005 , Long Beach, California, USA *
|
30
30
|
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
|
31
31
|
* *
|
32
32
|
*******************************************************************************/
|
@@ -34,11 +34,29 @@
|
|
34
34
|
#ifndef clipper_hpp
|
35
35
|
#define clipper_hpp
|
36
36
|
|
37
|
+
#define CLIPPER_VERSION "6.2.0"
|
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
|
+
|
37
52
|
#include <vector>
|
53
|
+
#include <set>
|
38
54
|
#include <stdexcept>
|
39
55
|
#include <cstring>
|
40
56
|
#include <cstdlib>
|
41
57
|
#include <ostream>
|
58
|
+
#include <functional>
|
59
|
+
#include <queue>
|
42
60
|
|
43
61
|
namespace ClipperLib {
|
44
62
|
|
@@ -50,129 +68,149 @@ enum PolyType { ptSubject, ptClip };
|
|
50
68
|
//see http://glprogramming.com/red/chapter11.html
|
51
69
|
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
52
70
|
|
53
|
-
|
54
|
-
typedef
|
71
|
+
#ifdef use_int32
|
72
|
+
typedef int cInt;
|
73
|
+
static cInt const loRange = 0x7FFF;
|
74
|
+
static cInt const hiRange = 0x7FFF;
|
75
|
+
#else
|
76
|
+
typedef signed long long cInt;
|
77
|
+
static cInt const loRange = 0x3FFFFFFF;
|
78
|
+
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
79
|
+
typedef signed long long long64; //used by Int128 class
|
80
|
+
typedef unsigned long long ulong64;
|
81
|
+
|
82
|
+
#endif
|
55
83
|
|
56
84
|
struct IntPoint {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
85
|
+
cInt X;
|
86
|
+
cInt Y;
|
87
|
+
#ifdef use_xyz
|
88
|
+
cInt Z;
|
89
|
+
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
|
90
|
+
#else
|
91
|
+
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
|
92
|
+
#endif
|
93
|
+
|
94
|
+
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
|
95
|
+
{
|
96
|
+
return a.X == b.X && a.Y == b.Y;
|
97
|
+
}
|
98
|
+
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
|
99
|
+
{
|
100
|
+
return a.X != b.X || a.Y != b.Y;
|
101
|
+
}
|
62
102
|
};
|
103
|
+
//------------------------------------------------------------------------------
|
104
|
+
|
105
|
+
typedef std::vector< IntPoint > Path;
|
106
|
+
typedef std::vector< Path > Paths;
|
63
107
|
|
64
|
-
|
65
|
-
|
108
|
+
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
|
109
|
+
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
|
66
110
|
|
67
|
-
std::ostream& operator <<(std::ostream &s,
|
68
|
-
std::ostream& operator <<(std::ostream &s,
|
111
|
+
std::ostream& operator <<(std::ostream &s, const IntPoint &p);
|
112
|
+
std::ostream& operator <<(std::ostream &s, const Path &p);
|
113
|
+
std::ostream& operator <<(std::ostream &s, const Paths &p);
|
69
114
|
|
70
|
-
struct
|
71
|
-
|
72
|
-
|
115
|
+
struct DoublePoint
|
116
|
+
{
|
117
|
+
double X;
|
118
|
+
double Y;
|
119
|
+
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
|
120
|
+
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
|
73
121
|
};
|
74
|
-
|
122
|
+
//------------------------------------------------------------------------------
|
75
123
|
|
76
|
-
|
124
|
+
#ifdef use_xyz
|
125
|
+
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
|
126
|
+
#endif
|
77
127
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
double delta, JoinType jointype = jtSquare, double MiterLimit = 2, bool AutoFix = true);
|
82
|
-
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
|
83
|
-
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
|
84
|
-
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
|
128
|
+
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
|
129
|
+
enum JoinType {jtSquare, jtRound, jtMiter};
|
130
|
+
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
|
85
131
|
|
86
|
-
|
87
|
-
|
132
|
+
class PolyNode;
|
133
|
+
typedef std::vector< PolyNode* > PolyNodes;
|
88
134
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
TEdge *next;
|
111
|
-
TEdge *prev;
|
112
|
-
TEdge *nextInLML;
|
113
|
-
TEdge *nextInAEL;
|
114
|
-
TEdge *prevInAEL;
|
115
|
-
TEdge *nextInSEL;
|
116
|
-
TEdge *prevInSEL;
|
135
|
+
class PolyNode
|
136
|
+
{
|
137
|
+
public:
|
138
|
+
PolyNode();
|
139
|
+
virtual ~PolyNode(){};
|
140
|
+
Path Contour;
|
141
|
+
PolyNodes Childs;
|
142
|
+
PolyNode* Parent;
|
143
|
+
PolyNode* GetNext() const;
|
144
|
+
bool IsHole() const;
|
145
|
+
bool IsOpen() const;
|
146
|
+
int ChildCount() const;
|
147
|
+
private:
|
148
|
+
unsigned Index; //node index in Parent.Childs
|
149
|
+
bool m_IsOpen;
|
150
|
+
JoinType m_jointype;
|
151
|
+
EndType m_endtype;
|
152
|
+
PolyNode* GetNextSiblingUp() const;
|
153
|
+
void AddChild(PolyNode& child);
|
154
|
+
friend class Clipper; //to access Index
|
155
|
+
friend class ClipperOffset;
|
117
156
|
};
|
118
157
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
158
|
+
class PolyTree: public PolyNode
|
159
|
+
{
|
160
|
+
public:
|
161
|
+
~PolyTree(){Clear();};
|
162
|
+
PolyNode* GetFirst() const;
|
163
|
+
void Clear();
|
164
|
+
int Total() const;
|
165
|
+
private:
|
166
|
+
PolyNodes AllNodes;
|
167
|
+
friend class Clipper; //to access AllNodes
|
124
168
|
};
|
125
169
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
TEdge *rightBound;
|
130
|
-
LocalMinima *next;
|
131
|
-
};
|
170
|
+
bool Orientation(const Path &poly);
|
171
|
+
double Area(const Path &poly);
|
172
|
+
int PointInPolygon(const IntPoint &pt, const Path &path);
|
132
173
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
};
|
174
|
+
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
175
|
+
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
176
|
+
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
|
137
177
|
|
138
|
-
|
178
|
+
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
|
179
|
+
void CleanPolygon(Path& poly, double distance = 1.415);
|
180
|
+
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
|
181
|
+
void CleanPolygons(Paths& polys, double distance = 1.415);
|
139
182
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
OutRec *FirstLeft;
|
144
|
-
OutRec *AppendLink;
|
145
|
-
OutPt *pts;
|
146
|
-
OutPt *bottomPt;
|
147
|
-
};
|
183
|
+
void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
|
184
|
+
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
|
185
|
+
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
|
148
186
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
OutPt *next;
|
153
|
-
OutPt *prev;
|
154
|
-
};
|
187
|
+
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
|
188
|
+
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
|
189
|
+
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
|
155
190
|
|
156
|
-
|
157
|
-
|
158
|
-
IntPoint pt1b;
|
159
|
-
int poly1Idx;
|
160
|
-
IntPoint pt2a;
|
161
|
-
IntPoint pt2b;
|
162
|
-
int poly2Idx;
|
163
|
-
};
|
191
|
+
void ReversePath(Path& p);
|
192
|
+
void ReversePaths(Paths& p);
|
164
193
|
|
165
|
-
struct
|
166
|
-
|
167
|
-
|
168
|
-
};
|
194
|
+
struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
|
195
|
+
|
196
|
+
//enums that are used internally ...
|
197
|
+
enum EdgeSide { esLeft = 1, esRight = 2};
|
169
198
|
|
170
|
-
|
199
|
+
//forward declarations (for stuff used internally) ...
|
200
|
+
struct TEdge;
|
201
|
+
struct IntersectNode;
|
202
|
+
struct LocalMinimum;
|
203
|
+
struct Scanbeam;
|
204
|
+
struct OutPt;
|
205
|
+
struct OutRec;
|
206
|
+
struct Join;
|
171
207
|
|
172
208
|
typedef std::vector < OutRec* > PolyOutList;
|
173
209
|
typedef std::vector < TEdge* > EdgeList;
|
174
|
-
typedef std::vector <
|
175
|
-
typedef std::vector <
|
210
|
+
typedef std::vector < Join* > JoinList;
|
211
|
+
typedef std::vector < IntersectNode* > IntersectList;
|
212
|
+
|
213
|
+
//------------------------------------------------------------------------------
|
176
214
|
|
177
215
|
//ClipperBase is the ancestor to the Clipper class. It should not be
|
178
216
|
//instantiated directly. This class simply abstracts the conversion of sets of
|
@@ -182,63 +220,83 @@ class ClipperBase
|
|
182
220
|
public:
|
183
221
|
ClipperBase();
|
184
222
|
virtual ~ClipperBase();
|
185
|
-
bool
|
186
|
-
bool
|
223
|
+
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
224
|
+
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
187
225
|
virtual void Clear();
|
188
226
|
IntRect GetBounds();
|
227
|
+
bool PreserveCollinear() {return m_PreserveCollinear;};
|
228
|
+
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
|
189
229
|
protected:
|
190
230
|
void DisposeLocalMinimaList();
|
191
|
-
TEdge* AddBoundsToLML(TEdge *e);
|
231
|
+
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
|
192
232
|
void PopLocalMinima();
|
193
233
|
virtual void Reset();
|
194
|
-
|
195
|
-
|
196
|
-
|
234
|
+
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
|
235
|
+
void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed);
|
236
|
+
TEdge* DescendToMin(TEdge *&E);
|
237
|
+
void AscendToMax(TEdge *&E, bool Appending, bool IsClosed);
|
238
|
+
|
239
|
+
typedef std::vector<LocalMinimum> MinimaList;
|
240
|
+
MinimaList::iterator m_CurrentLM;
|
241
|
+
MinimaList m_MinimaList;
|
242
|
+
|
197
243
|
bool m_UseFullRange;
|
198
244
|
EdgeList m_edges;
|
245
|
+
bool m_PreserveCollinear;
|
246
|
+
bool m_HasOpenPaths;
|
199
247
|
};
|
248
|
+
//------------------------------------------------------------------------------
|
200
249
|
|
201
250
|
class Clipper : public virtual ClipperBase
|
202
251
|
{
|
203
252
|
public:
|
204
|
-
Clipper();
|
253
|
+
Clipper(int initOptions = 0);
|
205
254
|
~Clipper();
|
206
255
|
bool Execute(ClipType clipType,
|
207
|
-
|
208
|
-
|
209
|
-
|
256
|
+
Paths &solution,
|
257
|
+
PolyFillType subjFillType = pftEvenOdd,
|
258
|
+
PolyFillType clipFillType = pftEvenOdd);
|
210
259
|
bool Execute(ClipType clipType,
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
void Clear();
|
260
|
+
PolyTree &polytree,
|
261
|
+
PolyFillType subjFillType = pftEvenOdd,
|
262
|
+
PolyFillType clipFillType = pftEvenOdd);
|
215
263
|
bool ReverseSolution() {return m_ReverseOutput;};
|
216
264
|
void ReverseSolution(bool value) {m_ReverseOutput = value;};
|
265
|
+
bool StrictlySimple() {return m_StrictSimple;};
|
266
|
+
void StrictlySimple(bool value) {m_StrictSimple = value;};
|
267
|
+
//set the callback function for z value filling on intersections (otherwise Z is 0)
|
268
|
+
#ifdef use_xyz
|
269
|
+
void ZFillFunction(ZFillCallback zFillFunc);
|
270
|
+
#endif
|
217
271
|
protected:
|
218
272
|
void Reset();
|
219
273
|
virtual bool ExecuteInternal();
|
220
274
|
private:
|
221
275
|
PolyOutList m_PolyOuts;
|
222
276
|
JoinList m_Joins;
|
223
|
-
|
277
|
+
JoinList m_GhostJoins;
|
278
|
+
IntersectList m_IntersectList;
|
224
279
|
ClipType m_ClipType;
|
225
|
-
|
280
|
+
typedef std::priority_queue<cInt> ScanbeamList;
|
281
|
+
ScanbeamList m_Scanbeam;
|
226
282
|
TEdge *m_ActiveEdges;
|
227
283
|
TEdge *m_SortedEdges;
|
228
|
-
|
229
|
-
|
230
|
-
PolyFillType
|
231
|
-
|
232
|
-
bool
|
233
|
-
bool
|
234
|
-
|
284
|
+
bool m_ExecuteLocked;
|
285
|
+
PolyFillType m_ClipFillType;
|
286
|
+
PolyFillType m_SubjFillType;
|
287
|
+
bool m_ReverseOutput;
|
288
|
+
bool m_UsingPolyTree;
|
289
|
+
bool m_StrictSimple;
|
290
|
+
#ifdef use_xyz
|
291
|
+
ZFillCallback m_ZFill; //custom callback
|
292
|
+
#endif
|
235
293
|
void SetWindingCount(TEdge& edge);
|
236
294
|
bool IsEvenOddFillType(const TEdge& edge) const;
|
237
295
|
bool IsEvenOddAltFillType(const TEdge& edge) const;
|
238
|
-
void InsertScanbeam(const
|
239
|
-
|
240
|
-
void InsertLocalMinimaIntoAEL(const
|
241
|
-
void InsertEdgeIntoAEL(TEdge *edge);
|
296
|
+
void InsertScanbeam(const cInt Y);
|
297
|
+
cInt PopScanbeam();
|
298
|
+
void InsertLocalMinimaIntoAEL(const cInt botY);
|
299
|
+
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
|
242
300
|
void AddEdgeToSEL(TEdge *edge);
|
243
301
|
void CopyAELToSEL();
|
244
302
|
void DeleteFromSEL(TEdge *e);
|
@@ -246,46 +304,77 @@ private:
|
|
246
304
|
void UpdateEdgeIntoAEL(TEdge *&e);
|
247
305
|
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
|
248
306
|
bool IsContributing(const TEdge& edge) const;
|
249
|
-
bool IsTopHorz(const
|
307
|
+
bool IsTopHorz(const cInt XPos);
|
250
308
|
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
|
251
|
-
void DoMaxima(TEdge *e
|
252
|
-
void ProcessHorizontals();
|
253
|
-
void ProcessHorizontal(TEdge *horzEdge);
|
309
|
+
void DoMaxima(TEdge *e);
|
310
|
+
void ProcessHorizontals(bool IsTopOfScanbeam);
|
311
|
+
void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam);
|
254
312
|
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
255
|
-
|
313
|
+
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
314
|
+
OutRec* GetOutRec(int idx);
|
256
315
|
void AppendPolygon(TEdge *e1, TEdge *e2);
|
257
|
-
void
|
258
|
-
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
|
259
|
-
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
|
260
|
-
void IntersectEdges(TEdge *e1, TEdge *e2,
|
261
|
-
const IntPoint &pt, const IntersectProtects protects);
|
316
|
+
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
|
262
317
|
OutRec* CreateOutRec();
|
263
|
-
|
264
|
-
void
|
318
|
+
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
|
319
|
+
void DisposeAllOutRecs();
|
265
320
|
void DisposeOutRec(PolyOutList::size_type index);
|
266
|
-
bool ProcessIntersections(const
|
267
|
-
void
|
268
|
-
void BuildIntersectList(const long64 botY, const long64 topY);
|
321
|
+
bool ProcessIntersections(const cInt topY);
|
322
|
+
void BuildIntersectList(const cInt topY);
|
269
323
|
void ProcessIntersectList();
|
270
|
-
void ProcessEdgesAtTopOfScanbeam(const
|
271
|
-
void BuildResult(
|
272
|
-
void
|
273
|
-
void SetHoleState(TEdge *e, OutRec *
|
324
|
+
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
|
325
|
+
void BuildResult(Paths& polys);
|
326
|
+
void BuildResult2(PolyTree& polytree);
|
327
|
+
void SetHoleState(TEdge *e, OutRec *outrec);
|
274
328
|
void DisposeIntersectNodes();
|
275
|
-
bool
|
276
|
-
void FixupOutPolygon(OutRec &
|
329
|
+
bool FixupIntersectionOrder();
|
330
|
+
void FixupOutPolygon(OutRec &outrec);
|
277
331
|
bool IsHole(TEdge *e);
|
278
|
-
|
279
|
-
void
|
332
|
+
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
|
333
|
+
void FixHoleLinkage(OutRec &outrec);
|
334
|
+
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
|
280
335
|
void ClearJoins();
|
281
|
-
void
|
282
|
-
void
|
283
|
-
bool JoinPoints(
|
284
|
-
void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx);
|
336
|
+
void ClearGhostJoins();
|
337
|
+
void AddGhostJoin(OutPt *op, const IntPoint offPt);
|
338
|
+
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
|
285
339
|
void JoinCommonEdges();
|
340
|
+
void DoSimplePolygons();
|
341
|
+
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
|
342
|
+
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
|
343
|
+
#ifdef use_xyz
|
344
|
+
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
|
345
|
+
#endif
|
286
346
|
};
|
287
|
-
|
288
347
|
//------------------------------------------------------------------------------
|
348
|
+
|
349
|
+
class ClipperOffset
|
350
|
+
{
|
351
|
+
public:
|
352
|
+
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
|
353
|
+
~ClipperOffset();
|
354
|
+
void AddPath(const Path& path, JoinType joinType, EndType endType);
|
355
|
+
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
|
356
|
+
void Execute(Paths& solution, double delta);
|
357
|
+
void Execute(PolyTree& solution, double delta);
|
358
|
+
void Clear();
|
359
|
+
double MiterLimit;
|
360
|
+
double ArcTolerance;
|
361
|
+
private:
|
362
|
+
Paths m_destPolys;
|
363
|
+
Path m_srcPoly;
|
364
|
+
Path m_destPoly;
|
365
|
+
std::vector<DoublePoint> m_normals;
|
366
|
+
double m_delta, m_sinA, m_sin, m_cos;
|
367
|
+
double m_miterLim, m_StepsPerRad;
|
368
|
+
IntPoint m_lowest;
|
369
|
+
PolyNode m_polyNodes;
|
370
|
+
|
371
|
+
void FixOrientations();
|
372
|
+
void DoOffset(double delta);
|
373
|
+
void OffsetPoint(int j, int& k, JoinType jointype);
|
374
|
+
void DoSquare(int j, int k);
|
375
|
+
void DoMiter(int j, int k, double r);
|
376
|
+
void DoRound(int j, int k);
|
377
|
+
};
|
289
378
|
//------------------------------------------------------------------------------
|
290
379
|
|
291
380
|
class clipperException : public std::exception
|
@@ -302,5 +391,3 @@ class clipperException : public std::exception
|
|
302
391
|
} //ClipperLib namespace
|
303
392
|
|
304
393
|
#endif //clipper_hpp
|
305
|
-
|
306
|
-
|