bribera-rubyvor 0.0.2 → 0.1.1

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.
@@ -0,0 +1,129 @@
1
+ require 'rubygems'
2
+ require 'minitest/unit'
3
+ require File.dirname(__FILE__) + '/../lib/ruby_vor'
4
+
5
+ class TestPriorityQueue < MiniTest::Unit::TestCase
6
+
7
+ def test_heap_order_property
8
+ # min heap by default
9
+ q = RubyVor::PriorityQueue.new
10
+
11
+ items = [1,2,3,4,5,6,99,4,-20,101,5412,2,-1,-1,-1,33.0,0,55,7,12321,123.123,-123.123,0,0,0]
12
+ items.each{|i| q.push(i)}
13
+
14
+ items.sort!
15
+ idx = 0
16
+
17
+ # Test peek
18
+ assert_equal q.peek.data, items[0]
19
+
20
+ while min = q.pop
21
+ # Test pop
22
+ assert_equal min.data, items[idx]
23
+
24
+ # Test peek
25
+ assert_equal q.peek.data, items[idx + 1] if idx + 1 < items.length
26
+
27
+ idx += 1
28
+ end
29
+ end
30
+
31
+ def test_heapify
32
+ q = RubyVor::PriorityQueue.new
33
+
34
+ # Create a randomized data set.
35
+ #
36
+ # Not ideal for unit tests, since they *should* be done
37
+ # on static data so that failure/success is deterministic...
38
+ # but works for me.
39
+
40
+ 100.times{ q.push(rand * 10000.0 - 5000.0)}
41
+
42
+ # Set things right.
43
+ q.heapify()
44
+
45
+ old_n = -1.0 * Float::MAX
46
+ while n = q.pop
47
+ assert n.priority >= old_n, 'Heap-order property violated'
48
+ old_n = n.priority
49
+ end
50
+ end
51
+
52
+ def test_bad_data
53
+ q = RubyVor::PriorityQueue.new
54
+ 10.times { q.push(rand * 100.0 - 50.0) }
55
+
56
+ #
57
+ # Heapify
58
+ #
59
+ old_data = q.data[1]
60
+ q.data[1] = 45
61
+ assert_raises TypeError do
62
+ q.heapify()
63
+ end
64
+ q.data[1] = old_data
65
+ assert_nothing_raised do
66
+ q.heapify()
67
+ end
68
+
69
+
70
+ #
71
+ # Percolation
72
+ #
73
+ [100, -100].each do |i|
74
+ assert_raises IndexError do
75
+ q.percolate_up(i)
76
+ end
77
+ assert_raises IndexError do
78
+ q.percolate_down(i)
79
+ end
80
+ end
81
+ [:x, Class, nil, false].each do |i|
82
+ assert_raises TypeError do
83
+ q.percolate_up(i)
84
+ end
85
+ assert_raises TypeError do
86
+ q.percolate_down(i)
87
+ end
88
+ end
89
+ [0,1,2,3].each do |i|
90
+ assert_nothing_raised do
91
+ q.percolate_up(i)
92
+ end
93
+ assert_nothing_raised do
94
+ q.percolate_down(i)
95
+ end
96
+ end
97
+ end
98
+
99
+ def test_build_queue
100
+ n = 100
101
+
102
+ q = RubyVor::PriorityQueue.build_queue(n) do |queue_item|
103
+ queue_item.priority = rand * 10000.0 - 5000.0
104
+ end
105
+
106
+ assert_equal n, q.data.length
107
+ assert_equal n, q.size
108
+
109
+ old_n = -1.0 * Float::MAX
110
+ while n = q.pop
111
+ assert n.priority >= old_n, 'Heap-order property violated'
112
+ old_n = n.priority
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ def assert_nothing_raised(&b)
119
+ begin
120
+ yield
121
+ rescue Exception => e
122
+ flunk "#{mu_pp(e)} exception encountered, expected no exceptions"
123
+ return
124
+ end
125
+ pass()
126
+ end
127
+ end
128
+
129
+ MiniTest::Unit.autorun
@@ -2,24 +2,26 @@ require 'rubygems'
2
2
  require 'minitest/unit'
3
3
  require File.dirname(__FILE__) + '/../lib/ruby_vor'
4
4
 
5
+
5
6
  class TestVoronoiInterface < MiniTest::Unit::TestCase
6
7
 
7
- MAX_DELTA = 0.000001
8
-
9
8
  def initialize(*args)
10
9
  @points = @trianglulation_raw = @diagram_raw = nil
11
10
  super(*args)
12
11
  end
12
+
13
+
14
+ MAX_DELTA = 0.000001
13
15
 
14
16
  def test_diagram_correct
15
- # Perform the decomposition.
16
- decomp = RubyVor::VDDT::Decomposition.from_points(sample_points)
17
+ # Perform the computation.
18
+ comp = RubyVor::VDDT::Computation.from_points(sample_points)
17
19
 
18
20
  # Test each raw entry against three basic assertions:
19
21
  # * entry lengths must match
20
22
  # * entry types must match
21
23
  # * entry values must match, with allowance for rounding errors (i.e. within a very small delta)
22
- decomp.voronoi_diagram_raw.each_with_index do |computed_entry, i|
24
+ comp.voronoi_diagram_raw.each_with_index do |computed_entry, i|
23
25
  sample_entry = example_diagram_raw[i]
24
26
 
25
27
 
@@ -36,15 +38,15 @@ class TestVoronoiInterface < MiniTest::Unit::TestCase
36
38
 
37
39
 
38
40
  def test_triangulation_correct
39
- # Perform the decomposition.
40
- decomp = RubyVor::VDDT::Decomposition.from_points(sample_points)
41
+ # Perform the computation.
42
+ comp = RubyVor::VDDT::Computation.from_points(sample_points)
41
43
 
42
44
  # One assertion:
43
45
  # * raw triangulation must match exactly.
44
46
 
45
- assert_equal example_triangulation_raw, decomp.delaunay_triangulation_raw
47
+ assert_equal example_triangulation_raw, comp.delaunay_triangulation_raw
46
48
  end
47
-
49
+
48
50
 
49
51
 
50
52
  #
@@ -153,6 +155,7 @@ class TestVoronoiInterface < MiniTest::Unit::TestCase
153
155
  end
154
156
  @trianglulation_raw
155
157
  end
158
+
156
159
  end
157
160
 
158
161
  MiniTest::Unit.autorun
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bribera-rubyvor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brendan Ribera
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-03 00:00:00 -08:00
12
+ date: 2009-01-15 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -44,14 +44,24 @@ files:
44
44
  - ext/heap.c
45
45
  - ext/memory.c
46
46
  - ext/output.c
47
+ - ext/rb_cComputation.c
48
+ - ext/rb_cPoint.c
49
+ - ext/rb_cPriorityQueue.c
50
+ - ext/ruby_vor_c.c
51
+ - ext/ruby_vor_c.h
47
52
  - ext/vdefs.h
48
53
  - ext/voronoi.c
49
- - ext/voronoi_interface.c
50
54
  - lib/ruby_vor.rb
51
- - lib/ruby_vor/decomposition.rb
55
+ - lib/ruby_vor/computation.rb
56
+ - lib/ruby_vor/geo_ruby_extensions.rb
52
57
  - lib/ruby_vor/point.rb
58
+ - lib/ruby_vor/priority_queue.rb
53
59
  - lib/ruby_vor/version.rb
60
+ - lib/ruby_vor/visualizer.rb
54
61
  - rubyvor.gemspec
62
+ - test/test_computation.rb
63
+ - test/test_point.rb
64
+ - test/test_priority_queue.rb
55
65
  - test/test_voronoi_interface.rb
56
66
  has_rdoc: true
57
67
  homepage: http://github.com/bribera/rubyvor
@@ -82,4 +92,7 @@ signing_key:
82
92
  specification_version: 2
83
93
  summary: RubyVor provides efficient computation of Voronoi diagrams and Delaunay triangulation for a set of Ruby points
84
94
  test_files:
95
+ - test/test_computation.rb
96
+ - test/test_priority_queue.rb
85
97
  - test/test_voronoi_interface.rb
98
+ - test/test_point.rb
@@ -1,213 +0,0 @@
1
- #include <ruby.h>
2
- #include <vdefs.h>
3
- #include <stdio.h>
4
- #include <stdlib.h>
5
-
6
-
7
-
8
-
9
- VoronoiState rubyvorState;
10
-
11
- static VALUE rb_mRubyVor;
12
- static VALUE rb_mVDDT;
13
- static VALUE rb_cDecomposition;
14
- static int repeat, rit;
15
-
16
- // Static method definitions
17
- static VALUE from_points(VALUE, VALUE);
18
-
19
- static Site * readone(void), * nextone(void);
20
- static int scomp(const void *, const void *);
21
-
22
-
23
-
24
- void
25
- Init_voronoi_interface(void)
26
- {
27
- // Set up our Modules and Class.
28
- rb_mRubyVor = rb_define_module("RubyVor");
29
- rb_mVDDT = rb_define_module_under(rb_mRubyVor, "VDDT");
30
- rb_cDecomposition = rb_define_class_under(rb_mVDDT, "Decomposition", rb_cObject);
31
-
32
- // Add methods.
33
- rb_define_singleton_method(rb_cDecomposition, "from_points", from_points, 1);
34
- }
35
-
36
-
37
- //
38
- // Class methods
39
- //
40
- static VALUE
41
- from_points(VALUE self, VALUE pointsArray)
42
- {
43
- //VALUE returnValue;
44
- VALUE * inPtr, newDecomp;
45
- ID x, y;
46
-
47
- long i, inSize;
48
-
49
- // TODO: remove
50
- repeat = 1;
51
-
52
- for (rit = 0; rit < repeat; rit++) {
53
-
54
- // Require T_ARRAY
55
- Check_Type(pointsArray, T_ARRAY);
56
-
57
- // Intern our point access methods
58
- x = rb_intern("x");
59
- y = rb_intern("y");
60
-
61
- // Load up point count & points pointer.
62
- inSize = RARRAY(pointsArray)->len;
63
- inPtr = RARRAY(pointsArray)->ptr;
64
-
65
- // Require nonzero size and x & y methods on each array object
66
- if (inSize < 1)
67
- rb_raise(rb_eRuntimeError, "points array have a nonzero length");
68
- for (i = 0; i < inSize; i++) {
69
- if(!rb_respond_to(inPtr[i], x) || !rb_respond_to(inPtr[i], y))
70
- rb_raise(rb_eRuntimeError, "members of points array must respond to 'x' and 'y'");
71
- }
72
-
73
-
74
- // Initialize rubyvorState
75
- initialize_state(0/* debug? */);
76
-
77
- // Create our return object.
78
- newDecomp = rb_funcall(self, rb_intern("new"), 0);
79
- // Store it in rubyvorState so we can populate its values.
80
- rubyvorState.decomp = (void *) &newDecomp;
81
-
82
-
83
- //
84
- // Read in the sites, sort, and compute xmin, xmax, ymin, ymax
85
- //
86
- // TODO: refactor this block into a separate method for clarity?
87
- //
88
- {
89
- // Allocate memory for 4000 sites...
90
- rubyvorState.sites = (Site *) myalloc(4000 * sizeof(Site));
91
-
92
-
93
- // Iterate over the arrays, doubling the incoming values.
94
- for (i=0; i<inSize; i++)
95
- {
96
- rubyvorState.sites[rubyvorState.nsites].coord.x = NUM2DBL(rb_funcall(inPtr[i], x, 0));
97
- rubyvorState.sites[rubyvorState.nsites].coord.y = NUM2DBL(rb_funcall(inPtr[i], y, 0));
98
-
99
- //
100
- rubyvorState.sites[rubyvorState.nsites].sitenbr = rubyvorState.nsites;
101
- rubyvorState.sites[rubyvorState.nsites++].refcnt = 0;
102
-
103
- // Allocate for 4000 more if we just hit a multiple of 4000...
104
- if (rubyvorState.nsites % 4000 == 0)
105
- {
106
- rubyvorState.sites = (Site *)myrealloc(rubyvorState.sites,(rubyvorState.nsites+4000)*sizeof(Site),rubyvorState.nsites*sizeof(Site));
107
- }
108
- }
109
-
110
- // Sort the Sites
111
- qsort((void *)rubyvorState.sites, rubyvorState.nsites, sizeof(Site), scomp) ;
112
-
113
- // Pull the minimum values.
114
- rubyvorState.xmin = rubyvorState.sites[0].coord.x;
115
- rubyvorState.xmax = rubyvorState.sites[0].coord.x;
116
- for (i=1; i < rubyvorState.nsites; ++i)
117
- {
118
- if (rubyvorState.sites[i].coord.x < rubyvorState.xmin)
119
- {
120
- rubyvorState.xmin = rubyvorState.sites[i].coord.x;
121
- }
122
- if (rubyvorState.sites[i].coord.x > rubyvorState.xmax)
123
- {
124
- rubyvorState.xmax = rubyvorState.sites[i].coord.x;
125
- }
126
- }
127
- rubyvorState.ymin = rubyvorState.sites[0].coord.y;
128
- rubyvorState.ymax = rubyvorState.sites[rubyvorState.nsites-1].coord.y;
129
-
130
- }
131
-
132
-
133
- // Perform the computation
134
- voronoi(nextone);
135
-
136
- // Free our allocated objects
137
- free_all();
138
-
139
- if (rubyvorState.debug)
140
- fprintf(stderr,"FINISHED ITERATION %i\n", repeat + 1);
141
-
142
-
143
- }
144
-
145
- return newDecomp;
146
- }
147
-
148
-
149
-
150
-
151
- //
152
- // Static C methods
153
- //
154
-
155
- /*** sort sites on y, then x, coord ***/
156
- static int
157
- scomp(const void * vs1, const void * vs2)
158
- {
159
- Point * s1 = (Point *)vs1 ;
160
- Point * s2 = (Point *)vs2 ;
161
-
162
- if (s1->y < s2->y)
163
- {
164
- return (-1) ;
165
- }
166
- if (s1->y > s2->y)
167
- {
168
- return (1) ;
169
- }
170
- if (s1->x < s2->x)
171
- {
172
- return (-1) ;
173
- }
174
- if (s1->x > s2->x)
175
- {
176
- return (1) ;
177
- }
178
- return (0) ;
179
- }
180
-
181
- /*** return a single in-storage site ***/
182
- static Site *
183
- nextone(void)
184
- {
185
- Site * s ;
186
-
187
- if (rubyvorState.siteidx < rubyvorState.nsites)
188
- {
189
- s = &rubyvorState.sites[rubyvorState.siteidx++];
190
- return (s) ;
191
- }
192
- else
193
- {
194
- return ((Site *)NULL) ;
195
- }
196
- }
197
-
198
-
199
- /*** read one site ***/
200
- static Site *
201
- readone(void)
202
- {
203
- Site * s ;
204
-
205
- s = (Site *)getfree(&(rubyvorState.sfl)) ;
206
- s->refcnt = 0 ;
207
- s->sitenbr = rubyvorState.siteidx++ ;
208
- if (scanf("%f %f", &(s->coord.x), &(s->coord.y)) == EOF)
209
- {
210
- return ((Site *)NULL ) ;
211
- }
212
- return (s) ;
213
- }