rbpip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/ext/rbpip/extconf.rb +6 -0
  3. data/ext/rbpip/rbpip.c +125 -0
  4. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a5bd34943439cd36bd33032bdddf348e7f65fa9f
4
+ data.tar.gz: ea9b875eea013c1bfb2482daa54acbd50d4c11b5
5
+ SHA512:
6
+ metadata.gz: 593d81c1ae7a50e7d07c7e07238655016a27257ed5bc4f9fef2c6e3dc4b02e4641e5cbae0a13c27e3e5ae982fa0debfb9e0acdd80698a7ac20a05f6b407bd1dc
7
+ data.tar.gz: 9605f5f9399676cd9a4523b56dc387bee8ee91c4903a4aa95f926f7fdde767e3f260e00d3f44f28bdcd7969ad0b04a55367c8646b4d84bab57d24ed9a2fa9215
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'rbpip'
4
+ dir_config(extension_name)
5
+
6
+ create_makefile(extension_name)
data/ext/rbpip/rbpip.c ADDED
@@ -0,0 +1,125 @@
1
+ #include "ruby.h"
2
+
3
+ int pip(double poly[][2], int npoints, double xt, double yt) {
4
+ double xnew, ynew;
5
+ double xold, yold;
6
+ double x1, y1;
7
+ double x2, y2;
8
+ int i;
9
+ int inside = 0;
10
+
11
+ if (npoints < 3) return 0;
12
+
13
+ xold = poly[npoints-1][0];
14
+ yold = poly[npoints-1][1];
15
+
16
+ for (i = 0; i < npoints; i++) {
17
+ xnew = poly[i][0];
18
+ ynew = poly[i][1];
19
+
20
+ if (xnew > xold) {
21
+ x1 = xold;
22
+ x2 = xnew;
23
+ y1 = yold;
24
+ y2 = ynew;
25
+ } else {
26
+ x1 = xnew;
27
+ x2 = xold;
28
+ y1 = ynew;
29
+ y2 = yold;
30
+ }
31
+
32
+ if ((xnew < xt) == (xt <= xold) && /* edge "open" at left end */
33
+ (yt - y1) * (x2 - x1) <
34
+ (y2 - y1) * (xt - x1))
35
+ {
36
+ inside = !inside;
37
+ }
38
+
39
+ xold = xnew;
40
+ yold = ynew;
41
+ }
42
+
43
+ return inside;
44
+ }
45
+
46
+ static VALUE c_contains_point(VALUE self, VALUE args) {
47
+ VALUE respond_to = rb_intern("respond_to?");
48
+
49
+ VALUE p_x;
50
+ VALUE p_y;
51
+
52
+ switch (RARRAY_LEN(args)) {
53
+ case 1: {
54
+ VALUE arg = rb_ary_entry(args, 0);
55
+ VALUE responds_x = rb_funcall(arg, respond_to, 1, ID2SYM(rb_intern("x")));
56
+ VALUE responds_y = rb_funcall(arg, respond_to, 1, ID2SYM(rb_intern("y")));
57
+
58
+ if (responds_x == Qtrue && responds_y == Qtrue) {
59
+ p_x = rb_funcall(arg, rb_intern("x"), 0);
60
+ p_y = rb_funcall(arg, rb_intern("y"), 0);
61
+ } else {
62
+ rb_raise(rb_eArgError, "Argument must respond to :x and :y.");
63
+ }
64
+
65
+ break;
66
+ }
67
+ case 2: {
68
+ p_x = rb_ary_entry(args, 0);
69
+ p_y = rb_ary_entry(args, 1);
70
+ break;
71
+ }
72
+ default:
73
+ break;
74
+ }
75
+
76
+ Check_Type(p_x, T_FLOAT);
77
+ Check_Type(p_y, T_FLOAT);
78
+
79
+ VALUE polygon = Qnil;
80
+
81
+ switch (TYPE(self)) {
82
+ case T_ARRAY: {
83
+ polygon = self;
84
+ break;
85
+ }
86
+ case T_OBJECT: {
87
+ VALUE points_id = rb_intern("points");
88
+ VALUE responds = rb_funcall(self, respond_to, 1, ID2SYM(points_id));
89
+ if (responds == Qtrue) polygon = rb_funcall(self, points_id, 0);
90
+ else rb_raise(rb_eTypeError, "Receiver does not respond to :points.");
91
+ break;
92
+ }
93
+ default:
94
+ rb_raise(rb_eTypeError, "Receiver is not a valid polygon.");
95
+ break;
96
+ }
97
+
98
+ VALUE *poly_arr = RARRAY_PTR(polygon);
99
+ int poly_len = RARRAY_LEN(polygon);
100
+ if (poly_len < 3) rb_raise(rb_eTypeError, "Polygon must have at least 3 points");
101
+
102
+ double x = NUM2DBL(p_x);
103
+ double y = NUM2DBL(p_y);
104
+
105
+ //double *p_polygon = ALLOCA_N(double, 2 * poly_len);
106
+ double *p_polygon = (double *)malloc(sizeof(double)*2*poly_len);
107
+
108
+ for (int i = 0; i < poly_len; i++) {
109
+ Check_Type(poly_arr[i], T_ARRAY);
110
+ VALUE *p = RARRAY_PTR(poly_arr[i]);
111
+ int p_len = RARRAY_LEN(poly_arr[i]);
112
+ if (p_len != 2) rb_raise(rb_eTypeError, "A polygon's points must contain only two values.");
113
+ Check_Type(p[0], T_FLOAT);
114
+ Check_Type(p[1], T_FLOAT);
115
+ p_polygon[i*2] = NUM2DBL(p[0]);
116
+ p_polygon[(i*2)+1] = NUM2DBL(p[1]);
117
+ }
118
+
119
+ int res = pip((double (*)[2]) p_polygon, poly_len, x, y);
120
+ return res == 1 ? Qtrue : Qfalse;
121
+ }
122
+
123
+ void Init_rbpip() {
124
+ rb_define_method(rb_cObject, "contains_point?", RUBY_METHOD_FUNC(c_contains_point), -2);
125
+ }
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbpip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nathaniel Symer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Point-in-poly calcs for ruby. Extends Object.
14
+ email: nate@natesymer.com
15
+ executables: []
16
+ extensions:
17
+ - ext/rbpip/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ext/rbpip/extconf.rb
21
+ - ext/rbpip/rbpip.c
22
+ homepage: https://github.com/fhsjaagshs/rbpip
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - ext
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.2.2
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Point-in-poly calcs for ruby.
46
+ test_files: []