geometry 6.4 → 6.6

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.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +21 -0
  3. data/Gemfile +3 -0
  4. data/README.markdown +1 -2
  5. data/geometry.gemspec +5 -1
  6. data/lib/geometry/annulus.rb +20 -2
  7. data/lib/geometry/arc.rb +72 -1
  8. data/lib/geometry/edge.rb +21 -4
  9. data/lib/geometry/line.rb +84 -18
  10. data/lib/geometry/obround.rb +1 -2
  11. data/lib/geometry/path.rb +27 -0
  12. data/lib/geometry/point.rb +59 -8
  13. data/lib/geometry/point_iso.rb +12 -2
  14. data/lib/geometry/point_one.rb +44 -34
  15. data/lib/geometry/point_zero.rb +12 -1
  16. data/lib/geometry/polygon.rb +13 -12
  17. data/lib/geometry/polyline.rb +6 -6
  18. data/lib/geometry/rectangle.rb +12 -12
  19. data/lib/geometry/rotation.rb +5 -3
  20. data/lib/geometry/size.rb +1 -3
  21. data/lib/geometry/square.rb +13 -11
  22. data/lib/geometry/transformation/composition.rb +1 -1
  23. data/lib/geometry/transformation.rb +15 -0
  24. data/lib/geometry/triangle.rb +1 -1
  25. data/test/geometry/annulus.rb +12 -0
  26. data/test/geometry/arc.rb +98 -0
  27. data/test/geometry/circle.rb +3 -3
  28. data/test/geometry/edge.rb +16 -2
  29. data/test/geometry/line.rb +73 -0
  30. data/test/geometry/path.rb +16 -0
  31. data/test/geometry/point.rb +78 -2
  32. data/test/geometry/point_iso.rb +31 -21
  33. data/test/geometry/point_one.rb +11 -1
  34. data/test/geometry/point_zero.rb +46 -36
  35. data/test/geometry/polygon.rb +1 -1
  36. data/test/geometry/rectangle.rb +6 -1
  37. data/test/geometry/rotation.rb +1 -1
  38. data/test/geometry/size_one.rb +1 -1
  39. data/test/geometry/size_zero.rb +1 -1
  40. data/test/geometry/square.rb +15 -10
  41. data/test/geometry/transformation.rb +15 -1
  42. data/test/geometry/vector.rb +1 -1
  43. metadata +36 -9
  44. data/.travis.yml +0 -12
@@ -134,6 +134,29 @@ describe Geometry::PointSlopeLine do
134
134
  line2.must_equal subject
135
135
  line3.wont_equal subject
136
136
  end
137
+
138
+ it 'must know how to be horizontal' do
139
+ Geometry::PointSlopeLine.new([1,2],0).horizontal?.must_equal true
140
+ Geometry::PointSlopeLine.new([1,2],1).horizontal?.must_equal false
141
+ end
142
+
143
+ it 'must know how to be vertical' do
144
+ Geometry::PointSlopeLine.new([1,2], Float::INFINITY).vertical?.must_equal true
145
+ Geometry::PointSlopeLine.new([1,2], -Float::INFINITY).vertical?.must_equal true
146
+ Geometry::PointSlopeLine.new([1,2],1).vertical?.must_equal false
147
+ end
148
+
149
+ it 'must have an x-intercept' do
150
+ subject.intercept(:x).must_equal 1
151
+ end
152
+
153
+ it 'must not have an x-intercept for horizontal lines' do
154
+ Geometry::PointSlopeLine.new([1,2], 0).intercept(:x).must_equal nil
155
+ end
156
+
157
+ it 'must have a y-intercept' do
158
+ subject.intercept.must_equal(-1)
159
+ end
137
160
  end
138
161
 
139
162
  describe Geometry::SlopeInterceptLine do
@@ -163,6 +186,29 @@ describe Geometry::SlopeInterceptLine do
163
186
  line2.must_equal subject
164
187
  line3.wont_equal subject
165
188
  end
189
+
190
+ it 'must know how to be horizontal' do
191
+ Geometry::SlopeInterceptLine.new(0, 2).horizontal?.must_equal true
192
+ Geometry::SlopeInterceptLine.new(1, 2).horizontal?.must_equal false
193
+ end
194
+
195
+ it 'must know how to be vertical' do
196
+ Geometry::SlopeInterceptLine.new(Float::INFINITY, 2).vertical?.must_equal true
197
+ Geometry::SlopeInterceptLine.new(-Float::INFINITY, 2).vertical?.must_equal true
198
+ Geometry::SlopeInterceptLine.new(1, 2).vertical?.must_equal false
199
+ end
200
+
201
+ it 'must have an x-intercept' do
202
+ subject.intercept(:x).must_equal(-2/3)
203
+ end
204
+
205
+ it 'must not have an x-intercept for horizontal lines' do
206
+ Geometry::SlopeInterceptLine.new(0, 2).intercept(:x).must_equal nil
207
+ end
208
+
209
+ it 'must have a y-intercept' do
210
+ subject.intercept.must_equal 2
211
+ end
166
212
  end
167
213
 
168
214
  describe Geometry::TwoPointLine do
@@ -192,4 +238,31 @@ describe Geometry::TwoPointLine do
192
238
  line2.must_equal subject
193
239
  line3.wont_equal subject
194
240
  end
241
+
242
+ it 'must know how to be horizontal' do
243
+ Geometry::TwoPointLine.new([1,2],[2,2]).horizontal?.must_equal true
244
+ Geometry::TwoPointLine.new([1,2],[3,4]).horizontal?.must_equal false
245
+ end
246
+
247
+ it 'must know how to be vertical' do
248
+ Geometry::TwoPointLine.new([1,2], [1,3]).vertical?.must_equal true
249
+ Geometry::TwoPointLine.new([1,2], [1,-3]).vertical?.must_equal true
250
+ Geometry::TwoPointLine.new([1,2],[3,4]).vertical?.must_equal false
251
+ end
252
+
253
+ it 'must have an x-intercept' do
254
+ subject.intercept(:x).must_equal(-1)
255
+ end
256
+
257
+ it 'must not have an x-intercept for horizontal lines' do
258
+ Geometry::TwoPointLine.new([1,2],[2,2]).intercept(:x).must_equal nil
259
+ end
260
+
261
+ it 'must have an x-intercept for vertical lines' do
262
+ Geometry::TwoPointLine.new([1,2], [1,3]).intercept(:x).must_equal 1
263
+ end
264
+
265
+ it 'must have a y-intercept' do
266
+ subject.intercept.must_equal 1
267
+ end
195
268
  end
@@ -63,4 +63,20 @@ describe Geometry::Path do
63
63
  path.elements[0].last.must_equal path.elements[1].first
64
64
  end
65
65
  end
66
+
67
+ describe 'attributes' do
68
+ let(:unit_square) { Geometry::Path.new [0,0], [1,0], [1,1], [0,1] }
69
+
70
+ it 'must know the max' do
71
+ unit_square.max.must_equal Point[1,1]
72
+ end
73
+
74
+ it 'must know the min' do
75
+ unit_square.min.must_equal Point[0,0]
76
+ end
77
+
78
+ it 'must know the min and the max' do
79
+ unit_square.minmax.must_equal [Point[0,0], Point[1,1]]
80
+ end
81
+ end
66
82
  end
@@ -2,6 +2,7 @@ require 'minitest/autorun'
2
2
  require 'geometry/point'
3
3
 
4
4
  describe Geometry::Point do
5
+ PointIso = Geometry::PointIso
5
6
  PointOne = Geometry::PointOne
6
7
  PointZero = Geometry::PointZero
7
8
 
@@ -14,6 +15,15 @@ describe Geometry::Point do
14
15
  Point.one(3).must_equal Point[1,1,1]
15
16
  end
16
17
 
18
+ it 'must generate a PointIso' do
19
+ Point.iso(3).must_be_kind_of(PointIso)
20
+ Point.iso(3).value.must_equal 3
21
+ end
22
+
23
+ it 'must generate a Point filled with a given value' do
24
+ Point.iso(3, 2).must_equal Point[3,3]
25
+ end
26
+
17
27
  it "must generate a PointZero" do
18
28
  Point.zero.must_be_instance_of(PointZero)
19
29
  end
@@ -114,7 +124,24 @@ describe Geometry::Point do
114
124
  Point[1,2].dup.must_equal Point[1,2]
115
125
  end
116
126
 
117
- describe 'minmax' do
127
+ it 'must pop' do
128
+ Point[1,2,3,4].pop.must_equal Point[4]
129
+ Point[1,2,3,4].pop(2).must_equal Point[3,4]
130
+ end
131
+
132
+ it 'must push' do
133
+ Point[1,2].push(3,4).must_equal Point[1,2,3,4]
134
+ end
135
+
136
+ it 'must shift' do
137
+ Point[1,2,3,4].shift.must_equal Point[1]
138
+ end
139
+
140
+ it 'must unshift' do
141
+ Point[2,3,4].unshift(1).must_equal Point[1,2,3,4]
142
+ end
143
+
144
+ describe 'minimum' do
118
145
  it 'must have a minimum' do
119
146
  Point[1,2].min.must_equal 1
120
147
  end
@@ -132,6 +159,20 @@ describe Geometry::Point do
132
159
  Point[1,3].min(4,2).must_equal Point[1,2]
133
160
  end
134
161
 
162
+ it 'must minimum with a PointIso' do
163
+ Point[-5,-5,5].min(PointIso.new(-5/2)).must_equal Point[-5,-5,-5/2]
164
+ end
165
+
166
+ it 'must minimum with a PointOne' do
167
+ Point[-5,-5,5].min(Point.one).must_equal Point[-5,-5,1]
168
+ end
169
+
170
+ it 'must minimum with a PointZero' do
171
+ Point[-5,-5,5].min(Point.zero).must_equal Point[-5,-5,0]
172
+ end
173
+ end
174
+
175
+ describe 'maximum' do
135
176
  it 'must have a maximum' do
136
177
  Point[1,2].max.must_equal 2
137
178
  end
@@ -149,6 +190,20 @@ describe Geometry::Point do
149
190
  Point[1,3].max(4,2).must_equal Point[4,3]
150
191
  end
151
192
 
193
+ it 'must maximum with a PointIso' do
194
+ Point[-5,-5,5].max(PointIso.new(-5/2)).must_equal Point[-5/2, -5/2, 5]
195
+ end
196
+
197
+ it 'must maximum with a PointOne' do
198
+ Point[-5,-5,5].max(Point.one).must_equal Point[1, 1, 5]
199
+ end
200
+
201
+ it 'must maximum with a PointZero' do
202
+ Point[-5,-5,5].max(Point.zero).must_equal Point[0, 0, 5]
203
+ end
204
+ end
205
+
206
+ describe 'minmax' do
152
207
  it 'must have a minmax' do
153
208
  Point[1,2].minmax.must_equal [1,2]
154
209
  end
@@ -161,9 +216,21 @@ describe Geometry::Point do
161
216
  Point[1,3].minmax([4,2]).must_equal [Point[1,2], Point[4,3]]
162
217
  end
163
218
 
164
- it 'must maximum with multiple arguments' do
219
+ it 'must minmax with multiple arguments' do
165
220
  Point[1,3].minmax(4,2).must_equal [Point[1,2], Point[4,3]]
166
221
  end
222
+
223
+ it 'must minmax with a PointIso' do
224
+ Point[-5,-5,5].minmax(PointIso.new(-5/2)).must_equal [Point[-5,-5,-5/2], Point[-5/2, -5/2, 5]]
225
+ end
226
+
227
+ it 'must minmax with a PointOne' do
228
+ Point[-5,-5,5].minmax(Point.one).must_equal [Point[-5,-5,1], Point[1, 1, 5]]
229
+ end
230
+
231
+ it 'must minmax with a PointZero' do
232
+ Point[-5,-5,5].minmax(Point.zero).must_equal [Point[-5,-5,0], Point[0, 0, 5]]
233
+ end
167
234
  end
168
235
 
169
236
  describe "arithmetic" do
@@ -254,6 +321,15 @@ describe Geometry::Point do
254
321
  end
255
322
  end
256
323
 
324
+ describe 'attributes' do
325
+ it 'must have a quadrant' do
326
+ Point[1,1].quadrant.must_equal 1
327
+ Point[-1,1].quadrant.must_equal 2
328
+ Point[-1,-1].quadrant.must_equal 3
329
+ Point[1,-1].quadrant.must_equal 4
330
+ end
331
+ end
332
+
257
333
  describe "coercion" do
258
334
  subject { Point[1,2] }
259
335
 
@@ -2,9 +2,19 @@ require 'minitest/autorun'
2
2
  require 'geometry/point_iso'
3
3
 
4
4
  describe Geometry::PointIso do
5
- let(:value) { 5 }
5
+ let(:iso_value) { 5 }
6
6
  subject { Geometry::PointIso.new(5) }
7
7
 
8
+ it 'must pop' do
9
+ subject.pop.must_equal Point[5]
10
+ subject.pop(2).must_equal Point[5, 5]
11
+ end
12
+
13
+ it 'must shift' do
14
+ subject.shift.must_equal Point[5]
15
+ subject.shift(2).must_equal Point[5, 5]
16
+ end
17
+
8
18
  describe 'minmax' do
9
19
  it 'must have a minimum' do
10
20
  subject.min.must_equal 5
@@ -73,30 +83,30 @@ describe Geometry::PointIso do
73
83
  end
74
84
 
75
85
  it 'must have +@' do
76
- (+subject).must_be :eql?, value
86
+ (+subject).must_be :eql?, iso_value
77
87
  (+subject).must_be_instance_of(Geometry::PointIso)
78
88
  end
79
89
 
80
90
  it 'must have unary negation' do
81
- (-subject).must_be :eql?, -value
91
+ (-subject).must_be :eql?, -iso_value
82
92
  (-subject).must_be_instance_of(Geometry::PointIso)
83
93
  end
84
94
 
85
95
  describe 'Accessors' do
86
96
  it 'must return 1 for array access' do
87
- subject[3].must_equal value
97
+ subject[3].must_equal iso_value
88
98
  end
89
99
 
90
100
  it 'must return 1 for named element access' do
91
- subject.x.must_equal value
92
- subject.y.must_equal value
93
- subject.z.must_equal value
101
+ subject.x.must_equal iso_value
102
+ subject.y.must_equal iso_value
103
+ subject.z.must_equal iso_value
94
104
  end
95
105
  end
96
106
 
97
107
  it 'must add a number' do
98
- (subject + 3).must_equal (value + 3)
99
- (3 + subject).must_equal (3 + value)
108
+ (subject + 3).must_equal (iso_value + 3)
109
+ (3 + subject).must_equal (3 + iso_value)
100
110
  end
101
111
 
102
112
  it 'return a Point when adding two Points' do
@@ -105,24 +115,24 @@ describe Geometry::PointIso do
105
115
  end
106
116
 
107
117
  it 'must return an Array when adding an array' do
108
- (subject + [5,6]).must_equal [value+5, value+6]
118
+ (subject + [5,6]).must_equal [iso_value+5, iso_value+6]
109
119
  # ([5,6] + subject).must_equal [10, 11]
110
120
  end
111
121
 
112
122
  it 'must return a Point when adding a Size' do
113
123
  (subject + Size[5,6]).must_be_instance_of(Point)
114
- (subject + Size[5,6]).must_equal Point[value+5, value+6]
124
+ (subject + Size[5,6]).must_equal Point[iso_value+5, iso_value+6]
115
125
  end
116
126
 
117
127
  describe 'when subtracting' do
118
128
  it 'must subtract a number' do
119
- (subject - 3).must_equal (value - 3)
120
- (3 - subject).must_equal -2
129
+ (subject - 3).must_equal (iso_value - 3)
130
+ (3 - subject).must_equal(-2)
121
131
  end
122
132
 
123
133
  it 'return a Point when subtracting two Points' do
124
- (subject - right).must_equal Point[value - right.x, value - right.y]
125
- (left - subject).must_equal Point[left.x - value, left.y - value]
134
+ (subject - right).must_equal Point[iso_value - right.x, iso_value - right.y]
135
+ (left - subject).must_equal Point[left.x - iso_value, left.y - iso_value]
126
136
  end
127
137
 
128
138
  it 'must return a Point when subtracting an array' do
@@ -221,15 +231,15 @@ describe Geometry::PointIso do
221
231
  end
222
232
 
223
233
  it 'must be equal to a Point of subjects' do
224
- subject.must_be :==, Point[value, value]
225
- subject.must_be :eql?, Point[value, value]
226
- subject.must_be :===, Point[value, value]
227
- Point[value, value].must_equal subject
228
- subject.must_equal Point[value, value]
234
+ subject.must_be :==, Point[iso_value, iso_value]
235
+ subject.must_be :eql?, Point[iso_value, iso_value]
236
+ subject.must_be :===, Point[iso_value, iso_value]
237
+ Point[iso_value, iso_value].must_equal subject
238
+ subject.must_equal Point[iso_value, iso_value]
229
239
  end
230
240
 
231
241
  it 'must be equal to an Vector of the same value' do
232
- subject.must_be :eql?, Vector[value, value]
242
+ subject.must_be :eql?, Vector[iso_value, iso_value]
233
243
  Vector[5, 5].must_equal subject
234
244
  end
235
245
 
@@ -5,6 +5,16 @@ describe Geometry::PointOne do
5
5
  subject { Geometry::PointOne.new }
6
6
  let(:one) { Geometry::PointOne.new }
7
7
 
8
+ it 'must pop' do
9
+ subject.pop.must_equal Point[1]
10
+ subject.pop(2).must_equal Point[1, 1]
11
+ end
12
+
13
+ it 'must shift' do
14
+ subject.shift.must_equal Point[1]
15
+ subject.shift(2).must_equal Point[1, 1]
16
+ end
17
+
8
18
  describe 'minmax' do
9
19
  it 'must have a minimum' do
10
20
  subject.min.must_equal 1
@@ -116,7 +126,7 @@ describe Geometry::PointOne do
116
126
 
117
127
  describe 'when subtracting' do
118
128
  it 'must subtract a number' do
119
- (one - 3).must_equal -2
129
+ (one - 3).must_equal(-2)
120
130
  (3 - one).must_equal 2
121
131
  end
122
132
 
@@ -5,55 +5,65 @@ describe Geometry::PointZero do
5
5
  subject { Geometry::PointZero.new }
6
6
  let(:zero) { Geometry::PointZero.new }
7
7
 
8
- describe 'minmax' do
9
- it 'must have a minimum' do
10
- subject.min.must_equal 0
8
+ it 'must pop' do
9
+ subject.pop.must_equal Point[0]
10
+ subject.pop(2).must_equal Point[0, 0]
11
11
  end
12
12
 
13
- it 'must minimum with another Point' do
14
- subject.min(Point[-1,7]).must_equal Point[-1,0]
13
+ it 'must shift' do
14
+ subject.shift.must_equal Point[0]
15
+ subject.shift(2).must_equal Point[0, 0]
15
16
  end
16
17
 
17
- it 'must minimum with an Array' do
18
- subject.min([-1,7]).must_equal Point[-1,0]
19
- end
18
+ describe 'minmax' do
19
+ it 'must have a minimum' do
20
+ subject.min.must_equal 0
21
+ end
20
22
 
21
- it 'must minimum with a multiple arguments' do
22
- subject.min(-1,7).must_equal Point[-1,0]
23
- end
23
+ it 'must minimum with another Point' do
24
+ subject.min(Point[-1,7]).must_equal Point[-1,0]
25
+ end
24
26
 
25
- it 'must have a maximum' do
26
- subject.max.must_equal 0
27
- end
27
+ it 'must minimum with an Array' do
28
+ subject.min([-1,7]).must_equal Point[-1,0]
29
+ end
28
30
 
29
- it 'must maximum with another Point' do
30
- subject.max(Point[7,-1]).must_equal Point[7,0]
31
- end
31
+ it 'must minimum with a multiple arguments' do
32
+ subject.min(-1,7).must_equal Point[-1,0]
33
+ end
32
34
 
33
- it 'must maximum with an Array' do
34
- subject.max([7,-1]).must_equal Point[7,0]
35
- end
35
+ it 'must have a maximum' do
36
+ subject.max.must_equal 0
37
+ end
36
38
 
37
- it 'must maximum with multiple arguments' do
38
- subject.max(7,-1).must_equal Point[7,0]
39
- end
39
+ it 'must maximum with another Point' do
40
+ subject.max(Point[7,-1]).must_equal Point[7,0]
41
+ end
40
42
 
41
- it 'must have a minmax' do
42
- subject.minmax.must_equal [0, 0]
43
- end
43
+ it 'must maximum with an Array' do
44
+ subject.max([7,-1]).must_equal Point[7,0]
45
+ end
44
46
 
45
- it 'must minmax with another Point' do
46
- subject.minmax(Point[7,-1]).must_equal [Point[0,-1], Point[7,0]]
47
- end
47
+ it 'must maximum with multiple arguments' do
48
+ subject.max(7,-1).must_equal Point[7,0]
49
+ end
48
50
 
49
- it 'must minmax with an Array' do
50
- subject.minmax([7,-1]).must_equal [Point[0,-1], Point[7,0]]
51
- end
51
+ it 'must have a minmax' do
52
+ subject.minmax.must_equal [0, 0]
53
+ end
52
54
 
53
- it 'must maximum with multiple arguments' do
54
- subject.minmax(7,-1).must_equal [Point[0,-1], Point[7,0]]
55
+ it 'must minmax with another Point' do
56
+ subject.minmax(Point[7,-1]).must_equal [Point[0,-1], Point[7,0]]
57
+ end
58
+
59
+ it 'must minmax with an Array' do
60
+ subject.minmax([7,-1]).must_equal [Point[0,-1], Point[7,0]]
61
+ end
62
+
63
+ it 'must maximum with multiple arguments' do
64
+ subject.minmax(7,-1).must_equal [Point[0,-1], Point[7,0]]
65
+ end
55
66
  end
56
- end
57
67
 
58
68
  describe "arithmetic" do
59
69
  let(:left) { Point[1,2] }
@@ -117,7 +127,7 @@ end
117
127
 
118
128
  describe "when subtracting" do
119
129
  it "must return a number" do
120
- (zero - 3).must_equal -3
130
+ (zero - 3).must_equal(-3)
121
131
  (3 - zero).must_equal 3
122
132
  end
123
133
 
@@ -118,7 +118,7 @@ describe Geometry::Polygon do
118
118
 
119
119
  describe "spaceship" do
120
120
  it "with a Point" do
121
- (unit_square <=> Point[2,0]).must_equal -1
121
+ (unit_square <=> Point[2,0]).must_equal(-1)
122
122
  (unit_square <=> Point[1,0]).must_equal 0
123
123
  (unit_square <=> Point[0.5,0.5]).must_equal 1
124
124
  end
@@ -133,10 +133,11 @@ describe Geometry::Rectangle do
133
133
  edges.each {|edge| assert_kind_of(Geometry::Edge, edge)}
134
134
  end
135
135
 
136
- it "have a points property that returns 4 points" do
136
+ it "have a points property that returns 4 points in clockwise order starting from the lower-left" do
137
137
  points = rectangle.points
138
138
  assert_equal(4, points.size)
139
139
  points.each {|point| assert_kind_of(Geometry::Point, point)}
140
+ points.must_equal [Point[1,2], Point[1,4], Point[3,4], Point[3,2]]
140
141
  end
141
142
 
142
143
  it "must have a bounds property that returns a Rectangle" do
@@ -154,5 +155,9 @@ describe Geometry::Rectangle do
154
155
  it "must have a min property that returns the lower left corner of the bounding rectangle" do
155
156
  subject.min.must_equal Point[1,2]
156
157
  end
158
+
159
+ it 'must have a path property that returns a closed Path' do
160
+ rectangle.path.must_equal Geometry::Path.new([1,2], [1,4], [3,4], [3,2], [1,2])
161
+ end
157
162
  end
158
163
  end
@@ -13,7 +13,7 @@ describe Geometry::Rotation do
13
13
  rotation.angle.must_equal Math::PI/2
14
14
  rotation.x.x.must_be_close_to 0
15
15
  rotation.x.y.must_be_close_to 1
16
- rotation.y.x.must_be_close_to -1
16
+ rotation.y.x.must_be_close_to(-1)
17
17
  rotation.y.y.must_be_close_to 0
18
18
  end
19
19
 
@@ -37,7 +37,7 @@ describe Geometry::SizeOne do
37
37
 
38
38
  describe 'when subtracting' do
39
39
  it 'must subtract a number' do
40
- (one - 3).must_equal -2
40
+ (one - 3).must_equal(-2)
41
41
  (3 - one).must_equal 2
42
42
  end
43
43
 
@@ -39,7 +39,7 @@ describe Geometry::SizeZero do
39
39
 
40
40
  describe "when subtracting" do
41
41
  it "must return a number" do
42
- (zero - 3).must_equal -3
42
+ (zero - 3).must_equal(-3)
43
43
  (3 - zero).must_equal 3
44
44
  end
45
45
 
@@ -9,7 +9,7 @@ describe Geometry::Square do
9
9
  square = Square.new from:[1,2], to:[3,4]
10
10
  square.must_be_kind_of Geometry::Square
11
11
  end
12
-
12
+
13
13
  it "must reorder swapped points when constructed from two Points" do
14
14
  square = Geometry::Square.new from:[3,4], to:[1,2]
15
15
  square.must_be_kind_of Geometry::Square
@@ -57,7 +57,7 @@ describe Geometry::Square do
57
57
  -> { Square.new size:[1,2] }.must_raise Geometry::NotSquareError
58
58
  end
59
59
  end
60
-
60
+
61
61
  describe "properties" do
62
62
  subject { Square.new from:[2,3], to:[3,4] }
63
63
 
@@ -66,7 +66,7 @@ describe Geometry::Square do
66
66
  end
67
67
 
68
68
  it 'must have edges' do
69
- subject.edges.must_equal [Edge([2,3], [3,3]), Edge.new([3,3], [3,4]), Edge.new([3,4], [2,4]), Edge.new([2,4], [2,3])]
69
+ subject.edges.must_equal [Edge([2,3], [2,4]), Edge.new([2,4], [3,4]), Edge.new([3,4], [3,3]), Edge.new([3,3], [2,3])]
70
70
  end
71
71
 
72
72
  it "must have an origin accessor" do
@@ -85,8 +85,13 @@ describe Geometry::Square do
85
85
  subject.min.must_equal Point[2, 3]
86
86
  end
87
87
 
88
- it 'must have points' do
89
- subject.points.must_equal [Point[2,3], Point[3,3], Point[3,4], Point[2,4]]
88
+ it 'have a points property that returns 4 points in clockwise order starting from the lower-left' do
89
+ subject.points.must_equal [Point[2,3], Point[2,4], Point[3,4], Point[3,3]]
90
+ end
91
+
92
+ it 'must have a path property that returns a closed Path' do
93
+ square = Geometry::Square.new origin:[0,0], size:5
94
+ square.path.must_equal Geometry::Path.new([0,0], [0,5], [5,5], [5,0], [0,0])
90
95
  end
91
96
  end
92
97
  end
@@ -102,13 +107,13 @@ describe Geometry::CenteredSquare do
102
107
 
103
108
  describe "properties" do
104
109
  let(:square) { Geometry::CenteredSquare.new [2,3], 4 }
105
-
110
+
106
111
  it "must have a center property" do
107
112
  square.center.must_equal Point[2,3]
108
113
  end
109
114
 
110
- it "must have a points property" do
111
- square.points.must_equal [Point[0,1], Point[4,1], Point[4,5], Point[0,5]]
115
+ it 'have a points property that returns 4 points in clockwise order starting from the lower-left' do
116
+ square.points.must_equal [Point[0,1], Point[0,5], Point[4,5], Point[4,1]]
112
117
  end
113
118
 
114
119
  it "must have a height property" do
@@ -149,8 +154,8 @@ describe Geometry::SizedSquare do
149
154
  square.center.must_equal Point[4,5]
150
155
  end
151
156
 
152
- it "must have a points property" do
153
- square.points.must_equal [Point[2,3], Point[6,3], Point[6,7], Point[2,7]]
157
+ it 'have a points property that returns 4 points in clockwise order starting from the lower-left' do
158
+ square.points.must_equal [Point[2,3], Point[2,7], Point[6,7], Point[6,3]]
154
159
  end
155
160
 
156
161
  it "must have a height property" do
@@ -78,12 +78,26 @@ describe Geometry::Transformation do
78
78
  rotation.angle.must_equal Math::PI/2
79
79
  rotation.x.x.must_be_close_to 0
80
80
  rotation.x.y.must_be_close_to 1
81
- rotation.y.x.must_be_close_to -1
81
+ rotation.y.x.must_be_close_to(-1)
82
82
  rotation.y.y.must_be_close_to 0
83
83
  end
84
84
  end
85
85
  end
86
86
 
87
+ describe 'convenience constructors' do
88
+ it 'must create a translation from coordinates' do
89
+ Geometry.translation(1, 2, 3).translation.must_equal Point[1,2,3]
90
+ end
91
+
92
+ it 'must create a translation from an Array' do
93
+ Geometry.translation([1, 2, 3]).translation.must_equal Point[1,2,3]
94
+ end
95
+
96
+ it 'must create a translation from a Point' do
97
+ Geometry.translation(Point[1, 2, 3]).translation.must_equal Point[1,2,3]
98
+ end
99
+ end
100
+
87
101
  it 'must translate with a Point' do
88
102
  Transformation.new(translate:[1,2]).translate(Point[3,4]).translation.must_equal Point[4,6]
89
103
  end
@@ -15,7 +15,7 @@ describe Vector do
15
15
  end
16
16
 
17
17
  it "must cross product" do
18
- left.cross(right).must_equal -2
18
+ left.cross(right).must_equal(-2)
19
19
  Vector[1,2,3].cross(Vector[3,4,5]).must_equal Vector[-2, 4, -2]
20
20
  (Vector[1,2,3] ** Vector[3,4,5]).must_equal Vector[-2, 4, -2]
21
21
  end