geo 0.1.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.
- data/README +24 -0
- data/examples/intersects.rb +26 -0
- data/ext/common.c +35 -0
- data/ext/common.h +97 -0
- data/ext/extconf.rb +51 -0
- data/ext/geo.c +163 -0
- data/ext/geo_set.c +488 -0
- data/ext/geo_set.h +156 -0
- data/ext/intersection.c +58 -0
- data/ext/intersection.h +38 -0
- data/ext/line.c +436 -0
- data/ext/line.h +170 -0
- data/ext/line_set.c +596 -0
- data/ext/line_set.h +87 -0
- data/ext/point.c +265 -0
- data/ext/point.h +123 -0
- data/ext/point_set.c +93 -0
- data/ext/point_set.h +44 -0
- data/ext/triangle.c +412 -0
- data/ext/triangle.h +83 -0
- data/ext/triangle_set.c +347 -0
- data/ext/triangle_set.h +68 -0
- data/ext/types.h +48 -0
- metadata +69 -0
data/ext/point.c
ADDED
@@ -0,0 +1,265 @@
|
|
1
|
+
|
2
|
+
#include "common.h"
|
3
|
+
|
4
|
+
VALUE rb_point;
|
5
|
+
|
6
|
+
const Point ORIGO = { 0.0, 0.0, 0 };
|
7
|
+
|
8
|
+
Point*
|
9
|
+
new_point(gdouble x, gdouble y) {
|
10
|
+
Point *rval = ALLOC(Point);
|
11
|
+
rval->x = x;
|
12
|
+
rval->y = y;
|
13
|
+
rval->rbPoint = 0;
|
14
|
+
return rval;
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
VALUE
|
19
|
+
rb_point_alloc(VALUE class) {
|
20
|
+
Point *p = ALLOC(Point);
|
21
|
+
return RB_POINT(p, class);
|
22
|
+
}
|
23
|
+
|
24
|
+
VALUE
|
25
|
+
rb_point_initialize(VALUE self, VALUE x, VALUE y) {
|
26
|
+
Point *p;
|
27
|
+
CHECK_NUMERICALITY(x);
|
28
|
+
CHECK_NUMERICALITY(y);
|
29
|
+
POINT(self, p);
|
30
|
+
p->x = NUM2DBL(x);
|
31
|
+
p->y = NUM2DBL(y);
|
32
|
+
return self;
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE
|
36
|
+
rb_point_set_x(VALUE self, VALUE new_x) {
|
37
|
+
Point *p;
|
38
|
+
CHECK_NUMERICALITY(new_x);
|
39
|
+
POINT(self, p);
|
40
|
+
p->x = NUM2DBL(new_x);
|
41
|
+
return new_x;
|
42
|
+
}
|
43
|
+
|
44
|
+
VALUE
|
45
|
+
rb_point_set_y(VALUE self, VALUE new_y) {
|
46
|
+
Point *p;
|
47
|
+
CHECK_NUMERICALITY(new_y);
|
48
|
+
POINT(self, p);
|
49
|
+
p->y = NUM2DBL(new_y);
|
50
|
+
return new_y;
|
51
|
+
}
|
52
|
+
|
53
|
+
VALUE
|
54
|
+
rb_point_x(VALUE self) {
|
55
|
+
Point *p;
|
56
|
+
POINT(self, p);
|
57
|
+
return rb_float_new(p->x);
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE
|
61
|
+
rb_point_y(VALUE self) {
|
62
|
+
Point *p;
|
63
|
+
POINT(self, p);
|
64
|
+
return rb_float_new(p->y);
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE
|
68
|
+
rb_point_inspect(VALUE self) {
|
69
|
+
gchar rval[1024];
|
70
|
+
Point *p;
|
71
|
+
POINT(self, p);
|
72
|
+
snprintf(rval, 1023, "<%s:%p x=%f y=%f>", rb_obj_classname(self), p, p->x, p->y);
|
73
|
+
return rb_str_new2(rval);
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
VALUE
|
78
|
+
rb_point_dot(VALUE self, VALUE o) {
|
79
|
+
Point *me;
|
80
|
+
Point *point;
|
81
|
+
CHECK_POINT(o);
|
82
|
+
POINT(self, me);
|
83
|
+
POINT(o, point);
|
84
|
+
return rb_float_new(POINT_DOT(me, point));
|
85
|
+
}
|
86
|
+
|
87
|
+
VALUE
|
88
|
+
rb_point_abs(VALUE self) {
|
89
|
+
Point *me;
|
90
|
+
POINT(self, me);
|
91
|
+
return rb_float_new(DISTANCE(&ORIGO, me));
|
92
|
+
}
|
93
|
+
|
94
|
+
VALUE
|
95
|
+
rb_point_equals(VALUE self, VALUE o) {
|
96
|
+
if (!POINT_P(o)) {
|
97
|
+
return Qfalse;
|
98
|
+
} else {
|
99
|
+
Point *me;
|
100
|
+
Point *other;
|
101
|
+
POINT(self, me);
|
102
|
+
POINT(o, other);
|
103
|
+
if (POINT_EQUALS(me, other)) {
|
104
|
+
return Qtrue;
|
105
|
+
} else {
|
106
|
+
return Qfalse;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
gint
|
112
|
+
point_cmp(Point *me, Point *other) {
|
113
|
+
gdouble my_length;
|
114
|
+
gdouble other_length;
|
115
|
+
my_length = LENGTH(me->x, me->y);
|
116
|
+
other_length = LENGTH(other->x, other->y);
|
117
|
+
if (my_length != other_length)
|
118
|
+
return CMP(my_length, other_length);
|
119
|
+
else if (me->x != other->x)
|
120
|
+
return CMP(me->x, other->x);
|
121
|
+
else
|
122
|
+
return CMP(me->y, other->y);
|
123
|
+
}
|
124
|
+
|
125
|
+
VALUE
|
126
|
+
rb_point_cmp(VALUE self, VALUE o) {
|
127
|
+
if (!POINT_P(o)) {
|
128
|
+
return INT2NUM(CMP(CLASS(self), CLASS(o)));
|
129
|
+
} else {
|
130
|
+
Point *me;
|
131
|
+
Point *other;
|
132
|
+
POINT(self, me);
|
133
|
+
POINT(o, other);
|
134
|
+
return INT2NUM(point_cmp(me, other));
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE
|
139
|
+
rb_point_set_angle(VALUE self, VALUE new_angle) {
|
140
|
+
Point *me;
|
141
|
+
gdouble length;
|
142
|
+
gdouble angle;
|
143
|
+
CHECK_NUMERICALITY(new_angle);
|
144
|
+
POINT(self, me);
|
145
|
+
angle = NUM2DBL(new_angle);
|
146
|
+
length = LENGTH(me->x, me->y);
|
147
|
+
while (angle > M_PI * 2)
|
148
|
+
angle -= M_PI * 2;
|
149
|
+
me->x = length * cos(angle);
|
150
|
+
me->y = length * sin(angle);
|
151
|
+
return rb_float_new(angle);
|
152
|
+
}
|
153
|
+
|
154
|
+
VALUE
|
155
|
+
rb_point_angle(VALUE self) {
|
156
|
+
Point *me;
|
157
|
+
POINT(self, me);
|
158
|
+
ZERO_LENGTH_CHECK(me);
|
159
|
+
return rb_float_new(ANGLE(me->x, me->y));
|
160
|
+
}
|
161
|
+
|
162
|
+
VALUE
|
163
|
+
rb_point_set_abs(VALUE self, VALUE new_abs) {
|
164
|
+
Point *me;
|
165
|
+
gdouble ratio;
|
166
|
+
CHECK_NUMERICALITY(new_abs);
|
167
|
+
POINT(self, me);
|
168
|
+
ZERO_LENGTH_CHECK(me);
|
169
|
+
ratio = NUM2DBL(new_abs) / LENGTH(me->x, me->y);
|
170
|
+
me->x = me->x * ratio;
|
171
|
+
me->y = me->y * ratio;
|
172
|
+
return new_abs;
|
173
|
+
}
|
174
|
+
|
175
|
+
VALUE
|
176
|
+
rb_point_clone(VALUE self) {
|
177
|
+
Point *me;
|
178
|
+
Point *rval;
|
179
|
+
POINT(self, me);
|
180
|
+
rval = new_point(me->x, me->y);
|
181
|
+
return RB_POINT(rval, CLASS(self));
|
182
|
+
}
|
183
|
+
|
184
|
+
VALUE
|
185
|
+
rb_point_to(int argc, VALUE *argv, VALUE self) {
|
186
|
+
Point *me;
|
187
|
+
Point *other_end;
|
188
|
+
Line *rval;
|
189
|
+
if (argc == 1) {
|
190
|
+
CHECK_POINT(argv[0]);
|
191
|
+
POINT(self, me);
|
192
|
+
POINT(argv[0], other_end);
|
193
|
+
rval = new_line_with_points(me, other_end);
|
194
|
+
return RB_LINE(rval, rb_line);
|
195
|
+
} else if (argc == 2) {
|
196
|
+
CHECK_NUMERICALITY(argv[0]);
|
197
|
+
CHECK_NUMERICALITY(argv[1]);
|
198
|
+
POINT(self, me);
|
199
|
+
other_end = new_point(NUM2DBL(argv[0]), NUM2DBL(argv[1]));
|
200
|
+
RB_POINT(other_end, CLASS(self));
|
201
|
+
rval = new_line_with_points(me, other_end);
|
202
|
+
return RB_LINE(rval, rb_line);
|
203
|
+
} else {
|
204
|
+
rb_raise(rb_eTypeError, "Arguments to %s#to has to be either a Grueserve::Map::Point or 2 numbers.", rb_obj_classname(self));
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
VALUE
|
209
|
+
rb_point_on(VALUE self, VALUE l) {
|
210
|
+
Point *me;
|
211
|
+
Line *line;
|
212
|
+
gint side;
|
213
|
+
CHECK_LINE(l);
|
214
|
+
POINT(self,me);
|
215
|
+
LINE(l, line);
|
216
|
+
side = line_side(line, me);
|
217
|
+
if (side == 0) {
|
218
|
+
return Qtrue;
|
219
|
+
} else {
|
220
|
+
return Qfalse;
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
VALUE
|
225
|
+
rb_point_in(VALUE self, VALUE t) {
|
226
|
+
Point *me;
|
227
|
+
Triangle *triangle;
|
228
|
+
CHECK_TRIANGLE(t);
|
229
|
+
POINT(self, me);
|
230
|
+
TRIANGLE(t, triangle);
|
231
|
+
if (triangle_contains(triangle, me)) {
|
232
|
+
return Qtrue;
|
233
|
+
} else {
|
234
|
+
return Qfalse;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
VALUE
|
239
|
+
rb_point_plus(VALUE self, VALUE p) {
|
240
|
+
Point *me;
|
241
|
+
Point *other;
|
242
|
+
Point *rval;
|
243
|
+
CHECK_POINT(p);
|
244
|
+
POINT(self, me);
|
245
|
+
POINT(p, other);
|
246
|
+
rval = ALLOC(Point);
|
247
|
+
rval->x = me->x + other->x;
|
248
|
+
rval->y = me->y + other->y;
|
249
|
+
return RB_POINT(rval, CLASS(self));
|
250
|
+
}
|
251
|
+
|
252
|
+
VALUE
|
253
|
+
rb_point_minus(VALUE self, VALUE p) {
|
254
|
+
Point *me;
|
255
|
+
Point *other;
|
256
|
+
Point *rval;
|
257
|
+
CHECK_POINT(p);
|
258
|
+
POINT(self, me);
|
259
|
+
POINT(p, other);
|
260
|
+
rval = ALLOC(Point);
|
261
|
+
rval->x = me->x - other->x;
|
262
|
+
rval->y = me->y - other->y;
|
263
|
+
return RB_POINT(rval, CLASS(self));
|
264
|
+
}
|
265
|
+
|
data/ext/point.h
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
|
2
|
+
#ifndef POINT_H
|
3
|
+
#define POINT_H
|
4
|
+
|
5
|
+
#include "common.h"
|
6
|
+
|
7
|
+
extern VALUE rb_point;
|
8
|
+
|
9
|
+
#define RB_POINT(point_pointer,klass) ((point_pointer)->rbPoint = Data_Wrap_Struct(klass, NULL, free, (point_pointer)))
|
10
|
+
#define POINT(rb_point,point_pointer) Data_Get_Struct((rb_point), Point, (point_pointer))
|
11
|
+
|
12
|
+
#define M_PI 3.14159265358979323846 /* pi */
|
13
|
+
#define M_PI_2 1.57079632679489661923 /* pi/2 */
|
14
|
+
#define M_PI_4 0.78539816339744830962 /* pi/4 */
|
15
|
+
#define LENGTH(dx,dy) (sqrt(pow((dx),2) + pow((dy),2)))
|
16
|
+
#define DISTANCE(p1,p2) (LENGTH((p1)->x - (p2)->x, (p1)->y - (p2)->y))
|
17
|
+
#define ANGLE(dx,dy) ((dy) > 0 ? \
|
18
|
+
((dx) > 0 ? \
|
19
|
+
acos((dx) / LENGTH((dx),(dy))) \
|
20
|
+
: \
|
21
|
+
((dx) < 0 ? \
|
22
|
+
acos((dx) / LENGTH((dx),(dy))) \
|
23
|
+
: \
|
24
|
+
M_PI_2)) \
|
25
|
+
: \
|
26
|
+
((dy) < 0 ? \
|
27
|
+
((dx) > 0 ? \
|
28
|
+
(2 * M_PI - acos((dx) / LENGTH((dx),(dy)))) \
|
29
|
+
: \
|
30
|
+
((dx) < 0 ? \
|
31
|
+
(2 * M_PI - acos((dx) / LENGTH((dx),(dy)))) \
|
32
|
+
: \
|
33
|
+
M_PI_2 + M_PI)) \
|
34
|
+
: \
|
35
|
+
((dx) > 0 ? \
|
36
|
+
0.0 \
|
37
|
+
: \
|
38
|
+
M_PI)))
|
39
|
+
|
40
|
+
#define POINT_EQUALS(p1,p2) (DBL_EQL((p1)->x, (p2)->x) && DBL_EQL((p1)->y, (p2)->y))
|
41
|
+
#define POINT_DOT(p1,p2) ((p1)->x * (p2)->x + (p1)->y * (p2)->y)
|
42
|
+
#define POINT_P(p) (!NIL_P((p)) && rb_is_a((p), rb_point))
|
43
|
+
#define CHECK_POINT(p) if (!POINT_P((p))) rb_raise(rb_eTypeError, "Expected Grueserve::Map::Point!")
|
44
|
+
#define ZERO_LENGTH_P(p) ((p)->x == 0 && (p)->y == 0)
|
45
|
+
#define ZERO_LENGTH_CHECK(p) if (ZERO_LENGTH_P((p))) rb_raise(rb_eTypeError, "Expected something with length > 0!")
|
46
|
+
#define ZERO_DISTANCE_P(p1,p2) ((p1)->x == (p2)->x && ((p1)->y == (p2)->y))
|
47
|
+
#define ZERO_DISTANCE_CHECK(p1,p2) if (ZERO_DISTANCE_P((p1),(p2))) rb_raise(rb_eTypeError, "Expected something with distance > 0!")
|
48
|
+
|
49
|
+
extern const Point ORIGO;
|
50
|
+
|
51
|
+
|
52
|
+
Point*
|
53
|
+
new_point(gdouble x, gdouble y);
|
54
|
+
|
55
|
+
VALUE
|
56
|
+
rb_point_alloc(VALUE class);
|
57
|
+
|
58
|
+
VALUE
|
59
|
+
rb_point_initialize(VALUE self, VALUE x, VALUE y);
|
60
|
+
|
61
|
+
VALUE
|
62
|
+
rb_point_set_x(VALUE self, VALUE new_x);
|
63
|
+
|
64
|
+
VALUE
|
65
|
+
rb_point_set_y(VALUE self, VALUE new_y);
|
66
|
+
|
67
|
+
VALUE
|
68
|
+
rb_point_x(VALUE self);
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
rb_point_y(VALUE self);
|
72
|
+
|
73
|
+
VALUE
|
74
|
+
rb_point_inspect(VALUE self);
|
75
|
+
|
76
|
+
VALUE
|
77
|
+
rb_point_dot(VALUE self, VALUE o);
|
78
|
+
|
79
|
+
VALUE
|
80
|
+
rb_point_abs(VALUE self);
|
81
|
+
|
82
|
+
VALUE
|
83
|
+
rb_point_equals(VALUE self, VALUE o);
|
84
|
+
|
85
|
+
VALUE
|
86
|
+
rb_point_cmp(VALUE self, VALUE o);
|
87
|
+
|
88
|
+
VALUE
|
89
|
+
rb_point_set_angle(VALUE self, VALUE new_angle);
|
90
|
+
|
91
|
+
VALUE
|
92
|
+
rb_point_angle(VALUE self);
|
93
|
+
|
94
|
+
VALUE
|
95
|
+
rb_point_set_abs(VALUE self, VALUE new_abs);
|
96
|
+
|
97
|
+
VALUE
|
98
|
+
rb_point_clone(VALUE self);
|
99
|
+
|
100
|
+
VALUE
|
101
|
+
rb_point_to(int argc, VALUE *argv, VALUE self);
|
102
|
+
|
103
|
+
VALUE
|
104
|
+
rb_point_on(VALUE self, VALUE l);
|
105
|
+
|
106
|
+
VALUE
|
107
|
+
rb_point_in(VALUE self, VALUE t);
|
108
|
+
|
109
|
+
VALUE
|
110
|
+
rb_point_plus(VALUE self, VALUE p);
|
111
|
+
|
112
|
+
VALUE
|
113
|
+
rb_point_minus(VALUE self, VALUE p);
|
114
|
+
|
115
|
+
gint
|
116
|
+
point_cmp(Point *me, Point *other);
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
#endif
|
123
|
+
|
data/ext/point_set.c
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
#include "common.h"
|
3
|
+
|
4
|
+
VALUE rb_point_set;
|
5
|
+
|
6
|
+
|
7
|
+
static void
|
8
|
+
g_hash_table_mark_point(gpointer key, gpointer value, gpointer user_data) {
|
9
|
+
rb_gc_mark( ( (Point *) key )->rbPoint);
|
10
|
+
}
|
11
|
+
|
12
|
+
void
|
13
|
+
point_set_mark(GeoSet *set) {
|
14
|
+
g_hash_table_foreach(set->table, g_hash_table_mark_point, NULL);
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
VALUE
|
19
|
+
rb_point_set_alloc(VALUE class) {
|
20
|
+
GeoSet *set = new_geo_set();
|
21
|
+
return RB_POINT_SET(set, class);
|
22
|
+
}
|
23
|
+
|
24
|
+
VALUE
|
25
|
+
rb_point_set_insert(VALUE self, VALUE p) {
|
26
|
+
Point *point;
|
27
|
+
GeoSet *me;
|
28
|
+
CHECK_POINT(p);
|
29
|
+
GEO_SET(self, me);
|
30
|
+
POINT(p, point);
|
31
|
+
geo_set_insert(me, (gpointer ) point);
|
32
|
+
return self;
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE
|
36
|
+
rb_point_set_include(VALUE self, VALUE point) {
|
37
|
+
GeoSet *me;
|
38
|
+
Point *t;
|
39
|
+
CHECK_POINT(point);
|
40
|
+
POINT(point, t);
|
41
|
+
GEO_SET(self, me);
|
42
|
+
return GBOOL2RB(g_hash_table_lookup_extended(me->table, (gpointer) t, NULL, NULL));
|
43
|
+
}
|
44
|
+
|
45
|
+
VALUE
|
46
|
+
rb_point_set_delete(VALUE self, VALUE point) {
|
47
|
+
GeoSet *me;
|
48
|
+
Point *t;
|
49
|
+
CHECK_POINT(point);
|
50
|
+
GEO_SET(self, me);
|
51
|
+
POINT(point, t);
|
52
|
+
return geo_set_delete(me, (gpointer) t, point);
|
53
|
+
}
|
54
|
+
|
55
|
+
static void
|
56
|
+
g_hash_table_yield_point(gpointer key, gpointer value, gpointer user_data) {
|
57
|
+
rb_yield(( (Point *) key )->rbPoint);
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE
|
61
|
+
rb_point_set_each(VALUE self) {
|
62
|
+
GeoSet *set;
|
63
|
+
GEO_SET(self, set);
|
64
|
+
geo_set_foreach(set, g_hash_table_yield_point);
|
65
|
+
return self;
|
66
|
+
}
|
67
|
+
|
68
|
+
VALUE
|
69
|
+
rb_point_set_clone(VALUE self) {
|
70
|
+
GeoSet *me;
|
71
|
+
GEO_SET(self, me);
|
72
|
+
return RB_POINT_SET(geo_set_clone(me), CLASS(self));
|
73
|
+
}
|
74
|
+
|
75
|
+
gpointer
|
76
|
+
geo_set_each_structure_having_common_segment_id_with_point_until(GeoSet *set,
|
77
|
+
Point *point,
|
78
|
+
geo_set_structure_handler handler,
|
79
|
+
gpointer user_data) {
|
80
|
+
GHashTable *seen_structures = g_hash_table_new(g_direct_hash, g_direct_equal);
|
81
|
+
gpointer args[3] = { seen_structures, handler, user_data };
|
82
|
+
GHashTable *seen_segment_ids = g_hash_table_new(g_direct_hash, g_direct_equal);
|
83
|
+
gpointer rval = NULL;
|
84
|
+
rval = geo_set_each_segment_id_for_point_until(set,
|
85
|
+
point,
|
86
|
+
seen_segment_ids,
|
87
|
+
geo_set_each_structure_in_segment_id_until,
|
88
|
+
args);
|
89
|
+
g_hash_table_destroy(seen_segment_ids);
|
90
|
+
g_hash_table_destroy(seen_structures);
|
91
|
+
return rval;
|
92
|
+
}
|
93
|
+
|
data/ext/point_set.h
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
#ifndef POINT_SET_H
|
3
|
+
#define POINT_SET_H
|
4
|
+
|
5
|
+
#include "common.h"
|
6
|
+
|
7
|
+
extern VALUE rb_point_set;
|
8
|
+
|
9
|
+
#define RB_POINT_SET(point_set_pointer,klass) Data_Wrap_Struct(klass, point_set_mark, geo_set_free, (point_set_pointer))
|
10
|
+
|
11
|
+
#define POINT_SET_P(pl) (!NIL_P((pl)) && rb_is_a((pl), rb_point_set))
|
12
|
+
#define CHECK_POINT_SET(pl) if (!POINT_SET_P((pl))) rb_raise(rb_eTypeError, "Expected Grueserve::Map::PointSet!")
|
13
|
+
|
14
|
+
void
|
15
|
+
point_set_mark(GeoSet *set);
|
16
|
+
|
17
|
+
VALUE
|
18
|
+
rb_point_set_alloc(VALUE class);
|
19
|
+
|
20
|
+
VALUE
|
21
|
+
rb_point_set_insert(VALUE self, VALUE p);
|
22
|
+
|
23
|
+
VALUE
|
24
|
+
rb_point_set_include(VALUE self, VALUE point);
|
25
|
+
|
26
|
+
VALUE
|
27
|
+
rb_point_set_delete(VALUE self, VALUE point);
|
28
|
+
|
29
|
+
VALUE
|
30
|
+
rb_point_set_each(VALUE self);
|
31
|
+
|
32
|
+
VALUE
|
33
|
+
rb_point_set_clone(VALUE self);
|
34
|
+
|
35
|
+
gpointer
|
36
|
+
geo_set_each_structure_having_common_segment_id_with_point_until(GeoSet *set,
|
37
|
+
Point *point,
|
38
|
+
geo_set_structure_handler handler,
|
39
|
+
gpointer user_data);
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
#endif
|