gosling 2.0.1 → 2.1.0
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.
- checksums.yaml +4 -4
- data/lib/gosling/collision.rb +56 -1
- data/lib/gosling/polygon.rb +22 -4
- data/lib/gosling/transformable.rb +19 -59
- data/lib/gosling/version.rb +1 -1
- data/spec/collision_spec.rb +604 -331
- data/spec/polygon_spec.rb +57 -12
- data/spec/transformable_spec.rb +6 -0
- metadata +2 -2
data/spec/collision_spec.rb
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
|
+
def angle_to_vector(angle)
|
4
|
+
Snow::Vec3[Math.sin(angle).round(12), Math.cos(angle).round(12), 0]
|
5
|
+
end
|
6
|
+
|
7
|
+
def clean_actor(actor)
|
8
|
+
actor.x = 0
|
9
|
+
actor.y = 0
|
10
|
+
actor.scale_x = 1
|
11
|
+
actor.scale_y = 1
|
12
|
+
actor.rotation = 0
|
13
|
+
end
|
14
|
+
|
3
15
|
def clean_shape(shape)
|
4
|
-
shape
|
5
|
-
shape.y = 0
|
16
|
+
clean_actor(shape)
|
6
17
|
shape.center_x = 0
|
7
18
|
shape.center_y = 0
|
8
|
-
shape.scale_x = 1
|
9
|
-
shape.scale_y = 1
|
10
|
-
shape.rotation = 0
|
11
19
|
end
|
12
20
|
|
13
21
|
def clean_rect(rect)
|
14
|
-
rect
|
15
|
-
rect.y = 0
|
22
|
+
clean_actor(rect)
|
16
23
|
rect.center_x = 5
|
17
24
|
rect.center_y = 5
|
18
|
-
rect.scale_x = 1
|
19
|
-
rect.scale_y = 1
|
20
|
-
rect.rotation = 0
|
21
25
|
end
|
22
26
|
|
23
27
|
def clean_sprite(sprite)
|
24
|
-
sprite
|
25
|
-
sprite.y = 0
|
28
|
+
clean_actor(sprite)
|
26
29
|
sprite.center_x = 8
|
27
30
|
sprite.center_y = 8
|
28
|
-
sprite.scale_x = 1
|
29
|
-
sprite.scale_y = 1
|
30
|
-
sprite.rotation = 0
|
31
31
|
end
|
32
32
|
|
33
33
|
def create_inheritance_chain(ancestry)
|
@@ -42,7 +42,11 @@ def break_inheritance_chain(ancestry)
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
ANGLE_COUNT = 8 * 4
|
46
|
+
|
45
47
|
describe Gosling::Collision do
|
48
|
+
FLOAT_TOLERANCE = 0.000001
|
49
|
+
|
46
50
|
before(:all) do
|
47
51
|
@window = Gosu::Window.new(640, 480, false)
|
48
52
|
@local_path = File.dirname(__FILE__)
|
@@ -109,305 +113,459 @@ describe Gosling::Collision do
|
|
109
113
|
@translate_actor = Gosling::Actor.new(@window)
|
110
114
|
@translate_actor.x = 128
|
111
115
|
@translate_actor.y = 256
|
116
|
+
|
117
|
+
@angles = (0...ANGLE_COUNT).map { |i| Math::PI * 2 * i / ANGLE_COUNT }
|
112
118
|
end
|
113
119
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
+
context 'any actor vs. itself' do
|
121
|
+
it 'never collides' do
|
122
|
+
[@actor1, @circle1, @polygon1, @rect1, @sprite1].each do |actor|
|
123
|
+
expect(Gosling::Collision.test(actor, actor)).to be false
|
124
|
+
result = Gosling::Collision.get_collision_info(actor, actor)
|
125
|
+
expect(result[:colliding]).to be false
|
126
|
+
expect(result[:overlap]).to be nil
|
127
|
+
expect(result[:penetration]).to be nil
|
120
128
|
end
|
121
129
|
end
|
130
|
+
end
|
122
131
|
|
123
|
-
|
124
|
-
|
125
|
-
|
132
|
+
context 'actor vs. anything' do
|
133
|
+
it 'never collides' do
|
134
|
+
pairs = [
|
135
|
+
[@actor1, @actor2],
|
136
|
+
[@actor1, @circle1],
|
137
|
+
[@actor1, @polygon1],
|
138
|
+
[@actor1, @rect1],
|
139
|
+
[@actor1, @sprite1]
|
140
|
+
]
|
141
|
+
pairs.each do |pair|
|
142
|
+
expect(Gosling::Collision.test(*pair)).to be false
|
143
|
+
result = Gosling::Collision.get_collision_info(*pair)
|
144
|
+
expect(result[:colliding]).to be false
|
145
|
+
expect(result[:overlap]).to be nil
|
146
|
+
expect(result[:penetration]).to be nil
|
126
147
|
end
|
127
148
|
end
|
149
|
+
end
|
128
150
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
151
|
+
context 'circle vs. circle' do
|
152
|
+
before do
|
153
|
+
clean_shape(@circle1)
|
154
|
+
@circle1.x = 0
|
155
|
+
@circle1.y = 0
|
156
|
+
|
157
|
+
clean_shape(@circle2)
|
158
|
+
@circle2.x = 5
|
159
|
+
@circle2.y = 5
|
133
160
|
end
|
134
161
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
162
|
+
it 'collides if the shapes are close enough' do
|
163
|
+
expect(Gosling::Collision.test(@circle1, @circle2)).to be true
|
164
|
+
result = Gosling::Collision.get_collision_info(@circle1, @circle2)
|
165
|
+
expect(result[:colliding]).to be true
|
166
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(10 - Math.sqrt(50))
|
167
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
|
139
168
|
end
|
140
169
|
|
141
|
-
|
142
|
-
|
143
|
-
|
170
|
+
it 'returns a vector that separates the shapes' do
|
171
|
+
@angles.each do |r|
|
172
|
+
@circle1.x = 5 + Math.sin(r) * 5
|
173
|
+
@circle1.y = 5 + Math.cos(r) * 5
|
174
|
+
@circle2.x = 5
|
175
|
+
@circle2.y = 5
|
176
|
+
|
177
|
+
result = Gosling::Collision.get_collision_info(@circle1, @circle2)
|
178
|
+
@circle2.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
179
|
+
expect(Gosling::Collision.test(@circle1, @circle2)).to be false
|
144
180
|
end
|
145
181
|
end
|
146
182
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
183
|
+
it 'always returns the vector that displaces shape b away from shape a' do
|
184
|
+
@circle1.y = 10
|
185
|
+
result = Gosling::Collision.get_collision_info(@circle1, @circle2)
|
186
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, -1, 0].normalize * result[:overlap])
|
151
187
|
end
|
152
188
|
|
153
|
-
|
154
|
-
|
155
|
-
clean_shape(@circle1)
|
156
|
-
@circle1.x = 0
|
157
|
-
@circle1.y = 0
|
189
|
+
it 'does not collide if the shapes are far apart' do
|
190
|
+
@circle2.x = 10
|
158
191
|
|
159
|
-
|
160
|
-
@circle2.x = 5
|
161
|
-
@circle2.y = 5
|
192
|
+
expect(Gosling::Collision.test(@circle1, @circle2)).to be false
|
162
193
|
|
163
|
-
|
164
|
-
|
194
|
+
result = Gosling::Collision.get_collision_info(@circle1, @circle2)
|
195
|
+
expect(result[:colliding]).to be false
|
196
|
+
expect(result[:overlap]).to be nil
|
197
|
+
expect(result[:penetration]).to be nil
|
198
|
+
end
|
199
|
+
end
|
165
200
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
201
|
+
context 'circle vs. polygon' do
|
202
|
+
before do
|
203
|
+
clean_shape(@circle1)
|
204
|
+
@circle1.x = 0
|
205
|
+
@circle1.y = 0
|
170
206
|
|
171
|
-
|
172
|
-
|
173
|
-
|
207
|
+
clean_shape(@polygon1)
|
208
|
+
@polygon1.x = 5
|
209
|
+
@polygon1.y = 5
|
210
|
+
end
|
174
211
|
|
175
|
-
|
176
|
-
|
212
|
+
it 'collides if the shapes are close enough' do
|
213
|
+
expect(Gosling::Collision.test(@circle1, @polygon1)).to be true
|
214
|
+
result = Gosling::Collision.get_collision_info(@circle1, @polygon1)
|
215
|
+
expect(result[:colliding]).to be true
|
216
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
|
217
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
|
177
218
|
end
|
178
219
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
220
|
+
it 'returns a vector that separates the shapes' do
|
221
|
+
result = Gosling::Collision.get_collision_info(@circle1, @polygon1)
|
222
|
+
@polygon1.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
223
|
+
expect(Gosling::Collision.test(@circle1, @polygon1)).to be false
|
224
|
+
end
|
184
225
|
|
185
|
-
|
186
|
-
|
187
|
-
|
226
|
+
it 'does not collide if the shapes are far apart' do
|
227
|
+
@polygon1.x = 10
|
228
|
+
@polygon1.y = 10
|
188
229
|
|
189
|
-
|
190
|
-
|
230
|
+
expect(Gosling::Collision.test(@circle1, @polygon1)).to be false
|
231
|
+
result = Gosling::Collision.get_collision_info(@circle1, @polygon1)
|
232
|
+
expect(result[:colliding]).to be false
|
233
|
+
expect(result[:overlap]).to be nil
|
234
|
+
expect(result[:penetration]).to be nil
|
235
|
+
end
|
236
|
+
end
|
191
237
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
238
|
+
context 'circle vs. rect' do
|
239
|
+
before do
|
240
|
+
clean_shape(@circle1)
|
241
|
+
@circle1.x = 0
|
242
|
+
@circle1.y = 0
|
196
243
|
|
197
|
-
|
198
|
-
|
199
|
-
|
244
|
+
clean_rect(@rect1)
|
245
|
+
@rect1.x = 5
|
246
|
+
@rect1.y = 5
|
247
|
+
end
|
200
248
|
|
201
|
-
|
202
|
-
|
249
|
+
it 'collides if the shapes are close enough' do
|
250
|
+
expect(Gosling::Collision.test(@circle1, @rect1)).to be true
|
251
|
+
result = Gosling::Collision.get_collision_info(@circle1, @rect1)
|
252
|
+
expect(result[:colliding]).to be true
|
253
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
|
254
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
|
203
255
|
end
|
204
256
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
257
|
+
it 'returns a vector that separates the shapes' do
|
258
|
+
result = Gosling::Collision.get_collision_info(@circle1, @rect1)
|
259
|
+
@rect1.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
260
|
+
expect(Gosling::Collision.test(@circle1, @rect1)).to be false
|
261
|
+
end
|
210
262
|
|
211
|
-
|
212
|
-
|
213
|
-
|
263
|
+
it 'does not collide if the shapes are far apart' do
|
264
|
+
@rect1.x = 10
|
265
|
+
@rect1.y = 10
|
214
266
|
|
215
|
-
|
216
|
-
|
267
|
+
expect(Gosling::Collision.test(@circle1, @rect1)).to be false
|
268
|
+
result = Gosling::Collision.get_collision_info(@circle1, @rect1)
|
269
|
+
expect(result[:colliding]).to be false
|
270
|
+
expect(result[:overlap]).to be nil
|
271
|
+
expect(result[:penetration]).to be nil
|
272
|
+
end
|
273
|
+
end
|
217
274
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
275
|
+
context 'circle vs. sprite' do
|
276
|
+
before do
|
277
|
+
clean_shape(@circle1)
|
278
|
+
@circle1.x = 0
|
279
|
+
@circle1.y = 0
|
222
280
|
|
223
|
-
|
224
|
-
|
225
|
-
|
281
|
+
clean_sprite(@sprite1)
|
282
|
+
@sprite1.x = 8
|
283
|
+
@sprite1.y = 8
|
284
|
+
end
|
226
285
|
|
227
|
-
|
228
|
-
|
286
|
+
it 'collides if the shapes are close enough' do
|
287
|
+
expect(Gosling::Collision.test(@circle1, @sprite1)).to be true
|
288
|
+
result = Gosling::Collision.get_collision_info(@circle1, @sprite1)
|
289
|
+
expect(result[:colliding]).to be true
|
290
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
|
291
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
|
229
292
|
end
|
230
293
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
294
|
+
it 'returns a vector that separates the shapes' do
|
295
|
+
result = Gosling::Collision.get_collision_info(@circle1, @sprite1)
|
296
|
+
@sprite1.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
297
|
+
expect(Gosling::Collision.test(@circle1, @sprite1)).to be false
|
298
|
+
end
|
236
299
|
|
237
|
-
|
238
|
-
|
239
|
-
|
300
|
+
it 'does not collide if the shapes are far apart' do
|
301
|
+
@sprite1.x = 16
|
302
|
+
@sprite1.y = 16
|
240
303
|
|
241
|
-
|
242
|
-
|
304
|
+
expect(Gosling::Collision.test(@circle1, @sprite1)).to be false
|
305
|
+
result = Gosling::Collision.get_collision_info(@circle1, @sprite1)
|
306
|
+
expect(result[:colliding]).to be false
|
307
|
+
expect(result[:overlap]).to be nil
|
308
|
+
expect(result[:penetration]).to be nil
|
309
|
+
end
|
310
|
+
end
|
243
311
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
312
|
+
context 'polygon vs. polygon' do
|
313
|
+
before do
|
314
|
+
clean_shape(@polygon1)
|
315
|
+
@polygon1.x = 0
|
316
|
+
@polygon1.y = 0
|
248
317
|
|
249
|
-
|
250
|
-
|
251
|
-
|
318
|
+
clean_shape(@polygon2)
|
319
|
+
@polygon2.x = 0
|
320
|
+
@polygon2.y = 5
|
321
|
+
end
|
252
322
|
|
253
|
-
|
254
|
-
|
323
|
+
it 'collides if the shapes are close enough' do
|
324
|
+
expect(Gosling::Collision.test(@polygon1, @polygon2)).to be true
|
325
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
|
326
|
+
expect(result[:colliding]).to be true
|
327
|
+
axis = Snow::Vec2[-10, -5].normalize
|
328
|
+
a = Snow::Vec2[0, 0].dot_product(axis)
|
329
|
+
b = Snow::Vec2[0, 5].dot_product(axis)
|
330
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(a - b)
|
331
|
+
expect(result[:penetration]).to eq(Snow::Vec3[2, 1, 0].normalize * result[:overlap])
|
255
332
|
end
|
256
333
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
@polygon1.x = 0
|
261
|
-
@polygon1.y = 0
|
334
|
+
it 'returns a vector that separates the shapes' do
|
335
|
+
@polygon1.x = 0
|
336
|
+
@polygon1.y = 0
|
262
337
|
|
263
|
-
|
338
|
+
@angles.each do |r|
|
264
339
|
@polygon2.x = 0
|
265
340
|
@polygon2.y = 5
|
266
341
|
|
267
|
-
|
342
|
+
@polygon1.rotation = r
|
343
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
|
344
|
+
@polygon2.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
345
|
+
expect(Gosling::Collision.test(@polygon1, @polygon2)).to be false
|
346
|
+
@polygon1.rotation = 0
|
347
|
+
|
348
|
+
@polygon2.x = Math.sin(r)
|
349
|
+
@polygon2.y = Math.cos(r)
|
350
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
|
351
|
+
@polygon2.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
352
|
+
expect(Gosling::Collision.test(@polygon1, @polygon2)).to be false
|
268
353
|
end
|
354
|
+
end
|
269
355
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
356
|
+
it 'always returns the vector that displaces shape b away from shape a' do
|
357
|
+
@polygon1.y = 5
|
358
|
+
@polygon2.y = 0
|
359
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
|
360
|
+
expect(result[:penetration]).to eq(Snow::Vec3[0, -1, 0].normalize * result[:overlap])
|
361
|
+
end
|
274
362
|
|
275
|
-
|
276
|
-
|
277
|
-
@polygon2.y = 5
|
363
|
+
it 'does not collide if the shapes are far apart' do
|
364
|
+
@polygon2.x = 5
|
278
365
|
|
279
|
-
|
280
|
-
|
366
|
+
expect(Gosling::Collision.test(@polygon1, @polygon2)).to be false
|
367
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
|
368
|
+
expect(result[:colliding]).to be false
|
369
|
+
expect(result[:overlap]).to be nil
|
370
|
+
expect(result[:penetration]).to be nil
|
281
371
|
end
|
372
|
+
end
|
282
373
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
374
|
+
context 'polygon vs. rect' do
|
375
|
+
before do
|
376
|
+
clean_shape(@polygon1)
|
377
|
+
@polygon1.x = 0
|
378
|
+
@polygon1.y = 0
|
288
379
|
|
289
|
-
|
290
|
-
|
291
|
-
|
380
|
+
clean_rect(@rect1)
|
381
|
+
@rect1.x = 5
|
382
|
+
@rect1.y = 5
|
383
|
+
end
|
292
384
|
|
293
|
-
|
294
|
-
|
385
|
+
it 'collides if the shapes are close enough' do
|
386
|
+
expect(Gosling::Collision.test(@polygon1, @rect1)).to be true
|
387
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @rect1)
|
388
|
+
expect(result[:colliding]).to be true
|
389
|
+
axis = Snow::Vec2[-10, -5].normalize
|
390
|
+
a = Snow::Vec2[0, 0].dot_product(axis)
|
391
|
+
b = Snow::Vec2[0, 5].dot_product(axis)
|
392
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(a - b)
|
393
|
+
expect(result[:penetration]).to eq(Snow::Vec3[2, 1, 0].normalize * result[:overlap])
|
394
|
+
end
|
295
395
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
396
|
+
it 'returns a vector that separates the shapes' do
|
397
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @rect1)
|
398
|
+
@rect1.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
399
|
+
expect(Gosling::Collision.test(@polygon1, @rect1)).to be false
|
400
|
+
end
|
300
401
|
|
301
|
-
|
302
|
-
|
303
|
-
@rect1.y = 5
|
402
|
+
it 'does not collide if the shapes are far apart' do
|
403
|
+
@rect1.x = 10
|
304
404
|
|
305
|
-
|
306
|
-
|
405
|
+
expect(Gosling::Collision.test(@polygon1, @rect1)).to be false
|
406
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @rect1)
|
407
|
+
expect(result[:colliding]).to be false
|
408
|
+
expect(result[:overlap]).to be nil
|
409
|
+
expect(result[:penetration]).to be nil
|
307
410
|
end
|
411
|
+
end
|
308
412
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
413
|
+
context 'polygon vs. sprite' do
|
414
|
+
before do
|
415
|
+
clean_shape(@polygon1)
|
416
|
+
@polygon1.x = 0
|
417
|
+
@polygon1.y = 0
|
314
418
|
|
315
|
-
|
316
|
-
|
317
|
-
|
419
|
+
clean_sprite(@sprite1)
|
420
|
+
@sprite1.x = 8
|
421
|
+
@sprite1.y = 8
|
422
|
+
end
|
318
423
|
|
319
|
-
|
320
|
-
|
424
|
+
it 'collides if the shapes are close enough' do
|
425
|
+
expect(Gosling::Collision.test(@polygon1, @sprite1)).to be true
|
426
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @sprite1)
|
427
|
+
expect(result[:colliding]).to be true
|
428
|
+
axis = Snow::Vec2[-10, -5].normalize
|
429
|
+
a = Snow::Vec2[0, 0].dot_product(axis)
|
430
|
+
b = Snow::Vec2[0, 5].dot_product(axis)
|
431
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(a - b)
|
432
|
+
expect(result[:penetration]).to eq(Snow::Vec3[2, 1, 0].normalize * result[:overlap])
|
433
|
+
end
|
321
434
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
435
|
+
it 'returns a vector that separates the shapes' do
|
436
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @sprite1)
|
437
|
+
@sprite1.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
438
|
+
expect(Gosling::Collision.test(@polygon1, @sprite1)).to be false
|
439
|
+
end
|
326
440
|
|
327
|
-
|
328
|
-
|
329
|
-
@sprite1.y = 8
|
441
|
+
it 'does not collide if the shapes are far apart' do
|
442
|
+
@sprite1.x = 13
|
330
443
|
|
331
|
-
|
332
|
-
|
444
|
+
expect(Gosling::Collision.test(@polygon1, @sprite1)).to be false
|
445
|
+
result = Gosling::Collision.get_collision_info(@polygon1, @sprite1)
|
446
|
+
expect(result[:colliding]).to be false
|
447
|
+
expect(result[:overlap]).to be nil
|
448
|
+
expect(result[:penetration]).to be nil
|
333
449
|
end
|
450
|
+
end
|
334
451
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
452
|
+
context 'rect vs. rect' do
|
453
|
+
before do
|
454
|
+
clean_rect(@rect1)
|
455
|
+
@rect1.x = 0
|
456
|
+
@rect1.y = 0
|
340
457
|
|
341
|
-
|
342
|
-
|
343
|
-
|
458
|
+
clean_rect(@rect2)
|
459
|
+
@rect2.x = 5
|
460
|
+
@rect2.y = 5
|
461
|
+
end
|
344
462
|
|
345
|
-
|
463
|
+
it 'collides if the shapes are close enough' do
|
464
|
+
expect(Gosling::Collision.test(@rect1, @rect2)).to be true
|
465
|
+
result = Gosling::Collision.get_collision_info(@rect1, @rect2)
|
466
|
+
expect(result[:colliding]).to be true
|
467
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
|
468
|
+
if result[:penetration].x == 0
|
469
|
+
expect(result[:penetration]).to eq(Snow::Vec3[0, 1, 0].normalize * result[:overlap])
|
470
|
+
else
|
471
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 0, 0].normalize * result[:overlap])
|
346
472
|
end
|
473
|
+
end
|
347
474
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
475
|
+
it 'returns a vector that separates the shapes' do
|
476
|
+
result = Gosling::Collision.get_collision_info(@rect1, @rect2)
|
477
|
+
@rect2.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
478
|
+
expect(Gosling::Collision.test(@rect1, @rect2)).to be false
|
479
|
+
end
|
352
480
|
|
353
|
-
|
354
|
-
|
355
|
-
@rect2.y = 5
|
481
|
+
it 'does not collide if the shapes are far apart' do
|
482
|
+
@rect2.x = 11
|
356
483
|
|
357
|
-
|
358
|
-
|
484
|
+
expect(Gosling::Collision.test(@rect1, @rect2)).to be false
|
485
|
+
result = Gosling::Collision.get_collision_info(@rect1, @rect2)
|
486
|
+
expect(result[:colliding]).to be false
|
487
|
+
expect(result[:overlap]).to be nil
|
488
|
+
expect(result[:penetration]).to be nil
|
359
489
|
end
|
490
|
+
end
|
360
491
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
492
|
+
context 'rect vs. sprite' do
|
493
|
+
before do
|
494
|
+
clean_rect(@rect1)
|
495
|
+
@rect1.x = 0
|
496
|
+
@rect1.y = 0
|
366
497
|
|
367
|
-
|
368
|
-
|
369
|
-
|
498
|
+
clean_sprite(@sprite1)
|
499
|
+
@sprite1.x = 8
|
500
|
+
@sprite1.y = 8
|
501
|
+
end
|
370
502
|
|
371
|
-
|
503
|
+
it 'collides if the shapes are close enough' do
|
504
|
+
expect(Gosling::Collision.test(@rect1, @sprite1)).to be true
|
505
|
+
result = Gosling::Collision.get_collision_info(@rect1, @sprite1)
|
506
|
+
expect(result[:colliding]).to be true
|
507
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
|
508
|
+
if result[:penetration].x == 0
|
509
|
+
expect(result[:penetration]).to eq(Snow::Vec3[0, 1, 0].normalize * result[:overlap])
|
510
|
+
else
|
511
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 0, 0].normalize * result[:overlap])
|
372
512
|
end
|
513
|
+
end
|
373
514
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
515
|
+
it 'returns a vector that separates the shapes' do
|
516
|
+
result = Gosling::Collision.get_collision_info(@rect1, @sprite1)
|
517
|
+
@sprite1.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
518
|
+
expect(Gosling::Collision.test(@rect1, @sprite1)).to be false
|
519
|
+
end
|
378
520
|
|
379
|
-
|
380
|
-
|
381
|
-
@sprite1.y = 8
|
521
|
+
it 'does not collide if the shapes are far apart' do
|
522
|
+
@sprite1.x = 16
|
382
523
|
|
383
|
-
|
384
|
-
|
524
|
+
expect(Gosling::Collision.test(@rect1, @sprite1)).to be false
|
525
|
+
result = Gosling::Collision.get_collision_info(@rect1, @sprite1)
|
526
|
+
expect(result[:colliding]).to be false
|
527
|
+
expect(result[:overlap]).to be nil
|
528
|
+
expect(result[:penetration]).to be nil
|
385
529
|
end
|
530
|
+
end
|
386
531
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
532
|
+
context 'sprite vs. sprite' do
|
533
|
+
before do
|
534
|
+
clean_sprite(@sprite1)
|
535
|
+
@sprite1.x = 0
|
536
|
+
@sprite1.y = 0
|
392
537
|
|
393
|
-
|
394
|
-
|
395
|
-
|
538
|
+
clean_sprite(@sprite2)
|
539
|
+
@sprite2.x = 8
|
540
|
+
@sprite2.y = 8
|
541
|
+
end
|
396
542
|
|
397
|
-
|
543
|
+
it 'collides if the shapes are close enough' do
|
544
|
+
expect(Gosling::Collision.test(@sprite1, @sprite2)).to be true
|
545
|
+
result = Gosling::Collision.get_collision_info(@sprite1, @sprite2)
|
546
|
+
expect(result[:colliding]).to be true
|
547
|
+
expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(8)
|
548
|
+
if result[:penetration].x == 0
|
549
|
+
expect(result[:penetration]).to eq(Snow::Vec3[0, 1, 0].normalize * result[:overlap])
|
550
|
+
else
|
551
|
+
expect(result[:penetration]).to eq(Snow::Vec3[1, 0, 0].normalize * result[:overlap])
|
398
552
|
end
|
553
|
+
end
|
399
554
|
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
555
|
+
it 'returns a vector that separates the shapes' do
|
556
|
+
result = Gosling::Collision.get_collision_info(@sprite1, @sprite2)
|
557
|
+
@sprite2.pos += result[:penetration] * (1 + FLOAT_TOLERANCE)
|
558
|
+
expect(Gosling::Collision.test(@sprite1, @sprite2)).to be false
|
559
|
+
end
|
404
560
|
|
405
|
-
|
406
|
-
|
407
|
-
@sprite2.y = 8
|
561
|
+
it 'does not collide if the shapes are far apart' do
|
562
|
+
@sprite2.x = 17
|
408
563
|
|
409
|
-
|
410
|
-
|
564
|
+
expect(Gosling::Collision.test(@sprite1, @sprite2)).to be false
|
565
|
+
result = Gosling::Collision.get_collision_info(@sprite1, @sprite2)
|
566
|
+
expect(result[:colliding]).to be false
|
567
|
+
expect(result[:overlap]).to be nil
|
568
|
+
expect(result[:penetration]).to be nil
|
411
569
|
end
|
412
570
|
end
|
413
571
|
|
@@ -428,124 +586,172 @@ describe Gosling::Collision do
|
|
428
586
|
end
|
429
587
|
|
430
588
|
context 'point vs. circle' do
|
431
|
-
|
589
|
+
before do
|
432
590
|
clean_shape(@circle1)
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
591
|
+
end
|
592
|
+
|
593
|
+
it 'returns true if point is in shape' do
|
594
|
+
points = [
|
595
|
+
Snow::Vec3[0, 0, 0],
|
596
|
+
Snow::Vec3[4, 0, 0],
|
597
|
+
Snow::Vec3[-4, 0, 0],
|
598
|
+
Snow::Vec3[0, 4, 0],
|
599
|
+
Snow::Vec3[0, -4, 0],
|
600
|
+
Snow::Vec3[5, 0, 0],
|
601
|
+
Snow::Vec3[-5, 0, 0],
|
602
|
+
Snow::Vec3[0, 5, 0],
|
603
|
+
Snow::Vec3[0, -5, 0],
|
604
|
+
]
|
605
|
+
points.each do |p|
|
606
|
+
expect(Gosling::Collision.is_point_in_shape?(p, @circle1)).to be true
|
607
|
+
end
|
442
608
|
end
|
443
609
|
|
444
610
|
it 'returns false if point is not in shape' do
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
611
|
+
points = [
|
612
|
+
Snow::Vec3[6, 0, 0],
|
613
|
+
Snow::Vec3[-6, 0, 0],
|
614
|
+
Snow::Vec3[0, 6, 0],
|
615
|
+
Snow::Vec3[0, -6, 0],
|
616
|
+
Snow::Vec3[4, 4, 0],
|
617
|
+
Snow::Vec3[-4, 4, 0],
|
618
|
+
Snow::Vec3[-4, -4, 0],
|
619
|
+
Snow::Vec3[4, -4, 0],
|
620
|
+
]
|
621
|
+
points.each do |p|
|
622
|
+
expect(Gosling::Collision.is_point_in_shape?(p, @circle1)).to be false
|
623
|
+
end
|
454
624
|
end
|
455
625
|
end
|
456
626
|
|
457
627
|
context 'point vs. polygon' do
|
458
|
-
|
628
|
+
before do
|
459
629
|
clean_shape(@polygon1)
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
630
|
+
end
|
631
|
+
|
632
|
+
it 'returns true if point is in shape' do
|
633
|
+
points = [
|
634
|
+
Snow::Vec3[0, 0, 0],
|
635
|
+
Snow::Vec3[0, 4, 0],
|
636
|
+
Snow::Vec3[0, -4, 0],
|
637
|
+
Snow::Vec3[4, -4, 0],
|
638
|
+
Snow::Vec3[-4, -4, 0],
|
639
|
+
Snow::Vec3[0, 5, 0],
|
640
|
+
Snow::Vec3[0, -5, 0],
|
641
|
+
Snow::Vec3[5, -5, 0],
|
642
|
+
Snow::Vec3[-5, -5, 0],
|
643
|
+
]
|
644
|
+
points.each do |p|
|
645
|
+
expect(Gosling::Collision.is_point_in_shape?(p, @polygon1)).to be true
|
646
|
+
end
|
469
647
|
end
|
470
648
|
|
471
649
|
it 'returns false if point is not in shape' do
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
650
|
+
points = [
|
651
|
+
Snow::Vec3[0, 6, 0],
|
652
|
+
Snow::Vec3[0, -6, 0],
|
653
|
+
Snow::Vec3[6, -6, 0],
|
654
|
+
Snow::Vec3[-6, -6, 0],
|
655
|
+
Snow::Vec3[4, 4, 0],
|
656
|
+
Snow::Vec3[-4, 4, 0],
|
657
|
+
]
|
658
|
+
points.each do |p|
|
659
|
+
expect(Gosling::Collision.is_point_in_shape?(p, @polygon1)).to be false
|
660
|
+
end
|
479
661
|
end
|
480
662
|
end
|
481
663
|
|
482
664
|
context 'point vs. rect' do
|
483
|
-
|
665
|
+
before do
|
484
666
|
clean_rect(@rect1)
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
667
|
+
end
|
668
|
+
|
669
|
+
it 'returns true if point is in shape' do
|
670
|
+
points = [
|
671
|
+
Snow::Vec3[0, 0, 0],
|
672
|
+
Snow::Vec3[-4, -4, 0],
|
673
|
+
Snow::Vec3[0, -4, 0],
|
674
|
+
Snow::Vec3[4, -4, 0],
|
675
|
+
Snow::Vec3[4, 0, 0],
|
676
|
+
Snow::Vec3[4, 4, 0],
|
677
|
+
Snow::Vec3[0, 4, 0],
|
678
|
+
Snow::Vec3[-4, 4, 0],
|
679
|
+
Snow::Vec3[-4, 0, 0],
|
680
|
+
Snow::Vec3[-5, -5, 0],
|
681
|
+
Snow::Vec3[0, -5, 0],
|
682
|
+
Snow::Vec3[5, -5, 0],
|
683
|
+
Snow::Vec3[5, 0, 0],
|
684
|
+
Snow::Vec3[5, 5, 0],
|
685
|
+
Snow::Vec3[0, 5, 0],
|
686
|
+
Snow::Vec3[-5, 5, 0],
|
687
|
+
Snow::Vec3[-5, 0, 0],
|
688
|
+
]
|
689
|
+
points.each do |p|
|
690
|
+
expect(Gosling::Collision.is_point_in_shape?(p, @rect1)).to be true
|
691
|
+
end
|
502
692
|
end
|
503
693
|
|
504
694
|
it 'returns false if point is not in shape' do
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
695
|
+
points = [
|
696
|
+
Snow::Vec3[-6, -6, 0],
|
697
|
+
Snow::Vec3[0, -6, 0],
|
698
|
+
Snow::Vec3[6, -6, 0],
|
699
|
+
Snow::Vec3[6, 0, 0],
|
700
|
+
Snow::Vec3[6, 6, 0],
|
701
|
+
Snow::Vec3[0, 6, 0],
|
702
|
+
Snow::Vec3[-6, 6, 0],
|
703
|
+
Snow::Vec3[-6, 0, 0],
|
704
|
+
]
|
705
|
+
points.each do |p|
|
706
|
+
expect(Gosling::Collision.is_point_in_shape?(p, @rect1)).to be false
|
707
|
+
end
|
514
708
|
end
|
515
709
|
end
|
516
710
|
|
517
711
|
context 'point vs. sprite' do
|
518
|
-
|
712
|
+
before do
|
519
713
|
clean_sprite(@sprite1)
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
714
|
+
end
|
715
|
+
|
716
|
+
it 'returns true if point is in shape' do
|
717
|
+
points = [
|
718
|
+
Snow::Vec3[0, 0, 0],
|
719
|
+
Snow::Vec3[-7, -7, 0],
|
720
|
+
Snow::Vec3[0, -7, 0],
|
721
|
+
Snow::Vec3[7, -7, 0],
|
722
|
+
Snow::Vec3[7, 0, 0],
|
723
|
+
Snow::Vec3[7, 7, 0],
|
724
|
+
Snow::Vec3[0, 7, 0],
|
725
|
+
Snow::Vec3[-7, 7, 0],
|
726
|
+
Snow::Vec3[-7, 0, 0],
|
727
|
+
Snow::Vec3[-8, -8, 0],
|
728
|
+
Snow::Vec3[0, -8, 0],
|
729
|
+
Snow::Vec3[8, -8, 0],
|
730
|
+
Snow::Vec3[8, 0, 0],
|
731
|
+
Snow::Vec3[8, 8, 0],
|
732
|
+
Snow::Vec3[0, 8, 0],
|
733
|
+
Snow::Vec3[-8, 8, 0],
|
734
|
+
Snow::Vec3[-8, 0, 0],
|
735
|
+
]
|
736
|
+
points.each do |p|
|
737
|
+
expect(Gosling::Collision.is_point_in_shape?(Snow::Vec3[-8, 0, 0], @sprite1)).to be true
|
738
|
+
end
|
537
739
|
end
|
538
740
|
|
539
741
|
it 'returns false if point is not in shape' do
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
742
|
+
points = [
|
743
|
+
Snow::Vec3[-9, -9, 0],
|
744
|
+
Snow::Vec3[0, -9, 0],
|
745
|
+
Snow::Vec3[9, -9, 0],
|
746
|
+
Snow::Vec3[9, 0, 0],
|
747
|
+
Snow::Vec3[9, 9, 0],
|
748
|
+
Snow::Vec3[0, 9, 0],
|
749
|
+
Snow::Vec3[-9, 9, 0],
|
750
|
+
Snow::Vec3[-9, 0, 0],
|
751
|
+
]
|
752
|
+
points.each do |p|
|
753
|
+
expect(Gosling::Collision.is_point_in_shape?(Snow::Vec3[-9, 0, 0], @sprite1)).to be false
|
754
|
+
end
|
549
755
|
end
|
550
756
|
end
|
551
757
|
end
|
@@ -677,6 +883,11 @@ describe Gosling::Collision do
|
|
677
883
|
end
|
678
884
|
|
679
885
|
describe '#get_circle_separation_axis' do
|
886
|
+
before do
|
887
|
+
clean_shape(@circle1)
|
888
|
+
clean_shape(@circle2)
|
889
|
+
end
|
890
|
+
|
680
891
|
it 'expects two shape arguments' do
|
681
892
|
expect { Gosling::Collision.get_circle_separation_axis(@circle1, @circle2) }.not_to raise_error
|
682
893
|
expect { Gosling::Collision.get_circle_separation_axis(@circle1, @polygon1) }.not_to raise_error
|
@@ -690,11 +901,9 @@ describe Gosling::Collision do
|
|
690
901
|
end
|
691
902
|
|
692
903
|
it 'returns a 3d vector' do
|
693
|
-
clean_shape(@circle1)
|
694
904
|
@circle1.x = 0
|
695
905
|
@circle1.y = 0
|
696
906
|
|
697
|
-
clean_shape(@circle2)
|
698
907
|
@circle2.x = 10
|
699
908
|
@circle2.y = -5
|
700
909
|
|
@@ -703,11 +912,9 @@ describe Gosling::Collision do
|
|
703
912
|
end
|
704
913
|
|
705
914
|
it "returns nil if distance beween shape centers is 0" do
|
706
|
-
clean_shape(@circle1)
|
707
915
|
@circle1.x = 0
|
708
916
|
@circle1.y = 0
|
709
917
|
|
710
|
-
clean_shape(@circle2)
|
711
918
|
@circle2.x = 0
|
712
919
|
@circle2.y = 0
|
713
920
|
|
@@ -716,11 +923,9 @@ describe Gosling::Collision do
|
|
716
923
|
end
|
717
924
|
|
718
925
|
it 'returns a correct unit vector' do
|
719
|
-
clean_shape(@circle1)
|
720
926
|
@circle1.x = 5
|
721
927
|
@circle1.y = -10
|
722
928
|
|
723
|
-
clean_shape(@circle2)
|
724
929
|
@circle2.x = 10
|
725
930
|
@circle2.y = -5
|
726
931
|
|
@@ -933,8 +1138,11 @@ describe Gosling::Collision do
|
|
933
1138
|
end
|
934
1139
|
|
935
1140
|
context 'with a circle' do
|
936
|
-
|
1141
|
+
before do
|
937
1142
|
clean_shape(@circle1)
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
it 'returns expected values' do
|
938
1146
|
@circle1.x = 0
|
939
1147
|
@circle1.y = 0
|
940
1148
|
@circle1.radius = 5
|
@@ -954,7 +1162,6 @@ describe Gosling::Collision do
|
|
954
1162
|
end
|
955
1163
|
|
956
1164
|
it 'respects centering' do
|
957
|
-
clean_shape(@circle1)
|
958
1165
|
@circle1.center_x = 3
|
959
1166
|
@circle1.center_y = 6
|
960
1167
|
|
@@ -968,7 +1175,6 @@ describe Gosling::Collision do
|
|
968
1175
|
end
|
969
1176
|
|
970
1177
|
it 'respects scaling' do
|
971
|
-
clean_shape(@circle1)
|
972
1178
|
@circle1.scale_x = 2
|
973
1179
|
@circle1.scale_y = 0.5
|
974
1180
|
|
@@ -982,7 +1188,6 @@ describe Gosling::Collision do
|
|
982
1188
|
end
|
983
1189
|
|
984
1190
|
it 'respects rotation' do
|
985
|
-
clean_shape(@circle1)
|
986
1191
|
@circle1.rotation = Math::PI
|
987
1192
|
|
988
1193
|
axis = Snow::Vec3[1, 0, 0].normalize
|
@@ -991,7 +1196,6 @@ describe Gosling::Collision do
|
|
991
1196
|
end
|
992
1197
|
|
993
1198
|
it 'respects translation' do
|
994
|
-
clean_shape(@circle1)
|
995
1199
|
@circle1.x = -12
|
996
1200
|
@circle1.y = 23
|
997
1201
|
|
@@ -1017,11 +1221,13 @@ describe Gosling::Collision do
|
|
1017
1221
|
|
1018
1222
|
axis = Snow::Vec3[0, 1, 0].normalize
|
1019
1223
|
result = Gosling::Collision.project_onto_axis(circle, axis)
|
1020
|
-
expect(result).to
|
1224
|
+
expect(result[0]).to be_within(FLOAT_TOLERANCE).of(290.0)
|
1225
|
+
expect(result[1]).to be_within(FLOAT_TOLERANCE).of(340.0)
|
1021
1226
|
|
1022
1227
|
axis = Snow::Vec3[1, 1, 0].normalize
|
1023
1228
|
result = Gosling::Collision.project_onto_axis(circle, axis)
|
1024
|
-
expect(result).to
|
1229
|
+
expect(result[0]).to be_within(FLOAT_TOLERANCE).of(-443.1343965537543)
|
1230
|
+
expect(result[1]).to be_within(FLOAT_TOLERANCE).of(-385.5947509968793)
|
1025
1231
|
|
1026
1232
|
break_inheritance_chain([@center_actor, @scale_actor, @rotate_actor, @translate_actor, circle])
|
1027
1233
|
end
|
@@ -1120,11 +1326,13 @@ describe Gosling::Collision do
|
|
1120
1326
|
|
1121
1327
|
axis = Snow::Vec3[0, 1, 0].normalize
|
1122
1328
|
result = Gosling::Collision.project_onto_axis(polygon, axis)
|
1123
|
-
expect(result).to
|
1329
|
+
expect(result[0]).to be_within(FLOAT_TOLERANCE).of(302.5)
|
1330
|
+
expect(result[1]).to be_within(FLOAT_TOLERANCE).of(327.5)
|
1124
1331
|
|
1125
1332
|
axis = Snow::Vec3[1, 1, 0].normalize
|
1126
1333
|
result = Gosling::Collision.project_onto_axis(polygon, axis)
|
1127
|
-
expect(result).to
|
1334
|
+
expect(result[0]).to be_within(FLOAT_TOLERANCE).of(-426.7389424460814)
|
1335
|
+
expect(result[1]).to be_within(FLOAT_TOLERANCE).of(-393.1513703397204)
|
1128
1336
|
|
1129
1337
|
break_inheritance_chain([@center_actor, @scale_actor, @rotate_actor, @translate_actor, polygon])
|
1130
1338
|
end
|
@@ -1175,9 +1383,74 @@ describe Gosling::Collision do
|
|
1175
1383
|
end
|
1176
1384
|
|
1177
1385
|
context 'when a touches b' do
|
1178
|
-
it 'returns
|
1179
|
-
expect(Gosling::Collision.projections_overlap?([-10, 0], [0, 10])).to be
|
1180
|
-
expect(Gosling::Collision.projections_overlap?([-5, 30], [-17, -5])).to be
|
1386
|
+
it 'returns false' do
|
1387
|
+
expect(Gosling::Collision.projections_overlap?([-10, 0], [0, 10])).to be false
|
1388
|
+
expect(Gosling::Collision.projections_overlap?([-5, 30], [-17, -5])).to be false
|
1389
|
+
end
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
context 'when a just barely overlaps b' do
|
1393
|
+
it 'returns false' do
|
1394
|
+
expect(Gosling::Collision.projections_overlap?([-10, 0.0000001], [0, 10])).to be false
|
1395
|
+
expect(Gosling::Collision.projections_overlap?([-4.999999999, 30], [-17, -5])).to be false
|
1396
|
+
end
|
1397
|
+
end
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
describe '#get_overlap' do
|
1401
|
+
it 'accepts two length 2 arrays with numbers' do
|
1402
|
+
expect { Gosling::Collision.get_overlap([0, 0], [0, 0]) }.not_to raise_error
|
1403
|
+
expect { Gosling::Collision.get_overlap([1, 2], [3, -4]) }.not_to raise_error
|
1404
|
+
|
1405
|
+
expect { Gosling::Collision.get_overlap([1, 2, 3], [4, 5, 6]) }.to raise_error(ArgumentError)
|
1406
|
+
expect { Gosling::Collision.get_overlap([1], [4]) }.to raise_error(ArgumentError)
|
1407
|
+
expect { Gosling::Collision.get_overlap([1, 2], [3, -4], [5, 6]) }.to raise_error(ArgumentError)
|
1408
|
+
expect { Gosling::Collision.get_overlap([1, 2]) }.to raise_error(ArgumentError)
|
1409
|
+
expect { Gosling::Collision.get_overlap([1, 2], :foo) }.to raise_error(ArgumentError)
|
1410
|
+
expect { Gosling::Collision.get_overlap(nil, [1, 2]) }.to raise_error(ArgumentError)
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
context 'when a and b do not overlap' do
|
1414
|
+
it 'returns nil' do
|
1415
|
+
expect(Gosling::Collision.get_overlap([0, 10], [20, 30])).to be_nil
|
1416
|
+
expect(Gosling::Collision.get_overlap([-20, -30], [0, 10])).to be_nil
|
1417
|
+
end
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
context 'when a contains b' do
|
1421
|
+
it 'returns the length of b' do
|
1422
|
+
expect(Gosling::Collision.get_overlap([0, 40], [20, 30])).to eq(10)
|
1423
|
+
expect(Gosling::Collision.get_overlap([-40, 0], [-25, -15])).to eq(10)
|
1424
|
+
expect(Gosling::Collision.get_overlap([-2, 0], [-1, 0])).to eq(1)
|
1425
|
+
end
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
context 'when b contains a' do
|
1429
|
+
it 'returns the length of a' do
|
1430
|
+
expect(Gosling::Collision.get_overlap([5, 10], [0, 50])).to eq(5)
|
1431
|
+
expect(Gosling::Collision.get_overlap([-10, 10], [-25, 25])).to eq(20)
|
1432
|
+
expect(Gosling::Collision.get_overlap([5, 6], [5, 10])).to eq(1)
|
1433
|
+
end
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
context 'when a overlaps b' do
|
1437
|
+
it 'returns the length that overlaps' do
|
1438
|
+
expect(Gosling::Collision.get_overlap([-10, 10], [0, 20])).to eq(10)
|
1439
|
+
expect(Gosling::Collision.get_overlap([-1000, 0], [-1, 314159])).to eq(1)
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
context 'when a touches b' do
|
1444
|
+
it 'returns zero' do
|
1445
|
+
expect(Gosling::Collision.get_overlap([-10, 0], [0, 10])).to eq(0)
|
1446
|
+
expect(Gosling::Collision.get_overlap([-5, 30], [-17, -5])).to eq(0)
|
1447
|
+
end
|
1448
|
+
end
|
1449
|
+
|
1450
|
+
context 'when a just barely overlaps b' do
|
1451
|
+
it 'returns a very tiny value' do
|
1452
|
+
expect(Gosling::Collision.get_overlap([-10, 0.0000001], [0, 10])).to eq(0.0000001)
|
1453
|
+
expect(Gosling::Collision.get_overlap([-5, 30], [-17, -4.999999999])).to be_within(0.00000001).of(0)
|
1181
1454
|
end
|
1182
1455
|
end
|
1183
1456
|
end
|