geo 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,24 @@
1
+ = This is geo, a 2D geometry library for ruby.
2
+
3
+ It provides fast operations for points, lines, triangles, intersections and containers.
4
+
5
+ == Dependencies:
6
+ glib:: http://www.gtk.org/
7
+
8
+ == Classes:
9
+ Geo::Point:: A 2D point providing some common geometry operations.
10
+ Geo::Line:: A 2D line consisting of 2 Geo::Points providing some common geometry operations.
11
+ Geo::Triangle:: A 2D triangle consisting of 3 Geo::Points providing some common geometry operations.
12
+ Geo::PointSet:: A Set-like container of Points.
13
+ Geo::LineSet:: A Set-like container of Lines that provides optimized versions of some common geometry operations on lines.
14
+ Geo::TriangleSet:: A Set-like container of Triangles that provides optimized versions of some common geometry operations on lines.
15
+
16
+ == Usage:
17
+
18
+ To use geo just install the gem.
19
+
20
+ == Examples:
21
+
22
+ To find if a given line intersects a set of 100 000 other lines:
23
+
24
+ :include:examples/intersects.rb
@@ -0,0 +1,26 @@
1
+
2
+ require 'rubygems'
3
+ require 'geo'
4
+ require 'benchmark'
5
+
6
+ puts "creating LineSet with 100 000 lines"
7
+ STDOUT.flush
8
+ ls = Geo::LineSet.new
9
+ 100000.times do |n|
10
+ l = Geo::Line.new(rand(1000), rand(1000), 1, 1)
11
+ l.abs = rand(20)
12
+ l.angle = rand * 2 * Math::PI
13
+ ls << Geo::Line.new(rand(1000), rand(1000), rand(1000), rand(1000))
14
+ end
15
+ print "reindexing LineSet..."
16
+ STDOUT.flush
17
+ ls._reindex
18
+ puts "done!"
19
+ l = Geo::Line.new(rand(1000), rand(1000), rand(1000), rand(1000))
20
+ Benchmark.benchmark("LineSet#intersects?(#{l.inspect})") do |bm|
21
+ bm.report do
22
+ ls.intersects?(l)
23
+ end
24
+ end
25
+
26
+
data/ext/common.c ADDED
@@ -0,0 +1,35 @@
1
+
2
+ #include "common.h"
3
+
4
+ #ifdef GEO_DEBUG
5
+ // The indentation of DBEUG messages.
6
+ gint DEBUG_indentation = 0;
7
+ #endif
8
+
9
+ gboolean
10
+ rb_is_a(VALUE obj, VALUE c) {
11
+ VALUE cl = CLASS_OF(obj);
12
+
13
+ switch (TYPE(c)) {
14
+ case T_MODULE:
15
+ case T_CLASS:
16
+ case T_ICLASS:
17
+ break;
18
+
19
+ default:
20
+ return FALSE;
21
+ }
22
+
23
+ while (cl) {
24
+ if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl)
25
+ return TRUE;
26
+ cl = RCLASS(cl)->super;
27
+ }
28
+ return FALSE;
29
+ }
30
+
31
+ gint
32
+ gpointer_compare_as_uint(gconstpointer p1, gconstpointer p2) {
33
+ return GPOINTER_TO_UINT(p1) - GPOINTER_TO_UINT(p2);
34
+ }
35
+
data/ext/common.h ADDED
@@ -0,0 +1,97 @@
1
+
2
+ #ifndef COMMON_H
3
+ #define COMMON_H
4
+
5
+ #include "ruby.h"
6
+ #include <stdlib.h>
7
+ #include <math.h>
8
+ #include <glib.h>
9
+ #include "types.h"
10
+ #include "point.h"
11
+ #include "line.h"
12
+ #include "intersection.h"
13
+ #include "triangle.h"
14
+ #include "geo_set.h"
15
+ #include "line_set.h"
16
+ #include "point_set.h"
17
+ #include "triangle_set.h"
18
+
19
+ //
20
+ // Utility macros.
21
+ //
22
+
23
+ //
24
+ // If we have debug turned on when compiling, lets do stuff with all these debug macros.
25
+ //
26
+ #ifdef GEO_DEBUG
27
+ // The indentation of DBEUG messages.
28
+ extern gint DEBUG_indentation;
29
+ // Only execute s if debugging.
30
+ #define IFDEBUG(s) s
31
+ // Make the indentation of normal DEBUG messages one greater.
32
+ #define INDENT indentation++;
33
+ // Make the indentation of normal DEBUG messages one less.
34
+ #define UNINDENT indentation--;
35
+ // Warn if x is NULL.
36
+ #define NULL_WARN(x) if ((x) == NULL) DEBUG("x is NULL!!!");
37
+ // Indent DEBUG_indentation spaces and print the debug message.
38
+ #define DEBUG(s, ...) { \
39
+ gint indentation_tmp; \
40
+ fprintf(stderr, "DEBUG: %s: ", __PRETTY_FUNCTION__); \
41
+ for (indentation_tmp = 0; indentation_tmp < DEBUG_indentation; indentation_tmp++) fprintf(stderr, " "); \
42
+ fprintf(stderr, s, ## __VA_ARGS__); \
43
+ fprintf(stderr, "\n"); \
44
+ fflush(NULL); }
45
+ // Print out the text in str of length len as a ruby inspected string.
46
+ #define STRING_DEBUG(msg,str,len) { \
47
+ fprintf(stderr, "DEBUG: %s: ", (msg)); \
48
+ rb_funcall(rb_const_get(rb_cObject, rb_intern("Kernel")), rb_intern("print"), 1, rb_funcall(rb_str_new((gchar *) (str), (len)), rb_intern("inspect"), 0)); \
49
+ fprintf(stderr, "\n"); \
50
+ fflush(NULL); }
51
+ //
52
+ // If we dont have debug turned on while compiling, just replace them with empty semicolons so as not to confuse the compiler.
53
+ //
54
+ #else
55
+ #define INDENT ;
56
+ #define UNINDENT ;
57
+ #define DEBUG(s, ...) ;
58
+ #define BITSTRING_DEBUG(msg,str,len) ;
59
+ #define IFDEBUG(s) ;
60
+ #endif
61
+
62
+
63
+
64
+
65
+
66
+ #define CLASS(value) (( (struct RBasic *) (value) )->klass)
67
+
68
+
69
+ #define DBL_PREC 0.00001
70
+ #define DBL_WITHIN(d1,d2,diff) (((d1) - (d2) < diff) && ((d2) - (d1) < diff))
71
+ #define DBL_EQL(d1,d2) (((d1) - (d2) < DBL_PREC) && ((d2) - (d1) < DBL_PREC))
72
+ #define DBL_EOG(object,subject) ((subject) - (object) < DBL_PREC)
73
+ #define DBL_EOL(object,subject) ((object) - (subject) < DBL_PREC)
74
+ #define DBL_GT(object,subject) ((object) - (subject) > DBL_PREC)
75
+ #define DBL_LT(object,subject) ((subject) - (object) > DBL_PREC)
76
+ #define IS_INTLIKE(x) (DBL_EQL((x), round((x))))
77
+ #define CMP(a,b) ((a) - (b))
78
+
79
+ #define GBOOL2RB(gbool) ((gbool) ? Qtrue : Qfalse)
80
+ #define CHECK_NUMERICALITY(v) if (NIL_P((v)) || (TYPE((v)) != T_FIXNUM && TYPE((v)) != T_FLOAT)) rb_raise(rb_eTypeError, "Expected a Number!")
81
+
82
+
83
+
84
+ gboolean
85
+ rb_is_a(VALUE obj, VALUE c);
86
+
87
+ gint
88
+ gpointer_compare_as_uint(gconstpointer p1, gconstpointer p2);
89
+
90
+
91
+
92
+
93
+
94
+
95
+ #endif
96
+
97
+
data/ext/extconf.rb ADDED
@@ -0,0 +1,51 @@
1
+ # Archipelago - a distributed computing toolkit for ruby
2
+ # Copyright (C) 2006 Martin Kihlgren <zond at troja dot ath dot cx>
3
+ #
4
+ # This program is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU General Public License
6
+ # as published by the Free Software Foundation; either version 2
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
+
18
+ require 'mkmf'
19
+
20
+ def crash(s)
21
+ puts "--------------------------------------------------"
22
+ puts " extconf failure: #{s}"
23
+ puts "--------------------------------------------------"
24
+ exit 1
25
+ end
26
+
27
+ unless find_executable("pkg-config")
28
+ crash("pkg-config needed")
29
+ end
30
+
31
+ unless have_library('glib-2.0')
32
+ crash "libglib-2.0 needed"
33
+ end
34
+
35
+ $CFLAGS += " -std=c99 -Wall " + `pkg-config --cflags glib-2.0`.strip
36
+
37
+ if ARGV.include?("-d")
38
+ $CFLAGS += " -D GEO_DEBUG"
39
+ end
40
+
41
+ if ARGV.include?("-O0")
42
+ $CFLAGS.gsub!(/-O./, "-O0")
43
+ else
44
+ $CFLAGS.gsub!(/-O./, "-O3")
45
+ end
46
+
47
+ if ARGV.include?("-gdb")
48
+ $CFLAGS += " -g -gdwarf-2 -g3"
49
+ end
50
+
51
+ create_makefile("geo")
data/ext/geo.c ADDED
@@ -0,0 +1,163 @@
1
+
2
+ #include "common.h"
3
+
4
+ VALUE
5
+ rb_float_intlike(VALUE self) {
6
+ if (IS_INTLIKE(NUM2DBL(self)))
7
+ return Qtrue;
8
+ else
9
+ return Qfalse;
10
+ }
11
+
12
+ #ifdef __cplusplus
13
+ extern "C" {
14
+ #endif
15
+ void Init_geo() {
16
+ rb_funcall(rb_cObject, rb_intern("require"), 1, rb_str_new2("set"));
17
+
18
+ rb_define_method(rb_cFloat, "intlike?", rb_float_intlike, 0);
19
+
20
+ VALUE rb_geo = rb_define_module("Geo");
21
+ rb_define_const(rb_geo, "VERSION", rb_str_new2("0.1.2"));
22
+
23
+ rb_triangle_set = rb_define_class_under(rb_geo,
24
+ "TriangleSet",
25
+ rb_cObject);
26
+ rb_triangle = rb_define_class_under(rb_geo,
27
+ "Triangle",
28
+ rb_cObject);
29
+ rb_line = rb_define_class_under(rb_geo,
30
+ "Line",
31
+ rb_cObject);
32
+ rb_point = rb_define_class_under(rb_geo,
33
+ "Point",
34
+ rb_cObject);
35
+ rb_line_set = rb_define_class_under(rb_geo,
36
+ "LineSet",
37
+ rb_cObject);
38
+ rb_point_set = rb_define_class_under(rb_geo,
39
+ "PointSet",
40
+ rb_cObject);
41
+
42
+ rb_define_alloc_func(rb_triangle_set, rb_triangle_set_alloc);
43
+ rb_define_method(rb_triangle_set, "<<", rb_triangle_set_insert, 1);
44
+ rb_define_method(rb_triangle_set, "each", rb_triangle_set_each, 0);
45
+ rb_define_method(rb_triangle_set, "size", rb_geo_set_size, 0);
46
+ rb_define_method(rb_triangle_set, "inspect", rb_geo_set_inspect, 0);
47
+ rb_define_method(rb_triangle_set, "include?", rb_triangle_set_include, 1);
48
+ rb_define_method(rb_triangle_set, "delete!", rb_triangle_set_delete, 1);
49
+ rb_define_method(rb_triangle_set, "contains?", rb_triangle_set_contains, 1);
50
+ rb_define_method(rb_triangle_set, "first_container", rb_triangle_set_first_container, 1);
51
+ rb_define_method(rb_triangle_set, "intersectors", rb_triangle_set_intersectors, 1);
52
+ rb_define_method(rb_triangle_set, "intersects?", rb_triangle_set_intersects, 1);
53
+ rb_define_method(rb_triangle_set, "clone", rb_triangle_set_clone, 0);
54
+ rb_define_method(rb_triangle_set, "_segment_side", rb_geo_set_segment_side, 0);
55
+ rb_define_method(rb_triangle_set, "_segment_lines", rb_geo_set_segment_lines, 0);
56
+ rb_define_method(rb_triangle_set, "_bottom_left", rb_geo_set_bottom_left, 0);
57
+ rb_define_method(rb_triangle_set, "_top_right", rb_geo_set_top_right, 0);
58
+ rb_define_method(rb_triangle_set, "_width", rb_geo_set_width, 0);
59
+ rb_define_method(rb_triangle_set, "_height", rb_geo_set_height, 0);
60
+ rb_define_method(rb_triangle_set, "_reindex", rb_triangle_set_reindex, 0);
61
+ rb_define_method(rb_triangle_set, "_segments_for", rb_triangle_set_segment_ids_for_triangle, 1);
62
+ rb_define_method(rb_triangle_set, "_with_common_segment", rb_triangle_set_triangles_with_common_segment_id, 1);
63
+ rb_define_method(rb_triangle_set, "_in_segment", rb_triangle_set_structures_in_segment, 2);
64
+
65
+ rb_define_alloc_func(rb_point_set, rb_point_set_alloc);
66
+ rb_define_method(rb_point_set, "<<", rb_point_set_insert, 1);
67
+ rb_define_method(rb_point_set, "each", rb_point_set_each, 0);
68
+ rb_define_method(rb_point_set, "size", rb_geo_set_size, 0);
69
+ rb_define_method(rb_point_set, "inspect", rb_geo_set_inspect, 0);
70
+ rb_define_method(rb_point_set, "include?", rb_point_set_include, 1);
71
+ rb_define_method(rb_point_set, "delete!", rb_point_set_delete, 1);
72
+ rb_define_method(rb_point_set, "clone", rb_point_set_clone, 0);
73
+
74
+ rb_define_alloc_func(rb_line_set, rb_line_set_alloc);
75
+ rb_define_method(rb_line_set, "<<", rb_line_set_insert, 1);
76
+ rb_define_method(rb_line_set, "each", rb_line_set_each, 0);
77
+ rb_define_method(rb_line_set, "size", rb_geo_set_size, 0);
78
+ rb_define_method(rb_line_set, "inspect", rb_geo_set_inspect, 0);
79
+ rb_define_method(rb_line_set, "intersects?", rb_line_set_intersects, 1);
80
+ rb_define_method(rb_line_set, "closest_intersection", rb_line_set_closest_intersection, 1);
81
+ rb_define_method(rb_line_set, "slide", rb_line_set_slide, 1);
82
+ rb_define_method(rb_line_set, "include?", rb_line_set_include, 1);
83
+ rb_define_method(rb_line_set, "delete!", rb_line_set_delete, 1);
84
+ rb_define_method(rb_line_set, "intersections", rb_line_set_intersections, 1);
85
+ rb_define_method(rb_line_set, "nr_of_intersections", rb_line_set_n_intersections, 1);
86
+ rb_define_method(rb_line_set, "intersection_free_endpoints", rb_line_set_intersection_free_endpoints, -1);
87
+ rb_define_method(rb_line_set, "clone", rb_line_set_clone, 0);
88
+ rb_define_method(rb_line_set, "_segment_side", rb_geo_set_segment_side, 0);
89
+ rb_define_method(rb_line_set, "_reindex", rb_line_set_reindex, 0);
90
+ rb_define_method(rb_line_set, "_in_segment", rb_line_set_structures_in_segment, 2);
91
+ rb_define_method(rb_line_set, "_segments_for", rb_line_set_segment_ids_for_line, 1);
92
+ rb_define_method(rb_line_set, "_segment_lines", rb_geo_set_segment_lines, 0);
93
+ rb_define_method(rb_line_set, "_bottom_left", rb_geo_set_bottom_left, 0);
94
+ rb_define_method(rb_line_set, "_top_right", rb_geo_set_top_right, 0);
95
+ rb_define_method(rb_line_set, "_width", rb_geo_set_width, 0);
96
+ rb_define_method(rb_line_set, "_height", rb_geo_set_height, 0);
97
+ rb_define_method(rb_line_set, "_with_common_segment", rb_line_set_lines_with_common_segment_id, 1);
98
+
99
+ rb_define_alloc_func(rb_triangle, rb_triangle_alloc);
100
+ rb_define_method(rb_triangle, "initialize", rb_triangle_initialize, -1);
101
+ rb_define_method(rb_triangle, "inspect", rb_triangle_inspect, 0);
102
+ rb_define_method(rb_triangle, "==", rb_triangle_equals, 1);
103
+ rb_define_method(rb_triangle, "p1", rb_triangle_p1, 0);
104
+ rb_define_method(rb_triangle, "p2", rb_triangle_p2, 0);
105
+ rb_define_method(rb_triangle, "p3", rb_triangle_p3, 0);
106
+ rb_define_method(rb_triangle, "p1=", rb_triangle_set_p1, 0);
107
+ rb_define_method(rb_triangle, "p2=", rb_triangle_set_p2, 0);
108
+ rb_define_method(rb_triangle, "p3=", rb_triangle_set_p3, 0);
109
+ rb_define_method(rb_triangle, "clone", rb_triangle_clone, 0);
110
+ rb_define_method(rb_triangle, "area", rb_triangle_area, 0);
111
+ rb_define_method(rb_triangle, "contains?", rb_triangle_contains, 1);
112
+ rb_define_method(rb_triangle, "intersects?", rb_triangle_intersects, 1);
113
+ rb_define_method(rb_triangle, "overlap", rb_triangle_overlap, 1);
114
+ rb_define_method(rb_triangle, "<=>", rb_triangle_cmp, 1);
115
+
116
+ rb_define_alloc_func(rb_line, rb_line_alloc);
117
+ rb_define_method(rb_line, "initialize", rb_line_initialize, -1);
118
+ rb_define_method(rb_line, "inspect", rb_line_inspect, 0);
119
+ rb_define_method(rb_line, "reverse", rb_line_reverse, 0);
120
+ rb_define_method(rb_line, "p1", rb_line_p1, 0);
121
+ rb_define_method(rb_line, "p2", rb_line_p2, 0);
122
+ rb_define_method(rb_line, "p1=", rb_line_set_p1, 1);
123
+ rb_define_method(rb_line, "p2=", rb_line_set_p2, 1);
124
+ rb_define_method(rb_line, "outside?", rb_line_outside, 1);
125
+ rb_define_method(rb_line, "within?", rb_line_within, 1);
126
+ rb_define_method(rb_line, "intersection", rb_line_intersection, 1);
127
+ rb_define_method(rb_line, "==", rb_line_equals, 1);
128
+ rb_define_method(rb_line, "*", rb_line_dot, 1);
129
+ rb_define_method(rb_line, "abs", rb_line_abs, 0);
130
+ rb_define_method(rb_line, "abs=", rb_line_set_abs, 1);
131
+ rb_define_method(rb_line, "angle", rb_line_angle, 0);
132
+ rb_define_method(rb_line, "angle=", rb_line_set_angle, 1);
133
+ rb_define_method(rb_line, "clone", rb_line_clone, 0);
134
+ rb_define_method(rb_line, "side", rb_line_side, 1);
135
+ rb_define_method(rb_line, "contains?", rb_line_contains, 1);
136
+ rb_define_method(rb_line, "parallel", rb_line_parallel, 1);
137
+ rb_define_method(rb_line, "<=>", rb_line_cmp, 1);
138
+
139
+ rb_define_alloc_func(rb_point, rb_point_alloc);
140
+ rb_define_method(rb_point, "initialize", rb_point_initialize, 2);
141
+ rb_define_method(rb_point, "inspect", rb_point_inspect, 0);
142
+ rb_define_method(rb_point, "x", rb_point_x, 0);
143
+ rb_define_method(rb_point, "y", rb_point_y, 0);
144
+ rb_define_method(rb_point, "x=", rb_point_set_x, 1);
145
+ rb_define_method(rb_point, "y=", rb_point_set_y, 1);
146
+ rb_define_method(rb_point, "*", rb_point_dot, 1);
147
+ rb_define_method(rb_point, "==", rb_point_equals, 1);
148
+ rb_define_method(rb_point, "abs", rb_point_abs, 0);
149
+ rb_define_method(rb_point, "angle", rb_point_angle, 0);
150
+ rb_define_method(rb_point, "angle=", rb_point_set_angle, 1);
151
+ rb_define_method(rb_point, "abs=", rb_point_set_abs, 1);
152
+ rb_define_method(rb_point, "to", rb_point_to, -1);
153
+ rb_define_method(rb_point, "clone", rb_point_clone, 0);
154
+ rb_define_method(rb_point, "on?", rb_point_on, 1);
155
+ rb_define_method(rb_point, "in?", rb_point_in, 1);
156
+ rb_define_method(rb_point, "<=>", rb_point_cmp, 1);
157
+ rb_define_method(rb_point, "+", rb_point_plus, 1);
158
+ rb_define_method(rb_point, "-", rb_point_minus, 1);
159
+ }
160
+ #ifdef __cplusplus
161
+ }
162
+ #endif
163
+