gosling 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|