bribera-rubyvor 0.0.3 → 0.0.4
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/History.txt +9 -0
- data/Manifest.txt +7 -0
- data/Rakefile +1 -1
- data/ext/extconf.rb +2 -2
- data/ext/output.c +2 -0
- data/ext/rb_cComputation.c +281 -0
- data/ext/rb_cPriorityQueue.c +106 -0
- data/ext/ruby_vor.c +41 -0
- data/ext/ruby_vor.h +23 -0
- data/ext/vdefs.h +2 -1
- data/ext/voronoi.c +2 -11
- data/lib/ruby_vor/computation.rb +126 -15
- data/lib/ruby_vor/point.rb +4 -0
- data/lib/ruby_vor/priority_queue.rb +60 -0
- data/lib/ruby_vor/version.rb +1 -1
- data/lib/ruby_vor.rb +3 -2
- data/rubyvor.gemspec +8 -6
- data/test/test_computation.rb +175 -0
- data/test/test_priority_queue.rb +56 -0
- data/test/test_voronoi_interface.rb +6 -3
- metadata +11 -2
- data/ext/voronoi_interface.c +0 -217
data/lib/ruby_vor/computation.rb
CHANGED
@@ -1,28 +1,139 @@
|
|
1
1
|
module RubyVor
|
2
|
-
|
3
|
-
# Voronoi Digram and Delaunay Triangulation namespace.
|
4
2
|
module VDDT
|
5
|
-
|
6
|
-
# Represents a computation from a set of 2-dimensional points
|
7
3
|
class Computation
|
8
4
|
attr_reader :points, :voronoi_diagram_raw, :delaunay_triangulation_raw
|
9
|
-
|
5
|
+
|
6
|
+
# Create a computation from an existing set of raw data.
|
10
7
|
def initialize(points=[], vd_raw=[], dt_raw=[])
|
8
|
+
@points = points
|
11
9
|
@voronoi_diagram_raw = vd_raw
|
12
|
-
@delaunay_triangulation_raw
|
10
|
+
@delaunay_triangulation_raw = dt_raw
|
11
|
+
@nn_graph = nil
|
13
12
|
end
|
14
13
|
|
15
|
-
|
14
|
+
# Uses the nearest-neighbors information encapsulated by the Delaunay triangulation as a seed for clustering:
|
15
|
+
# We take the edges (there are O(n) of them, because defined by the triangulation and delete any edge above a certain distance.
|
16
|
+
#
|
17
|
+
# This method allows the caller to pass in a lambda for customizing distance calculations. For instance, to use a GeoRuby::SimpleFeatures::Point, one would:
|
18
|
+
# > cluster_by_distance(50 lambda{|a,b| a.spherical_distance(b, 3958.754)}) # this rejects edges greater than 50 miles, using spherical distance as a measure
|
19
|
+
def cluster_by_distance(max_distance, dist_proc=lambda{|a,b| a.distance_from(b)})
|
20
|
+
|
21
|
+
clusters = []
|
22
|
+
nodes = (0..points.length-1).to_a
|
23
|
+
visited = []
|
24
|
+
|
25
|
+
v = 0
|
26
|
+
graph = nn_graph.map do |neighbors|
|
27
|
+
neighbors = neighbors.reject do |neighbor|
|
28
|
+
dist_proc[points[v], points[neighbor]] > max_distance
|
29
|
+
end
|
30
|
+
v += 1
|
31
|
+
neighbors
|
32
|
+
end
|
33
|
+
|
34
|
+
until nodes.empty?
|
35
|
+
v = nodes.pop
|
36
|
+
|
37
|
+
next if visited[v]
|
38
|
+
|
39
|
+
cluster = []
|
40
|
+
visited[v] = true
|
41
|
+
cluster.push(v)
|
42
|
+
|
43
|
+
children = graph[v]
|
44
|
+
until children.nil? || children.empty?
|
45
|
+
cnode = children.pop
|
46
|
+
next if cnode.nil? || visited[cnode]
|
47
|
+
|
48
|
+
visited[cnode] = true
|
49
|
+
cluster.push(cnode)
|
50
|
+
children.concat(graph[cnode])
|
51
|
+
end
|
52
|
+
|
53
|
+
clusters.push(cluster)
|
54
|
+
end
|
16
55
|
|
17
|
-
|
18
|
-
#
|
19
|
-
# This implementation uses Steven Fortune's sweepline algorithm, which runs in O(n log n) time and O(n) space.
|
20
|
-
# It is limited to 2-dimensional space, therefore it expects to receive an array of objects that respond to 'x' and 'y' methods.
|
21
|
-
def from_points(p)
|
22
|
-
# Stub; implemented as C function in voronoi_interface.so
|
23
|
-
end
|
56
|
+
clusters
|
24
57
|
end
|
25
|
-
|
58
|
+
|
59
|
+
# Computes the minimum spanning tree for given points, using the Delaunay triangulation as a seed.
|
60
|
+
#
|
61
|
+
# For points on a Euclidean plane, the MST is always comprised of a subset of the edges in a Delaunay triangulation. This makes computation of the tree very efficient: simply compute the Delaunay triangulation, and then run Prim's algorithm on the resulting edges.
|
62
|
+
def minimum_spanning_tree(dist_proc=lambda{|a,b| a.distance_from(b)})
|
63
|
+
nodes = []
|
64
|
+
q = RubyVor::PriorityQueue.new
|
65
|
+
(0..points.length-1).to_a.map do |n|
|
66
|
+
q.push({
|
67
|
+
:node => n,
|
68
|
+
:parent => nil,
|
69
|
+
:adjacency_list => nn_graph[n].clone,
|
70
|
+
:min_adjacency_list => [],
|
71
|
+
:in_q => true
|
72
|
+
}, (n == 0) ? 0.0 : Float::MAX)
|
73
|
+
end
|
74
|
+
|
75
|
+
q.data.each do |n|
|
76
|
+
n.data[:adjacency_list].map!{|v| q.data[v]}
|
77
|
+
nodes.push(n)
|
78
|
+
end
|
79
|
+
|
80
|
+
while latest_addition = q.pop
|
81
|
+
latest_addition.data[:in_q] = false
|
82
|
+
|
83
|
+
if latest_addition.data[:parent]
|
84
|
+
latest_addition.data[:parent].data[:min_adjacency_list].push(latest_addition)
|
85
|
+
latest_addition.data[:min_adjacency_list].push(latest_addition.data[:parent])
|
86
|
+
end
|
87
|
+
|
88
|
+
latest_addition.data[:adjacency_list].each do |adjacent|
|
89
|
+
|
90
|
+
if adjacent.data[:in_q]
|
91
|
+
|
92
|
+
adjacent_distance = dist_proc[ points[latest_addition.data[:node]], points[adjacent.data[:node]] ]
|
93
|
+
|
94
|
+
if adjacent_distance < adjacent.priority
|
95
|
+
adjacent.data[:parent] = latest_addition
|
96
|
+
adjacent.priority = adjacent_distance
|
97
|
+
q.percolate_up(adjacent.index)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
nodes.map! do |n|
|
106
|
+
n.data[:min_adjacency_list].map!{|v| v.data[:node]}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def cluster_by_size(sizes=[])
|
111
|
+
# TODO
|
112
|
+
# * Create a minimum_spanning_tree routine to:
|
113
|
+
# 1. compute weights (should be done for us in C?)
|
114
|
+
# 2. Use Prim's algorithm for computation
|
115
|
+
# * Take MST, and
|
116
|
+
# 1. For n in sizes (taken in descending order), delete the n most expensive edges from MST
|
117
|
+
# * use a MaxHeap?
|
118
|
+
# 2. Determine remaining connectivity using BFS as above?
|
119
|
+
# 3. Some other more efficient connectivity test?
|
120
|
+
# 4. Return {n1 => cluster, n2 => cluster} for all n.
|
121
|
+
end
|
122
|
+
|
123
|
+
protected
|
124
|
+
|
125
|
+
def weighted_edges(dist_proc)
|
126
|
+
v = 0
|
127
|
+
edges = nn_graph.inject({}) do |eh, neighbors|
|
128
|
+
neighbors.each do |neighbor|
|
129
|
+
k = [v,neighbor].sort
|
130
|
+
eh[k] = dist_proc.call(points[v],points[neighbor]) unless eh.has_key?(k)
|
131
|
+
end
|
132
|
+
v += 1
|
133
|
+
eh
|
134
|
+
end.to_a
|
135
|
+
end
|
136
|
+
|
26
137
|
end
|
27
138
|
end
|
28
139
|
end
|
data/lib/ruby_vor/point.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
module RubyVor
|
2
|
+
class PriorityQueue
|
3
|
+
|
4
|
+
attr_reader :data, :size
|
5
|
+
|
6
|
+
def initialize(d=[])
|
7
|
+
@data = d || []
|
8
|
+
@size = d.length
|
9
|
+
|
10
|
+
heapify()
|
11
|
+
end
|
12
|
+
|
13
|
+
def peek
|
14
|
+
@data[0]
|
15
|
+
end
|
16
|
+
|
17
|
+
def pop
|
18
|
+
return nil if @size < 1
|
19
|
+
|
20
|
+
r = @data[0]
|
21
|
+
|
22
|
+
@data[0] = @data[@size-1]
|
23
|
+
@data[0].index = 1
|
24
|
+
@data.delete_at(@size-1)
|
25
|
+
|
26
|
+
@size -= 1
|
27
|
+
|
28
|
+
percolate_down(1) if @size > 0
|
29
|
+
|
30
|
+
return r
|
31
|
+
end
|
32
|
+
|
33
|
+
def push(data, priority=Float::MAX)
|
34
|
+
@size += 1
|
35
|
+
@data[@size - 1] = QueueItem.new(priority, @size - 1, data)
|
36
|
+
percolate_up(@size)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Implemented in C
|
40
|
+
def reorder_queue;end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
# Implemented in C
|
45
|
+
def percolate_up(i);end
|
46
|
+
|
47
|
+
# Implemented in C
|
48
|
+
def percolate_down(i);end
|
49
|
+
|
50
|
+
class QueueItem
|
51
|
+
attr_accessor :priority, :index, :data
|
52
|
+
def initialize(p, i, d)
|
53
|
+
@priority = p
|
54
|
+
@index = i
|
55
|
+
@data = d
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/ruby_vor/version.rb
CHANGED
data/lib/ruby_vor.rb
CHANGED
@@ -3,10 +3,11 @@ $:.unshift File.join(File.dirname(__FILE__), '..', 'ext')
|
|
3
3
|
|
4
4
|
require 'ruby_vor/version'
|
5
5
|
require 'ruby_vor/point'
|
6
|
+
require 'ruby_vor/priority_queue'
|
6
7
|
require 'ruby_vor/computation'
|
7
8
|
|
8
|
-
# Require
|
9
|
-
require '
|
9
|
+
# Require ruby_vor.so last to clobber old from_points
|
10
|
+
require 'ruby_vor.so'
|
10
11
|
|
11
12
|
# DOC HERE
|
12
13
|
module RubyVor
|
data/rubyvor.gemspec
CHANGED
@@ -1,29 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
1
3
|
Gem::Specification.new do |s|
|
2
4
|
s.name = %q{rubyvor}
|
3
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.4"
|
4
6
|
|
5
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
8
|
s.authors = ["Brendan Ribera"]
|
7
|
-
s.date = %q{2008-12-
|
9
|
+
s.date = %q{2008-12-10}
|
8
10
|
s.description = %q{RubyVor provides efficient computation of Voronoi diagrams and Delaunay triangulation for a set of Ruby points. It is intended to function as a complemenet to GeoRuby. These structures can be used to compute a nearest-neighbor graph for a set of points. This graph can in turn be used for proximity-based clustering of the input points.}
|
9
11
|
s.email = ["brendan.ribera+rubyvor@gmail.com"]
|
10
12
|
s.extensions = ["ext/extconf.rb"]
|
11
13
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
12
|
-
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "ext/Doc", "ext/edgelist.c", "ext/extconf.rb", "ext/geometry.c", "ext/heap.c", "ext/memory.c", "ext/output.c", "ext/vdefs.h", "ext/voronoi.c", "ext/voronoi_interface.c", "lib/ruby_vor.rb", "lib/ruby_vor/computation.rb", "lib/ruby_vor/point.rb", "lib/ruby_vor/version.rb", "rubyvor.gemspec", "test/test_voronoi_interface.rb"]
|
14
|
+
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "ext/Doc", "ext/edgelist.c", "ext/extconf.rb", "ext/geometry.c", "ext/heap.c", "ext/memory.c", "ext/output.c", "ext/rb_cComputation.c", "ext/rb_cPriorityQueue.c", "ext/ruby_vor.c", "ext/ruby_vor.h", "ext/vdefs.h", "ext/voronoi.c", "ext/voronoi_interface.c", "lib/ruby_vor.rb", "lib/ruby_vor/computation.rb", "lib/ruby_vor/point.rb", "lib/ruby_vor/priority_queue.rb", "lib/ruby_vor/version.rb", "rubyvor.gemspec", "test/test_computation.rb", "test/test_priority_queue.rb", "test/test_voronoi_interface.rb"]
|
13
15
|
s.has_rdoc = true
|
14
16
|
s.homepage = %q{http://github.com/bribera/rubyvor}
|
15
17
|
s.rdoc_options = ["--main", "README.txt"]
|
16
18
|
s.require_paths = ["lib", "ext"]
|
17
19
|
s.rubyforge_project = %q{rubyvor}
|
18
|
-
s.rubygems_version = %q{1.
|
20
|
+
s.rubygems_version = %q{1.3.1}
|
19
21
|
s.summary = %q{RubyVor provides efficient computation of Voronoi diagrams and Delaunay triangulation for a set of Ruby points}
|
20
|
-
s.test_files = ["test/test_voronoi_interface.rb"]
|
22
|
+
s.test_files = ["test/test_voronoi_interface.rb", "test/test_computation.rb", "test/test_priority_queue.rb"]
|
21
23
|
|
22
24
|
if s.respond_to? :specification_version then
|
23
25
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
26
|
s.specification_version = 2
|
25
27
|
|
26
|
-
if
|
28
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
29
|
s.add_development_dependency(%q<hoe>, [">= 1.8.2"])
|
28
30
|
else
|
29
31
|
s.add_dependency(%q<hoe>, [">= 1.8.2"])
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'minitest/unit'
|
3
|
+
require File.dirname(__FILE__) + '/../lib/ruby_vor'
|
4
|
+
|
5
|
+
class TestComputation < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
@points = @trianglulation_raw = @diagram_raw = nil
|
9
|
+
super(*args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_nn_graph
|
13
|
+
comp = RubyVor::VDDT::Computation.from_points(sample_points)
|
14
|
+
|
15
|
+
# based on this expected delaunay trianglulation:
|
16
|
+
# 3 2 1
|
17
|
+
# 3 0 2
|
18
|
+
# 8 2 0
|
19
|
+
# 3 8 0
|
20
|
+
# 5 6 8
|
21
|
+
# 7 6 5
|
22
|
+
# 7 4 6
|
23
|
+
# 6 2 8
|
24
|
+
# 8 7 5
|
25
|
+
|
26
|
+
expected_graph = [
|
27
|
+
[2, 3, 8], # 0
|
28
|
+
[2, 3], # 1
|
29
|
+
[0, 1, 3, 6, 8], # 2
|
30
|
+
[0, 1, 2, 8], # 3
|
31
|
+
[6, 7], # 4
|
32
|
+
[6, 7, 8], # 5
|
33
|
+
[2, 4, 5, 7, 8], # 6
|
34
|
+
[4, 5, 6, 8], # 7
|
35
|
+
[0, 2, 3, 5, 6, 7], # 8
|
36
|
+
]
|
37
|
+
|
38
|
+
assert_equal comp.nn_graph.map{|v| v.sort}.sort, \
|
39
|
+
expected_graph.map{|v| v.sort}.sort
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_simple_mst
|
43
|
+
points = [
|
44
|
+
RubyVor::Point.new(0,0),
|
45
|
+
RubyVor::Point.new(1.0,1.1),
|
46
|
+
RubyVor::Point.new(4.9,3.1),
|
47
|
+
]
|
48
|
+
|
49
|
+
comp = RubyVor::VDDT::Computation.from_points(points)
|
50
|
+
|
51
|
+
expected_mst = [
|
52
|
+
[1],
|
53
|
+
[0,2],
|
54
|
+
[1]
|
55
|
+
]
|
56
|
+
|
57
|
+
assert_equal expected_mst.map{|v| v.sort}.sort, \
|
58
|
+
comp.minimum_spanning_tree.map{|v| v.sort}.sort
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_advanced_mst
|
62
|
+
# Test tree taken from an example SVG included in the Wikipedia article on Euclidean minimum spanning trees:
|
63
|
+
# http://en.wikipedia.org/wiki/Image:Euclidean_minimum_spanning_tree.svg
|
64
|
+
|
65
|
+
points = [
|
66
|
+
RubyVor::Point.new(155.692, 99.783), # 0
|
67
|
+
RubyVor::Point.new(162.285, 120.245), # 1
|
68
|
+
RubyVor::Point.new(143.692, 129.893), # 2
|
69
|
+
RubyVor::Point.new(150.128, 167.924), # 3
|
70
|
+
RubyVor::Point.new(137.617, 188.953), # 4
|
71
|
+
RubyVor::Point.new(193.467, 119.345), # 5
|
72
|
+
RubyVor::Point.new(196.754, 88.47), # 6
|
73
|
+
RubyVor::Point.new(241.629, 70.845), # 7
|
74
|
+
RubyVor::Point.new(262.692, 59.97), # 8
|
75
|
+
RubyVor::Point.new(269.629, 63.158), # 9
|
76
|
+
RubyVor::Point.new(247.257, 200.669), # 10
|
77
|
+
RubyVor::Point.new(231.28, 245.974), # 11
|
78
|
+
RubyVor::Point.new(268.002, 264.693), # 12
|
79
|
+
RubyVor::Point.new(155.442, 64.473), # 13
|
80
|
+
RubyVor::Point.new(198.598, 31.804), # 14
|
81
|
+
RubyVor::Point.new(216.816, 3.513), # 15
|
82
|
+
RubyVor::Point.new(89.624, 27.344), # 16
|
83
|
+
RubyVor::Point.new(67.925, 56.999), # 17
|
84
|
+
RubyVor::Point.new(77.328, 93.404), # 18
|
85
|
+
RubyVor::Point.new(65.525, 158.783), # 19
|
86
|
+
RubyVor::Point.new(63.525,170.783), # 20
|
87
|
+
RubyVor::Point.new(15.192, 192.783), # 21
|
88
|
+
RubyVor::Point.new(7.025, 236.949), # 22
|
89
|
+
RubyVor::Point.new(40.525, 262.949), # 23
|
90
|
+
RubyVor::Point.new(61.692, 225.95) # 24
|
91
|
+
]
|
92
|
+
|
93
|
+
comp = RubyVor::VDDT::Computation.from_points(points)
|
94
|
+
|
95
|
+
expected_mst = [
|
96
|
+
[1,13], # 0
|
97
|
+
[0,2,5], # 1
|
98
|
+
[1,3], # 2
|
99
|
+
[2,4], # 3
|
100
|
+
[3], # 4
|
101
|
+
[1,6,10], # 5
|
102
|
+
[5,7], # 6
|
103
|
+
[6,8], # 7
|
104
|
+
[7,9], # 8
|
105
|
+
[8], # 9
|
106
|
+
[5,11], # 10
|
107
|
+
[10,12], # 11
|
108
|
+
[11], # 12
|
109
|
+
[0,14,16], # 13
|
110
|
+
[13,15], # 14
|
111
|
+
[14], # 15
|
112
|
+
[13,17], # 16
|
113
|
+
[16,18], # 17
|
114
|
+
[17,19], # 18
|
115
|
+
[18,20], # 19
|
116
|
+
[19,21], # 20
|
117
|
+
[20,22], # 21
|
118
|
+
[21,23], # 22
|
119
|
+
[22,24], # 23
|
120
|
+
[23] # 24
|
121
|
+
]
|
122
|
+
assert_equal expected_mst.map{|v| v.sort}.sort, \
|
123
|
+
comp.minimum_spanning_tree.map{|v| v.sort}.sort
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_cluster_by_distance
|
127
|
+
comp = RubyVor::VDDT::Computation.from_points(sample_points)
|
128
|
+
|
129
|
+
expected_clusters = [
|
130
|
+
[0,1,2,3],
|
131
|
+
[8],
|
132
|
+
[4,5,6,7]
|
133
|
+
]
|
134
|
+
|
135
|
+
# We want to ensure that the nn_graph isn't modified by this call
|
136
|
+
original_nn_graph = comp.nn_graph.map{|v| v.clone}
|
137
|
+
|
138
|
+
# Compute clusters within a distance of 10
|
139
|
+
computed_clusters = comp.cluster_by_distance(10)
|
140
|
+
|
141
|
+
assert_equal expected_clusters.map{|cl| cl.sort}.sort, \
|
142
|
+
computed_clusters.map{|cl| cl.sort}.sort
|
143
|
+
|
144
|
+
assert_equal original_nn_graph, \
|
145
|
+
comp.nn_graph
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# A few helper methods
|
151
|
+
#
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def sample_points
|
156
|
+
if @points.nil?
|
157
|
+
@points = [
|
158
|
+
[1.1,1],
|
159
|
+
[0,0],
|
160
|
+
[1,0],
|
161
|
+
[0,1.1],
|
162
|
+
|
163
|
+
[101.1,101],
|
164
|
+
[100,100],
|
165
|
+
[101,100],
|
166
|
+
[100,101.1],
|
167
|
+
|
168
|
+
[43, 55]
|
169
|
+
].map{|x,y| RubyVor::Point.new(x,y)}
|
170
|
+
end
|
171
|
+
@points
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
MiniTest::Unit.autorun
|
@@ -0,0 +1,56 @@
|
|
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,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
|
+
([10] * 10).each{|x| q.push(x,x)}
|
35
|
+
|
36
|
+
q.data[3] = RubyVor::PriorityQueue::QueueItem.new(-34, 3, -34)
|
37
|
+
q.data[4] = RubyVor::PriorityQueue::QueueItem.new(1, 4, 1)
|
38
|
+
q.data[5] = RubyVor::PriorityQueue::QueueItem.new(100, 5, 100)
|
39
|
+
q.data[7] = RubyVor::PriorityQueue::QueueItem.new(0.9, 7, 0.9)
|
40
|
+
q.data.sort!{|a,b| rand(3)-1}
|
41
|
+
|
42
|
+
q.heapify()
|
43
|
+
|
44
|
+
assert_equal(-34, q.pop.data)
|
45
|
+
assert_equal 0.9, q.pop.data
|
46
|
+
assert_equal 1, q.pop.data
|
47
|
+
assert_equal 10, q.pop.data
|
48
|
+
assert_equal 10, q.pop.data
|
49
|
+
assert_equal 10, q.pop.data
|
50
|
+
assert_equal 10, q.pop.data
|
51
|
+
assert_equal 10, q.pop.data
|
52
|
+
assert_equal 10, q.pop.data
|
53
|
+
assert_equal 100, q.pop.data
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -2,14 +2,16 @@ 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
17
|
# Perform the computation.
|
@@ -44,7 +46,7 @@ class TestVoronoiInterface < MiniTest::Unit::TestCase
|
|
44
46
|
|
45
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.
|
4
|
+
version: 0.0.4
|
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-
|
12
|
+
date: 2008-12-10 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -44,14 +44,21 @@ files:
|
|
44
44
|
- ext/heap.c
|
45
45
|
- ext/memory.c
|
46
46
|
- ext/output.c
|
47
|
+
- ext/rb_cComputation.c
|
48
|
+
- ext/rb_cPriorityQueue.c
|
49
|
+
- ext/ruby_vor.c
|
50
|
+
- ext/ruby_vor.h
|
47
51
|
- ext/vdefs.h
|
48
52
|
- ext/voronoi.c
|
49
53
|
- ext/voronoi_interface.c
|
50
54
|
- lib/ruby_vor.rb
|
51
55
|
- lib/ruby_vor/computation.rb
|
52
56
|
- lib/ruby_vor/point.rb
|
57
|
+
- lib/ruby_vor/priority_queue.rb
|
53
58
|
- lib/ruby_vor/version.rb
|
54
59
|
- rubyvor.gemspec
|
60
|
+
- test/test_computation.rb
|
61
|
+
- test/test_priority_queue.rb
|
55
62
|
- test/test_voronoi_interface.rb
|
56
63
|
has_rdoc: true
|
57
64
|
homepage: http://github.com/bribera/rubyvor
|
@@ -83,3 +90,5 @@ specification_version: 2
|
|
83
90
|
summary: RubyVor provides efficient computation of Voronoi diagrams and Delaunay triangulation for a set of Ruby points
|
84
91
|
test_files:
|
85
92
|
- test/test_voronoi_interface.rb
|
93
|
+
- test/test_computation.rb
|
94
|
+
- test/test_priority_queue.rb
|