hexagonly 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,208 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hexagonly::Hexagon do
4
+
5
+ describe "#hex_corners" do
6
+
7
+ context "if hex_center or hex_size have not been defined" do
8
+ subject { Hexagonly::Hexagon.new(nil, nil) }
9
+ it { expect { subject.hex_corners }.to raise_error Exception }
10
+ end
11
+
12
+ context "if hex_center and hex_size have been defined" do
13
+ subject { Hexagonly::Hexagon.new(Hexagonly::Point.new(5, 6), 2.1) }
14
+ let(:corners) do
15
+ [
16
+ [7.1, 6.0],
17
+ [6.050000000000001, 7.818653347947321],
18
+ [3.95, 7.818653347947321],
19
+ [2.9, 6.0],
20
+ [3.9499999999999993, 4.18134665205268],
21
+ [6.049999999999999, 4.181346652052678]
22
+ ]
23
+ end
24
+ it { subject.hex_corners.size == 5 }
25
+ it { (subject.hex_corners.map{ |p| [p.x_coord, p.y_coord] } - corners).should == [] }
26
+ end
27
+
28
+ end
29
+
30
+ describe "#loosely_contains?" do
31
+
32
+ context "if hex_center or hex_size have not been defined" do
33
+ subject { Hexagonly::Hexagon.new(nil, nil) }
34
+ it { expect { subject.loosely_contains?(Hexagonly::Point.new(1, 1)) }.to raise_error Exception }
35
+ end
36
+
37
+ context "if hex_center and hex_size have been defined" do
38
+ subject { Hexagonly::Hexagon.new(Hexagonly::Point.new(5, 6), 2.1) }
39
+ # Outside the bounding box
40
+ it { subject.loosely_contains?(Hexagonly::Point.new(5, 8)).should == false }
41
+ it { subject.loosely_contains?(Hexagonly::Point.new(5, 4)).should == false }
42
+ it { subject.loosely_contains?(Hexagonly::Point.new(2, 6)).should == false }
43
+ it { subject.loosely_contains?(Hexagonly::Point.new(8, 6)).should == false }
44
+ # Inside the bounding box but outside the hexagon
45
+ it { subject.loosely_contains?(Hexagonly::Point.new(3.3, 7)).should == true }
46
+ it { subject.loosely_contains?(Hexagonly::Point.new(6.7, 5)).should == true }
47
+ # Inside the hexagon
48
+ it { subject.loosely_contains?(Hexagonly::Point.new(5.1, 6.2)).should == true }
49
+ it { subject.loosely_contains?(Hexagonly::Point.new(4.2, 5.3)).should == true }
50
+ it { subject.loosely_contains?(Hexagonly::Point.new(5.0, 6.0)).should == true }
51
+ end
52
+
53
+ end
54
+
55
+ describe "#contains?" do
56
+
57
+ context "if hex_center or hex_size have not been defined" do
58
+ subject { Hexagonly::Hexagon.new(nil, nil) }
59
+ it { expect { subject.contains?(Hexagonly::Point.new(1, 1)) }.to raise_error Exception }
60
+ end
61
+
62
+ context "if hex_center and hex_size have been defined" do
63
+ subject { Hexagonly::Hexagon.new(Hexagonly::Point.new(5, 6), 2.1) }
64
+ # Outside the bounding box
65
+ it { subject.contains?(Hexagonly::Point.new(5, 8)).should == false }
66
+ it { subject.contains?(Hexagonly::Point.new(5, 4)).should == false }
67
+ it { subject.contains?(Hexagonly::Point.new(2, 6)).should == false }
68
+ it { subject.contains?(Hexagonly::Point.new(8, 6)).should == false }
69
+ # Inside the bounding box but outside the hexagon
70
+ it { subject.contains?(Hexagonly::Point.new(3.3, 7)).should == false }
71
+ it { subject.contains?(Hexagonly::Point.new(6.7, 5)).should == false }
72
+ # Inside the hexagon
73
+ it { subject.contains?(Hexagonly::Point.new(5.1, 6.2)).should == true }
74
+ it { subject.contains?(Hexagonly::Point.new(4.2, 5.3)).should == true }
75
+ it { subject.contains?(Hexagonly::Point.new(5.0, 6.0)).should == true }
76
+ end
77
+
78
+ end
79
+
80
+ describe "#grab" do
81
+
82
+ context "when none of the points belong to the hexagon" do
83
+ let(:rejected_points) { [[5, 8], [5, 4], [2, 6], [8, 6], [3.3, 7], [6.7, 5]].map{ |x, y| Hexagonly::Point.new(x, y) } }
84
+ subject do
85
+ hex = Hexagonly::Hexagon.new(Hexagonly::Point.new(5, 6), 2.1)
86
+ hex.grab(rejected_points)
87
+ hex
88
+ end
89
+ it { subject.collected_points.class.should == Array }
90
+ it { subject.collected_points.size.should == 0 }
91
+ it { subject.rejected_points.class.should == Array }
92
+ it { subject.rejected_points.should == rejected_points }
93
+ end
94
+
95
+ context "when some of the points belong to the hexagon" do
96
+ let(:accepted_points) { [[5.1, 6.2], [4.2, 5.3], [5.0, 6.0]].map{ |x, y| Hexagonly::Point.new(x, y) } }
97
+ let(:rejected_points) { [[5, 8], [5, 4], [2, 6], [8, 6], [3.3, 7], [6.7, 5]].map{ |x, y| Hexagonly::Point.new(x, y) } }
98
+ subject do
99
+ hex = Hexagonly::Hexagon.new(Hexagonly::Point.new(5, 6), 2.1)
100
+ hex.grab(accepted_points + rejected_points)
101
+ hex
102
+ end
103
+ it { subject.collected_points.class.should == Array }
104
+ it { subject.collected_points.should == accepted_points }
105
+ it { subject.rejected_points.class.should == Array }
106
+ it { subject.rejected_points.should == rejected_points }
107
+ end
108
+
109
+ context "when all of the points belong to the hexagon" do
110
+ let(:accepted_points) { [[5.1, 6.2], [4.2, 5.3], [5.0, 6.0]].map{ |x, y| Hexagonly::Point.new(x, y) } }
111
+ subject do
112
+ hex = Hexagonly::Hexagon.new(Hexagonly::Point.new(5, 6), 2.1)
113
+ hex.grab(accepted_points)
114
+ hex
115
+ end
116
+ it { subject.collected_points.class.should == Array }
117
+ it { subject.collected_points.should == accepted_points }
118
+ it { subject.rejected_points.class.should == Array }
119
+ it { subject.rejected_points.size.should == 0 }
120
+ end
121
+
122
+ end
123
+
124
+ describe ".pack" do
125
+
126
+ context "when using default classes and point grabbing" do
127
+ let(:points) { 100.times.map{ build(:point) } }
128
+ let(:hex_size) { 0.15 }
129
+ let(:params) { { :grab_points => true } }
130
+ subject { Hexagonly::Hexagon.pack(points, hex_size, params) }
131
+ it { subject.class.should == Array }
132
+ it { subject.each{ |hex| hex.collected_points.each{ |p| hex.contains?(p).should == true } } }
133
+ it { subject.inject([]){ |arr, hex| arr += hex.collected_points }.size.should == points.size }
134
+ end
135
+
136
+ context "when using default classes, point grabbing and rejecting empty" do
137
+ let(:points) { 100.times.map{ build(:point) } }
138
+ let(:hex_size) { 0.15 }
139
+ let(:params) { { :grab_points => true, :reject_empty => true } }
140
+ subject { Hexagonly::Hexagon.pack(points, hex_size, params) }
141
+ it { subject.class.should == Array }
142
+ it { subject.inject([]){ |arr, hex| arr += hex.collected_points }.size.should == points.size }
143
+ it { subject.each{ |hex| hex.collected_points.should_not be_empty} }
144
+ end
145
+
146
+ context "when using custom classes" do
147
+ before(:all) do
148
+ class CustomPoint
149
+ include Hexagonly::Point::Methods
150
+ x_y_coord_methods :a, :b
151
+
152
+ attr_accessor :a, :b
153
+ def initialize(*args); set_coords(*args) if args.size == 2; end
154
+ end
155
+
156
+ class CustomHexagon
157
+ include Hexagonly::Hexagon::Methods
158
+
159
+ def initialize(*args); setup_hex(center, size) if args.size == 2; end
160
+ end
161
+ end
162
+ let(:custom_boundries) { [[22, 46], [24, 48]].map{ |x, y| CustomPoint.new(x, y) } }
163
+ let(:hex_size) { 0.15 }
164
+ let(:params) { { :hexagon_class => CustomHexagon, :point_class => CustomPoint } }
165
+ subject{ Hexagonly::Hexagon.pack(custom_boundries, hex_size, params) }
166
+ it { subject.inject(0){ |sum, hex| sum += custom_boundries.inject(0){ |subsum, p| hex.contains?(p) ? subsum += 1 : subsum } }.should == custom_boundries.size }
167
+ it { subject.each{ |hex| hex.class.should == CustomHexagon } }
168
+ it { subject.each{ |hex| hex.hex_center.class.should == CustomPoint } }
169
+ end
170
+
171
+ context "when using custom classes with mixed points and point grabbing" do
172
+ before(:all) do
173
+ class Cheese
174
+ include Hexagonly::Point::Methods
175
+ x_y_coord_methods :a, :b
176
+
177
+ attr_accessor :a, :b
178
+ def initialize(*args); set_coords(*args) if args.size == 2; end
179
+ end
180
+
181
+ class Salami
182
+ include Hexagonly::Point::Methods
183
+ x_y_coord_methods :a, :b
184
+
185
+ attr_accessor :a, :b
186
+ def initialize(*args); set_coords(*args) if args.size == 2; end
187
+ end
188
+
189
+ class Pizza
190
+ include Hexagonly::Hexagon::Methods
191
+
192
+ def initialize(*args); setup_hex(center, size) if args.size == 2; end
193
+ end
194
+ end
195
+ let(:points) { 100.times.map{ [Cheese, Salami].sample.new(generate(:x), generate(:y)) } }
196
+ let(:hex_size) { 0.15 }
197
+ let(:params) { { :hexagon_class => Pizza, :grab_points => true } }
198
+ subject{ Hexagonly::Hexagon.pack(points, hex_size, params) }
199
+ it { subject.class.should == Array }
200
+ it { subject.each{ |hex| hex.class.should == Pizza } }
201
+ it { subject.each{ |hex| hex.collected_points.each{ |p| hex.contains?(p).should == true } } }
202
+ it { subject.inject([]){ |arr, hex| arr += hex.collected_points }.size.should == points.size }
203
+ it { subject.each{ |hex| hex.collected_points.each{ |p| [Cheese, Salami].should include(p.class) } } }
204
+ end
205
+
206
+ end
207
+
208
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hexagonly::Point do
4
+
5
+ describe "#x_coord and #y_coord" do
6
+
7
+ context "when .set_coord_names WAS NOT used" do
8
+
9
+ context "if #x and #y are not defined" do
10
+ before(:all) do
11
+ class TestPoint
12
+ include Hexagonly::Point::Methods
13
+ end
14
+ end
15
+
16
+ subject { TestPoint.new }
17
+ it { expect {subject.x_coord}.to raise_error(NoMethodError) }
18
+ it { expect {subject.y_coord}.to raise_error(NoMethodError) }
19
+ end
20
+
21
+ context "if #x and #y are defined" do
22
+ before(:all) do
23
+ class TestPoint
24
+ include Hexagonly::Point::Methods
25
+ attr_accessor :x, :y
26
+ def initialize(x, y); @x, @y = x, y; end
27
+ end
28
+ end
29
+
30
+ subject { TestPoint.new(1, 2) }
31
+ it { subject.x_coord.should == 1 }
32
+ it { subject.y_coord.should == 2 }
33
+ end
34
+
35
+ end
36
+
37
+ context "when .set_coord_names WAS used" do
38
+
39
+ context "if given coordinate methods are not defined" do
40
+ before(:all) do
41
+ class TestPoint
42
+ include Hexagonly::Point::Methods
43
+ x_y_coord_methods :a, :b
44
+ end
45
+ end
46
+
47
+ subject { TestPoint.new(1, 2) }
48
+ it { expect {subject.x_coord}.to raise_error(NoMethodError) }
49
+ it { expect {subject.y_coord}.to raise_error(NoMethodError) }
50
+ end
51
+
52
+ context "if given coordinate methods are defined" do
53
+ before(:all) do
54
+ class TestPoint
55
+ include Hexagonly::Point::Methods
56
+ x_y_coord_methods :a, :b
57
+ attr_accessor :a, :b
58
+ def initialize(a, b); @a, @b = a, b; end
59
+ end
60
+ end
61
+
62
+ subject { TestPoint.new(1, 2) }
63
+ it { subject.x_coord.should == 1 }
64
+ it { subject.y_coord.should == 2 }
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hexagonly::Polygon do
4
+
5
+ describe "#poly_points" do
6
+
7
+ context "when .poly_points_method WAS NOT used" do
8
+
9
+ context "if #poly_points is not defined" do
10
+ before(:all) do
11
+ class TestPolyWithoutPolyPoints
12
+ include Hexagonly::Polygon::Methods
13
+ end
14
+ end
15
+
16
+ subject { TestPolyWithoutPolyPoints.new }
17
+ it { expect { subject.poly_points }.to raise_error(NoMethodError) }
18
+ end
19
+
20
+ context "if #poly_points is defined" do
21
+ before(:all) do
22
+ class TestPolyWithPolyPoints
23
+ include Hexagonly::Polygon::Methods
24
+ attr_reader :poly_points
25
+ def initialize(points); @poly_points = points; end
26
+ end
27
+ end
28
+
29
+ let(:points) { 5.times.map{ build(:point) } }
30
+ subject { TestPolyWithPolyPoints.new(points).poly_points }
31
+ it { subject.class.should == Array }
32
+ it { should == points }
33
+ end
34
+
35
+ end
36
+
37
+ context "when .poly_points_method WAS used" do
38
+
39
+ context "if given method is defined" do
40
+ before(:all) do
41
+ class TestPolyWithCustomMethod
42
+ include Hexagonly::Polygon::Methods
43
+ poly_points_method :custom_poly_points
44
+ attr_reader :custom_poly_points
45
+ def initialize(points); @custom_poly_points = points; end
46
+ end
47
+ end
48
+
49
+ let(:points) { 5.times.map{ build(:point) } }
50
+ subject { TestPolyWithCustomMethod.new(points) }
51
+ it { subject.poly_points.class.should == Array }
52
+ it { subject.poly_points.should == points }
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ describe "#contains?" do
60
+
61
+ context "when the polygon has less than 3 points" do
62
+ let(:points) { 2.times.map( build(:point)) }
63
+ it { expect { Hexagonly::Polygon.new(nil).contains?(Hexagonly::Point.new(1, 2)) }.to raise_error Exception }
64
+ it { expect { Hexagonly::Polygon.new(points).contains?(Hexagonly::Point.new(1, 2)) }.to raise_error Exception }
65
+ end
66
+
67
+ context "when the polygon has 3 or more points and a simple poly was given" do
68
+ # See Wolfram Alpha: (4, 4)(5, 6)(3, 8)(8, 8)(7, 4) polygon
69
+ let(:simple_poly_points) { [[4, 4], [5, 6], [3, 8], [8, 8], [7, 4]].map{ |p| Hexagonly::Point.new(p[0], p[1]) } }
70
+ subject { Hexagonly::Polygon.new(simple_poly_points) }
71
+ it { subject.contains?(Hexagonly::Point.new(4, 6)).should == false }
72
+ it { subject.contains?(Hexagonly::Point.new(6, 6)).should == true }
73
+ it { subject.contains?(Hexagonly::Point.new(3, 3)).should == false }
74
+ it { subject.contains?(Hexagonly::Point.new(6, 7.99)).should == true }
75
+ it { subject.contains?(Hexagonly::Point.new(8, 6)).should == false }
76
+ it { subject.contains?(Hexagonly::Point.new(-6, -6)).should == false }
77
+ end
78
+
79
+ context "when the polygon has 3 or more points and a messed up poly was given" do
80
+ # See Wolfram Alpha: (4, 6)(8, 7)(7, 3)(5, 9)(8, 9)(4.2, 2)(5, 4) polygon
81
+ let(:messed_up_poly_points) { [[4, 6], [8, 7], [7, 3], [5, 9], [8, 9], [4.2, 2], [5, 4]].map{ |p| Hexagonly::Point.new(p[0], p[1]) } }
82
+ subject { Hexagonly::Polygon.new(messed_up_poly_points) }
83
+ it { subject.contains?(Hexagonly::Point.new(8, 6)).should == false }
84
+ it { subject.contains?(Hexagonly::Point.new(4, 4)).should == false }
85
+ it { subject.contains?(Hexagonly::Point.new(4.3, 7)).should == false }
86
+ it { subject.contains?(Hexagonly::Point.new(7, 8)).should == true }
87
+ it { subject.contains?(Hexagonly::Point.new(5.1, 4)).should == true }
88
+ it { subject.contains?(Hexagonly::Point.new(6, 4.2)).should == false }
89
+ it { subject.contains?(Hexagonly::Point.new(6, 5)).should == false }
90
+ it { subject.contains?(Hexagonly::Point.new(4.9, 3.5)).should == true }
91
+ it { subject.contains?(Hexagonly::Point.new(6, 6.2)).should == false }
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hexagonly::Space do
4
+
5
+ context "when initialized with sufficient points" do
6
+ before(:each) do
7
+ points_arr = [
8
+ [1, 2], [3, 2], [4, 3], [1, 5], [4, 4], [7, 2], [8, 1], [2, 6], [5, 9], [6, 5], [1, 4]
9
+ ]
10
+ @points = points_arr.map{ |point| Hexagonly::Point.new(point[0], point[1]) }
11
+ @space = Hexagonly::Space.new(@points)
12
+ end
13
+
14
+ it "assigns points to a readable attribute" do
15
+ @space.points.should == @points
16
+ end
17
+
18
+ it "computes the boundries of this space" do
19
+ @space.north.should == Hexagonly::Point.new(5, 9)
20
+ @space.west.should == Hexagonly::Point.new(1, 2)
21
+ @space.south.should == Hexagonly::Point.new(8, 1)
22
+ @space.east.should == Hexagonly::Point.new(8, 1)
23
+ end
24
+
25
+ it "computes the center of this space" do
26
+ @space.center.class.should == Hexagonly::Point
27
+ @space.center.should == Hexagonly::Point.new((8 - 1) / 2 + 1, (9 - 1) / 2 + 1)
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hexagonly do
4
+
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'hexagonly'
2
+ require 'factory_girl'
3
+
4
+ FactoryGirl.find_definitions
5
+
6
+ RSpec.configure do |config|
7
+ config.include FactoryGirl::Syntax::Methods
8
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hexagonly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Florin Lipan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: factory_girl
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: redcarpet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Hexagonal tiling in Ruby.
98
+ email:
99
+ - lipanski@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - .ruby-gemset
107
+ - .ruby-version
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - hexagonly.gemspec
113
+ - lib/hexagonly.rb
114
+ - lib/hexagonly/geo_json.rb
115
+ - lib/hexagonly/hexagon.rb
116
+ - lib/hexagonly/point.rb
117
+ - lib/hexagonly/polygon.rb
118
+ - lib/hexagonly/space.rb
119
+ - lib/hexagonly/version.rb
120
+ - localities.rb
121
+ - spec/factories.rb
122
+ - spec/fixtures/localities.csv
123
+ - spec/lib/hexagonly/hexagon_spec.rb
124
+ - spec/lib/hexagonly/point_spec.rb
125
+ - spec/lib/hexagonly/polygon_spec.rb
126
+ - spec/lib/hexagonly/space_spec.rb
127
+ - spec/lib/hexagonly_spec.rb
128
+ - spec/spec_helper.rb
129
+ homepage: ''
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.0.5
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Provides helper classes for performing regular, flat-topped hexagonal tiling
153
+ and other polygon-related operations.
154
+ test_files:
155
+ - spec/factories.rb
156
+ - spec/fixtures/localities.csv
157
+ - spec/lib/hexagonly/hexagon_spec.rb
158
+ - spec/lib/hexagonly/point_spec.rb
159
+ - spec/lib/hexagonly/polygon_spec.rb
160
+ - spec/lib/hexagonly/space_spec.rb
161
+ - spec/lib/hexagonly_spec.rb
162
+ - spec/spec_helper.rb
163
+ has_rdoc: