rbclipper 6.4.2.5.5
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 +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: []
|