rbclipper 6.4.2.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Changelog +13 -0
- data/Gemfile +4 -0
- data/LICENSE.bindings +4 -0
- data/LICENSE.clipper +29 -0
- data/README.md +188 -0
- data/Rakefile +15 -0
- data/ext/clipper/clipper.cpp +4629 -0
- data/ext/clipper/clipper.hpp +406 -0
- data/ext/clipper/extconf.rb +6 -0
- data/ext/clipper/rbclipper.cpp +530 -0
- data/lib/clipper/version.rb +6 -0
- metadata +135 -0
@@ -0,0 +1,530 @@
|
|
1
|
+
/*
|
2
|
+
* Clipper Ruby Bindings
|
3
|
+
* Copyright 2010 Mike Owens <http://mike.filespanker.com/>
|
4
|
+
* Changed by Dag Rende for Clipper after 2.9
|
5
|
+
*
|
6
|
+
* Released under the same terms as Clipper.
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include "clipper.hpp"
|
11
|
+
#include <ruby.h>
|
12
|
+
|
13
|
+
#ifndef DBL2NUM
|
14
|
+
# define DBL2NUM rb_float_new
|
15
|
+
#endif
|
16
|
+
|
17
|
+
using namespace std;
|
18
|
+
using namespace ClipperLib;
|
19
|
+
|
20
|
+
static ID id_even_odd;
|
21
|
+
static ID id_non_zero;
|
22
|
+
static ID id_positive;
|
23
|
+
static ID id_negative;
|
24
|
+
static ID id_polygons;
|
25
|
+
static ID id_ex_polygons;
|
26
|
+
static ID id_jtSquare;
|
27
|
+
static ID id_jtMiter;
|
28
|
+
static ID id_jtRound;
|
29
|
+
static ID id_etClosedPolygon;
|
30
|
+
static ID id_etClosedLine;
|
31
|
+
static ID id_etOpenButt;
|
32
|
+
static ID id_etOpenSquare;
|
33
|
+
static ID id_etOpenRound;
|
34
|
+
|
35
|
+
static inline Clipper*
|
36
|
+
XCLIPPER(VALUE x)
|
37
|
+
{
|
38
|
+
Clipper* clipper;
|
39
|
+
Data_Get_Struct(x, Clipper, clipper);
|
40
|
+
return clipper;
|
41
|
+
}
|
42
|
+
|
43
|
+
static inline ClipperOffset*
|
44
|
+
XCLIPPEROFFSET(VALUE x)
|
45
|
+
{
|
46
|
+
ClipperOffset* clipperOffset;
|
47
|
+
Data_Get_Struct(x, ClipperOffset, clipperOffset);
|
48
|
+
return clipperOffset;
|
49
|
+
}
|
50
|
+
|
51
|
+
static inline PolyFillType
|
52
|
+
sym_to_filltype(VALUE sym)
|
53
|
+
{
|
54
|
+
ID inp = rb_to_id(sym);
|
55
|
+
|
56
|
+
if (inp == id_even_odd) {
|
57
|
+
return pftEvenOdd;
|
58
|
+
} else if (inp == id_non_zero) {
|
59
|
+
return pftNonZero;
|
60
|
+
} else if (inp == id_positive) {
|
61
|
+
return pftPositive;
|
62
|
+
} else if (inp == id_negative) {
|
63
|
+
return pftNegative;
|
64
|
+
}
|
65
|
+
|
66
|
+
rb_raise(rb_eArgError, "%s", "Expected :even_odd, :non_zero, :positive or :negative");
|
67
|
+
}
|
68
|
+
|
69
|
+
static inline EndType
|
70
|
+
sym_to_endtype(VALUE sym)
|
71
|
+
{
|
72
|
+
ID inp = rb_to_id(sym);
|
73
|
+
|
74
|
+
if (inp == id_etClosedPolygon) {
|
75
|
+
return etClosedPolygon;
|
76
|
+
} else if (inp == id_etClosedLine) {
|
77
|
+
return etClosedLine;
|
78
|
+
} else if (inp == id_etOpenButt) {
|
79
|
+
return etOpenButt;
|
80
|
+
} else if (inp == id_etOpenSquare) {
|
81
|
+
return etOpenSquare;
|
82
|
+
} else if (inp == id_etOpenRound) {
|
83
|
+
return etOpenRound;
|
84
|
+
}
|
85
|
+
|
86
|
+
rb_raise(rb_eArgError, "%s", "Expected :etClosedPolygon, :etClosedLine or :etOpenButt or :etOpenSquare or :etOpenRound");
|
87
|
+
}
|
88
|
+
|
89
|
+
static inline JoinType
|
90
|
+
sym_to_jointype(VALUE sym)
|
91
|
+
{
|
92
|
+
ID inp = rb_to_id(sym);
|
93
|
+
|
94
|
+
if (inp == id_jtSquare) {
|
95
|
+
return jtSquare;
|
96
|
+
} else if (inp == id_jtMiter) {
|
97
|
+
return jtMiter;
|
98
|
+
} else if (inp == id_jtRound) {
|
99
|
+
return jtRound;
|
100
|
+
}
|
101
|
+
|
102
|
+
rb_raise(rb_eArgError, "%s", "Expected :jtSquare, :jtMiter or :jtRound");
|
103
|
+
}
|
104
|
+
|
105
|
+
extern "C" {
|
106
|
+
|
107
|
+
static inline IntPoint
|
108
|
+
xy_to_intpoint(VALUE px, VALUE py, double multiplier) {
|
109
|
+
return IntPoint((long64)(NUM2DBL(px) * multiplier), (long64)(NUM2DBL(py) * multiplier));
|
110
|
+
}
|
111
|
+
|
112
|
+
static void
|
113
|
+
ary_to_polygon(VALUE ary, ClipperLib::Path* poly, double multiplier)
|
114
|
+
{
|
115
|
+
const char* earg =
|
116
|
+
"Paths have format: [[p0_x, p0_y], [p1_x, p1_y], ...]";
|
117
|
+
|
118
|
+
Check_Type(ary, T_ARRAY);
|
119
|
+
|
120
|
+
for(long i = 0; i != RARRAY_LEN(ary); i++) {
|
121
|
+
VALUE sub = rb_ary_entry(ary, i);
|
122
|
+
Check_Type(sub, T_ARRAY);
|
123
|
+
|
124
|
+
if(RARRAY_LEN(sub) != 2) {
|
125
|
+
rb_raise(rb_eArgError, "%s", earg);
|
126
|
+
}
|
127
|
+
|
128
|
+
VALUE px = rb_ary_entry(sub, 0);
|
129
|
+
VALUE py = rb_ary_entry(sub, 1);
|
130
|
+
poly->push_back(IntPoint((long64)(NUM2DBL(px) * multiplier), (long64)(NUM2DBL(py) * multiplier)));
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
static void
|
135
|
+
arys_to_polygons(VALUE polygonsValue, ClipperLib::Paths* polygons, const double multiplier)
|
136
|
+
{
|
137
|
+
for(long i = 0; i != RARRAY_LEN(polygonsValue); i++) {
|
138
|
+
VALUE sub = rb_ary_entry(polygonsValue, i);
|
139
|
+
Check_Type(sub, T_ARRAY);
|
140
|
+
|
141
|
+
ClipperLib::Path tmp;
|
142
|
+
ary_to_polygon(sub, &tmp, multiplier);
|
143
|
+
polygons->push_back(tmp);
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
static void
|
148
|
+
rbclipper_free(void* ptr)
|
149
|
+
{
|
150
|
+
delete (Clipper*) ptr;
|
151
|
+
}
|
152
|
+
|
153
|
+
static void
|
154
|
+
rbclipperoffset_free(void* ptr)
|
155
|
+
{
|
156
|
+
delete (ClipperOffset*) ptr;
|
157
|
+
}
|
158
|
+
|
159
|
+
static VALUE
|
160
|
+
rbclipper_new(VALUE klass)
|
161
|
+
{
|
162
|
+
Clipper* ptr = new Clipper;
|
163
|
+
VALUE r = Data_Wrap_Struct(klass, 0, rbclipper_free, ptr);
|
164
|
+
rb_obj_call_init(r, 0, 0);
|
165
|
+
rb_iv_set(r, "@multiplier", INT2NUM(1048576));
|
166
|
+
return r;
|
167
|
+
}
|
168
|
+
|
169
|
+
static VALUE
|
170
|
+
rbclipperoffset_new(VALUE klass)
|
171
|
+
{
|
172
|
+
ClipperOffset* ptr = new ClipperOffset;
|
173
|
+
VALUE r = Data_Wrap_Struct(klass, 0, rbclipperoffset_free, ptr);
|
174
|
+
rb_obj_call_init(r, 0, 0);
|
175
|
+
rb_iv_set(r, "@multiplier", INT2NUM(1048576));
|
176
|
+
return r;
|
177
|
+
}
|
178
|
+
|
179
|
+
static VALUE
|
180
|
+
rbclipper_add_polygon_internal(VALUE self, VALUE polygon,
|
181
|
+
PolyType polytype, bool closed = true)
|
182
|
+
{
|
183
|
+
ClipperLib::Path tmp;
|
184
|
+
double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
185
|
+
ary_to_polygon(polygon, &tmp, multiplier);
|
186
|
+
XCLIPPER(self)->AddPath(tmp, polytype, closed);
|
187
|
+
return Qnil;
|
188
|
+
}
|
189
|
+
|
190
|
+
static VALUE
|
191
|
+
rbclipper_add_polygons_internal(VALUE self, VALUE polygonsValue, PolyType polytype, bool closed = true) {
|
192
|
+
Paths tmp;
|
193
|
+
const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
194
|
+
arys_to_polygons(polygonsValue, &tmp, multiplier);
|
195
|
+
XCLIPPER(self)->AddPaths(tmp, polytype, closed);
|
196
|
+
return Qnil;
|
197
|
+
}
|
198
|
+
|
199
|
+
static VALUE
|
200
|
+
rbclipper_minkowski_sum(VALUE self, VALUE patternValue, VALUE pathsValue, bool isClosed = true) {
|
201
|
+
Paths paths;
|
202
|
+
const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
203
|
+
arys_to_polygons(pathsValue, &paths, multiplier);
|
204
|
+
|
205
|
+
Path pattern;
|
206
|
+
ary_to_polygon(patternValue, &pattern, multiplier);
|
207
|
+
|
208
|
+
Paths solution;
|
209
|
+
ClipperLib::MinkowskiSum(pattern, paths, solution, isClosed);
|
210
|
+
|
211
|
+
const double inv_multiplier = 1.0 / multiplier;
|
212
|
+
|
213
|
+
VALUE r = rb_ary_new();
|
214
|
+
for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
|
215
|
+
VALUE sub = rb_ary_new();
|
216
|
+
for(Path::iterator p = i->begin(); p != i->end(); ++p) {
|
217
|
+
rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
|
218
|
+
}
|
219
|
+
rb_ary_push(r, sub);
|
220
|
+
}
|
221
|
+
return r;
|
222
|
+
}
|
223
|
+
|
224
|
+
static VALUE
|
225
|
+
rbclipper_minkowski_diff(VALUE self, VALUE poly1v, VALUE poly2v) {
|
226
|
+
const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
227
|
+
Path poly1;
|
228
|
+
ary_to_polygon(poly1v, &poly1, multiplier);
|
229
|
+
Path poly2;
|
230
|
+
ary_to_polygon(poly2v, &poly2, multiplier);
|
231
|
+
|
232
|
+
Paths solution;
|
233
|
+
ClipperLib::MinkowskiDiff(poly1, poly2, solution);
|
234
|
+
|
235
|
+
const double inv_multiplier = 1.0 / multiplier;
|
236
|
+
|
237
|
+
VALUE r = rb_ary_new();
|
238
|
+
for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
|
239
|
+
VALUE sub = rb_ary_new();
|
240
|
+
for(Path::iterator p = i->begin(); p != i->end(); ++p) {
|
241
|
+
rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
|
242
|
+
}
|
243
|
+
rb_ary_push(r, sub);
|
244
|
+
}
|
245
|
+
return r;
|
246
|
+
}
|
247
|
+
|
248
|
+
static VALUE
|
249
|
+
rbclipper_add_subject_polyline(VALUE self, VALUE polyline)
|
250
|
+
{
|
251
|
+
return rbclipper_add_polygon_internal(self, polyline, ptSubject, false);
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE
|
255
|
+
rbclipper_add_subject_polylines(VALUE self, VALUE polylines)
|
256
|
+
{
|
257
|
+
return rbclipper_add_polygons_internal(self, polylines, ptSubject, false);
|
258
|
+
}
|
259
|
+
|
260
|
+
static VALUE
|
261
|
+
rbclipper_add_subject_polygon(VALUE self, VALUE polygon)
|
262
|
+
{
|
263
|
+
return rbclipper_add_polygon_internal(self, polygon, ptSubject);
|
264
|
+
}
|
265
|
+
|
266
|
+
static VALUE
|
267
|
+
rbclipper_add_clip_polygon(VALUE self, VALUE polygon)
|
268
|
+
{
|
269
|
+
return rbclipper_add_polygon_internal(self, polygon, ptClip);
|
270
|
+
}
|
271
|
+
|
272
|
+
static VALUE
|
273
|
+
rbclipper_add_subject_polygons(VALUE self, VALUE polygons)
|
274
|
+
{
|
275
|
+
return rbclipper_add_polygons_internal(self, polygons, ptSubject);
|
276
|
+
}
|
277
|
+
|
278
|
+
static VALUE
|
279
|
+
rbclipper_add_clip_polygons(VALUE self, VALUE polygons)
|
280
|
+
{
|
281
|
+
return rbclipper_add_polygons_internal(self, polygons, ptClip);
|
282
|
+
}
|
283
|
+
|
284
|
+
static VALUE
|
285
|
+
rbclipper_clear(VALUE self)
|
286
|
+
{
|
287
|
+
XCLIPPER(self)->Clear();
|
288
|
+
return Qnil;
|
289
|
+
}
|
290
|
+
|
291
|
+
static VALUE
|
292
|
+
rbclipperoffset_clear(VALUE self)
|
293
|
+
{
|
294
|
+
XCLIPPEROFFSET(self)->Clear();
|
295
|
+
return Qnil;
|
296
|
+
}
|
297
|
+
|
298
|
+
static VALUE
|
299
|
+
rbclipper_multiplier(VALUE self)
|
300
|
+
{
|
301
|
+
return rb_iv_get(self, "@multiplier");
|
302
|
+
}
|
303
|
+
|
304
|
+
static VALUE
|
305
|
+
rbclipper_multiplier_eq(VALUE self, VALUE multiplier)
|
306
|
+
{
|
307
|
+
rb_iv_set(self, "@multiplier", multiplier);
|
308
|
+
return multiplier;
|
309
|
+
}
|
310
|
+
|
311
|
+
static VALUE
|
312
|
+
rbclipper_orientation(VALUE self, VALUE polygonValue)
|
313
|
+
{
|
314
|
+
double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
315
|
+
ClipperLib::Path polygon;
|
316
|
+
ary_to_polygon(polygonValue, &polygon, multiplier);
|
317
|
+
|
318
|
+
return ClipperLib::Orientation(polygon) ? Qtrue : Qfalse;
|
319
|
+
}
|
320
|
+
|
321
|
+
static VALUE
|
322
|
+
rbclipper_area(VALUE self, VALUE polygonValue)
|
323
|
+
{
|
324
|
+
double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
325
|
+
ClipperLib::Path polygon;
|
326
|
+
ary_to_polygon(polygonValue, &polygon, multiplier);
|
327
|
+
|
328
|
+
return DBL2NUM(ClipperLib::Area(polygon) / multiplier / multiplier);
|
329
|
+
}
|
330
|
+
|
331
|
+
static VALUE
|
332
|
+
rbclipper_point_in_polygon(VALUE self, VALUE px, VALUE py, VALUE polygonValue)
|
333
|
+
{
|
334
|
+
double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
335
|
+
ClipperLib::Path polygon;
|
336
|
+
ary_to_polygon(polygonValue, &polygon, multiplier);
|
337
|
+
|
338
|
+
return INT2NUM(ClipperLib::PointInPolygon(xy_to_intpoint(px, py, multiplier), polygon));
|
339
|
+
}
|
340
|
+
|
341
|
+
static VALUE
|
342
|
+
rbclipper_offset_polygons(int argc, VALUE* argv, VALUE self)
|
343
|
+
{
|
344
|
+
const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
|
345
|
+
const double inv_multiplier = 1.0 / multiplier;
|
346
|
+
VALUE polygonsValue, deltaValue, joinTypeValue, endTypeValue;
|
347
|
+
|
348
|
+
rb_scan_args(argc, argv, "31", &polygonsValue, &deltaValue, &joinTypeValue, &endTypeValue);
|
349
|
+
|
350
|
+
Paths polygons;
|
351
|
+
arys_to_polygons(polygonsValue, &polygons, multiplier);
|
352
|
+
|
353
|
+
Paths resultPaths;
|
354
|
+
XCLIPPEROFFSET(self)->AddPaths(polygons, sym_to_jointype(joinTypeValue), sym_to_endtype(endTypeValue));
|
355
|
+
XCLIPPEROFFSET(self)->Execute(resultPaths, NUM2DBL(deltaValue) * multiplier);
|
356
|
+
|
357
|
+
VALUE r = rb_ary_new();
|
358
|
+
for(Paths::iterator i = resultPaths.begin(); i != resultPaths.end(); ++i) {
|
359
|
+
VALUE sub = rb_ary_new();
|
360
|
+
for(Path::iterator p = i->begin(); p != i->end(); ++p) {
|
361
|
+
rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
|
362
|
+
}
|
363
|
+
rb_ary_push(r, sub);
|
364
|
+
}
|
365
|
+
return r;
|
366
|
+
}
|
367
|
+
|
368
|
+
static VALUE
|
369
|
+
rbclipper_execute_internal(VALUE self, ClipType cliptype,
|
370
|
+
VALUE subjfill, VALUE clipfill, VALUE resulttype)
|
371
|
+
{
|
372
|
+
if (NIL_P(subjfill)) {
|
373
|
+
subjfill = ID2SYM(id_even_odd);
|
374
|
+
}
|
375
|
+
|
376
|
+
if (NIL_P(clipfill)) {
|
377
|
+
clipfill = ID2SYM(id_even_odd);
|
378
|
+
}
|
379
|
+
|
380
|
+
if (NIL_P(resulttype)) {
|
381
|
+
resulttype = ID2SYM(id_polygons);
|
382
|
+
}
|
383
|
+
|
384
|
+
double inv_multiplier = 1.0 / NUM2LONG(rb_iv_get(self, "@multiplier"));
|
385
|
+
|
386
|
+
VALUE r = rb_ary_new();
|
387
|
+
if (resulttype == ID2SYM(id_polygons)) {
|
388
|
+
PolyTree polytree;
|
389
|
+
Paths solution;
|
390
|
+
XCLIPPER(self)->Execute((ClipType) cliptype,
|
391
|
+
polytree,
|
392
|
+
sym_to_filltype(subjfill),
|
393
|
+
sym_to_filltype(clipfill));
|
394
|
+
ClosedPathsFromPolyTree(polytree, solution);
|
395
|
+
for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
|
396
|
+
VALUE sub = rb_ary_new();
|
397
|
+
for(Path::iterator p = i->begin(); p != i->end(); ++p) {
|
398
|
+
rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
|
399
|
+
}
|
400
|
+
rb_ary_push(r, sub);
|
401
|
+
}
|
402
|
+
#ifdef use_lines
|
403
|
+
OpenPathsFromPolyTree(polytree, solution);
|
404
|
+
for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
|
405
|
+
VALUE sub = rb_ary_new();
|
406
|
+
rb_ary_push(sub, Qnil);
|
407
|
+
for(Path::iterator p = i->begin(); p != i->end(); ++p) {
|
408
|
+
rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
|
409
|
+
}
|
410
|
+
rb_ary_push(r, sub);
|
411
|
+
}
|
412
|
+
#endif
|
413
|
+
}
|
414
|
+
return r;
|
415
|
+
}
|
416
|
+
|
417
|
+
static VALUE
|
418
|
+
rbclipper_intersection(int argc, VALUE* argv, VALUE self)
|
419
|
+
{
|
420
|
+
VALUE subjfill, clipfill, resulttype;
|
421
|
+
rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
|
422
|
+
return rbclipper_execute_internal(self, ctIntersection, subjfill, clipfill, resulttype);
|
423
|
+
}
|
424
|
+
|
425
|
+
static VALUE
|
426
|
+
rbclipper_union(int argc, VALUE* argv, VALUE self)
|
427
|
+
{
|
428
|
+
VALUE subjfill, clipfill, resulttype;
|
429
|
+
rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
|
430
|
+
return rbclipper_execute_internal(self, ctUnion, subjfill, clipfill, resulttype);
|
431
|
+
}
|
432
|
+
|
433
|
+
|
434
|
+
static VALUE
|
435
|
+
rbclipper_difference(int argc, VALUE* argv, VALUE self)
|
436
|
+
{
|
437
|
+
VALUE subjfill, clipfill, resulttype;
|
438
|
+
rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
|
439
|
+
return rbclipper_execute_internal(self, ctDifference, subjfill, clipfill, resulttype);
|
440
|
+
}
|
441
|
+
|
442
|
+
|
443
|
+
static VALUE
|
444
|
+
rbclipper_xor(int argc, VALUE* argv, VALUE self)
|
445
|
+
{
|
446
|
+
VALUE subjfill, clipfill, resulttype;
|
447
|
+
rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
|
448
|
+
return rbclipper_execute_internal(self, ctXor, subjfill, clipfill, resulttype);
|
449
|
+
}
|
450
|
+
|
451
|
+
typedef VALUE (*ruby_method)(...);
|
452
|
+
|
453
|
+
void Init_clipper() {
|
454
|
+
|
455
|
+
id_even_odd = rb_intern("even_odd");
|
456
|
+
id_non_zero = rb_intern("non_zero");
|
457
|
+
id_positive = rb_intern("positive");
|
458
|
+
id_negative = rb_intern("negative");
|
459
|
+
id_polygons = rb_intern("polygons");
|
460
|
+
id_ex_polygons = rb_intern("expolygons");
|
461
|
+
id_jtSquare = rb_intern("jtSquare");
|
462
|
+
id_jtMiter = rb_intern("jtMiter");
|
463
|
+
id_jtRound = rb_intern("jtRound");
|
464
|
+
id_etClosedPolygon = rb_intern("etClosedPolygon");
|
465
|
+
id_etClosedLine = rb_intern("etClosedLine");
|
466
|
+
id_etOpenButt = rb_intern("etOpenButt");
|
467
|
+
id_etOpenSquare = rb_intern("etOpenSquare");
|
468
|
+
id_etOpenRound = rb_intern("etOpenRound");
|
469
|
+
|
470
|
+
VALUE mod = rb_define_module("Clipper");
|
471
|
+
|
472
|
+
VALUE k = rb_define_class_under(mod, "Clipper", rb_cObject);
|
473
|
+
rb_define_singleton_method(k, "new",
|
474
|
+
(ruby_method) rbclipper_new, 0);
|
475
|
+
|
476
|
+
rb_define_method(k, "orientation",
|
477
|
+
(ruby_method) rbclipper_orientation, 1);
|
478
|
+
rb_define_method(k, "point_in_polygon",
|
479
|
+
(ruby_method) rbclipper_point_in_polygon, 3);
|
480
|
+
rb_define_method(k, "area",
|
481
|
+
(ruby_method) rbclipper_area, 1);
|
482
|
+
rb_define_method(k, "add_subject_polygon",
|
483
|
+
(ruby_method) rbclipper_add_subject_polygon, 1);
|
484
|
+
rb_define_method(k, "add_clip_polygon",
|
485
|
+
(ruby_method) rbclipper_add_clip_polygon, 1);
|
486
|
+
rb_define_method(k, "add_subject_polyline",
|
487
|
+
(ruby_method) rbclipper_add_subject_polyline, 1);
|
488
|
+
rb_define_method(k, "add_subject_polygons",
|
489
|
+
(ruby_method) rbclipper_add_subject_polygons, 1);
|
490
|
+
rb_define_method(k, "add_clip_polygons",
|
491
|
+
(ruby_method) rbclipper_add_clip_polygons, 1);
|
492
|
+
rb_define_method(k, "add_subject_polylines",
|
493
|
+
(ruby_method) rbclipper_add_subject_polylines, 1);
|
494
|
+
rb_define_method(k, "clear!",
|
495
|
+
(ruby_method) rbclipper_clear, 0);
|
496
|
+
rb_define_method(k, "intersection",
|
497
|
+
(ruby_method) rbclipper_intersection, -1);
|
498
|
+
rb_define_method(k, "union",
|
499
|
+
(ruby_method) rbclipper_union, -1);
|
500
|
+
rb_define_method(k, "difference",
|
501
|
+
(ruby_method) rbclipper_difference, -1);
|
502
|
+
rb_define_method(k, "xor",
|
503
|
+
(ruby_method) rbclipper_xor, -1);
|
504
|
+
|
505
|
+
rb_define_method(k, "multiplier",
|
506
|
+
(ruby_method) rbclipper_multiplier, 0);
|
507
|
+
rb_define_method(k, "multiplier=",
|
508
|
+
(ruby_method) rbclipper_multiplier_eq, 1);
|
509
|
+
|
510
|
+
rb_define_method(k, "minkowski_sum",
|
511
|
+
(ruby_method) rbclipper_minkowski_sum, 3);
|
512
|
+
|
513
|
+
rb_define_method(k, "minkowski_diff",
|
514
|
+
(ruby_method) rbclipper_minkowski_diff, 2);
|
515
|
+
|
516
|
+
VALUE ko = rb_define_class_under(mod, "ClipperOffset", rb_cObject);
|
517
|
+
rb_define_singleton_method(ko, "new",
|
518
|
+
(ruby_method) rbclipperoffset_new, 0);
|
519
|
+
rb_define_method(ko, "offset_polygons",
|
520
|
+
(ruby_method) rbclipper_offset_polygons, -1);
|
521
|
+
rb_define_method(ko, "clear!",
|
522
|
+
(ruby_method) rbclipperoffset_clear, 0);
|
523
|
+
|
524
|
+
rb_define_method(ko, "multiplier",
|
525
|
+
(ruby_method) rbclipper_multiplier, 0);
|
526
|
+
rb_define_method(ko, "multiplier=",
|
527
|
+
(ruby_method) rbclipper_multiplier_eq, 1);
|
528
|
+
}
|
529
|
+
|
530
|
+
} /* extern "C" */
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rbclipper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 6.4.2.5.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Angus Johnson
|
8
|
+
- Mike Owens
|
9
|
+
- Dag Rende
|
10
|
+
- Jaap van der Plas
|
11
|
+
- Simon George
|
12
|
+
- Kjell Morgenstern
|
13
|
+
- Will Ross
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
date: 2021-12-08 00:00:00.000000000 Z
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: bundler
|
21
|
+
requirement: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '1.5'
|
26
|
+
type: :development
|
27
|
+
prerelease: false
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.5'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: minitest
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '5.8'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '5.8'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: minitest-junit
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: minitest-snail
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
description: Builds a native ruby extension for Clipper
|
90
|
+
email:
|
91
|
+
- will@spanner.org
|
92
|
+
executables: []
|
93
|
+
extensions:
|
94
|
+
- ext/clipper/extconf.rb
|
95
|
+
extra_rdoc_files:
|
96
|
+
- README.md
|
97
|
+
- Changelog
|
98
|
+
- ext/clipper/rbclipper.cpp
|
99
|
+
files:
|
100
|
+
- Changelog
|
101
|
+
- Gemfile
|
102
|
+
- LICENSE.bindings
|
103
|
+
- LICENSE.clipper
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- ext/clipper/clipper.cpp
|
107
|
+
- ext/clipper/clipper.hpp
|
108
|
+
- ext/clipper/extconf.rb
|
109
|
+
- ext/clipper/rbclipper.cpp
|
110
|
+
- lib/clipper/version.rb
|
111
|
+
homepage: http://github.com/spanner/rbclipper
|
112
|
+
licenses:
|
113
|
+
- Boost Software License - Version 1.0
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options:
|
117
|
+
- "--main=README.md"
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.3.6
|
130
|
+
requirements: []
|
131
|
+
rubygems_version: 3.1.4
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Ruby wrapper for Clipper, Angus Johnson's excellent polygon clipping library
|
135
|
+
test_files: []
|