steering_behaviors 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ ##
2
+ # Copyright 2013, Prylis Incorporated.
3
+ #
4
+ # This file is part of The Ruby Steering Behaviors Library.
5
+ # http://github.com/cpowell/steering-behaviors
6
+ # You can redistribute and/or modify this software only in accordance with
7
+ # the terms found in the "LICENSE" file included with the framework.
8
+
9
+ class SteeringBehaviors::Wander
10
+
11
+ # Wander about in a 'random walk' way. Speeds up and slows down, too.
12
+ # See http://www.red3d.com/cwr/steer/
13
+ #
14
+ # * *Args* :
15
+ # - +kinematic+ -> the wandering thing
16
+ # - +erraticism+ -> how erratic the wandering effect will be
17
+ # * *Returns* :
18
+ # - the calculated steering force
19
+ #
20
+ def self.steer(kinematic, erraticism)
21
+ kinematic.steering_target += SteeringBehaviors::Vector.new(rand(-1.0..1.0)*erraticism, rand(-1.0..1.0)*erraticism)
22
+ kinematic.steering_target.normalize!
23
+
24
+ kinematic.steering_target.rotate(kinematic.heading_vec.radians)
25
+ end
26
+ end
data/test/all_suite.rb ADDED
@@ -0,0 +1,7 @@
1
+ # This is a whole test suite.
2
+ #
3
+ # $ ruby test/all_suite.rb
4
+ # or just
5
+ # $ rake test
6
+
7
+ require "test/vector_test"
@@ -0,0 +1,362 @@
1
+ gem 'minitest'
2
+ require 'minitest/autorun'
3
+
4
+ $:.push File.expand_path('../../lib/', __FILE__)
5
+ require 'steering_behaviors'
6
+ require 'steering_behaviors/vector.rb'
7
+
8
+ # ruby ./test/vector_test.rb
9
+
10
+ class VectorTest < MiniTest::Unit::TestCase
11
+ def setup
12
+ @v = SteeringBehaviors::Vector.new(0, 1.0)
13
+ end
14
+
15
+ def test_setters
16
+ @v.x=5
17
+ assert_equal(5, @v.x)
18
+
19
+ @v.y=10
20
+ assert_equal(10, @v.y)
21
+ end
22
+
23
+ def test_equality
24
+ @v2 = SteeringBehaviors::Vector.new(0, 1.0)
25
+ assert_equal(@v, @v2)
26
+
27
+ @v2 = SteeringBehaviors::Vector.new(5, 1.0)
28
+ refute_equal(@v, @v2)
29
+ end
30
+
31
+ def test_length_calculation
32
+ assert_equal(1, @v.length)
33
+
34
+ @v.x=10
35
+ @v.y=10
36
+ assert_equal(14.142135623730951, @v.length)
37
+
38
+ @v.x=-10
39
+ assert_equal(14.142135623730951, @v.length)
40
+ end
41
+
42
+ def test_addition
43
+ @v2 = SteeringBehaviors::Vector.new(5, -5)
44
+ @v+= @v2
45
+
46
+ assert_equal(5, @v.x)
47
+ assert_equal(-4, @v.y)
48
+ assert_equal(6.4031242374328485, @v.length)
49
+ end
50
+
51
+ def test_subtraction
52
+ @v2 = SteeringBehaviors::Vector.new(5, -5)
53
+ @v-= @v2
54
+
55
+ assert_equal(-5, @v.x)
56
+ assert_equal(6, @v.y)
57
+
58
+ assert_equal(7.810249675906654, @v.length)
59
+ end
60
+
61
+ def test_multiplication
62
+ @v *= 10
63
+ assert_equal(0, @v.x)
64
+ assert_equal(10.0, @v.y)
65
+
66
+ @v *= 0.5
67
+ assert_equal(0, @v.x)
68
+ assert_equal(5.0, @v.y)
69
+
70
+ assert_equal(5.0, @v.length)
71
+ end
72
+
73
+ def test_division
74
+ @v /= 2
75
+ assert_equal(0, @v.x)
76
+ assert_equal(0.5, @v.y)
77
+
78
+ @v /= 0.2
79
+ assert_equal(0, @v.x)
80
+ assert_equal(2.5, @v.y)
81
+
82
+ assert_equal(2.5, @v.length)
83
+ end
84
+
85
+ def test_delta
86
+ other = SteeringBehaviors::Vector.new(1.0, 0)
87
+ assert_equal(Math::PI/2, @v.delta(other))
88
+
89
+ assert_equal(Math::PI/2, other.delta(@v))
90
+
91
+ other = SteeringBehaviors::Vector.new(0.1, 1.0)
92
+ assert_in_delta(0.1, other.delta(@v), 0.01)
93
+
94
+ other = SteeringBehaviors::Vector.new(-0.1, 1.0)
95
+ assert_in_delta(0.1, other.delta(@v), 0.01)
96
+
97
+ other = SteeringBehaviors::Vector.new(-0.1, -1.0)
98
+ assert_in_delta(3.04, other.delta(@v), 0.01)
99
+
100
+ other = SteeringBehaviors::Vector.new(0.1, -1.0)
101
+ assert_in_delta(3.04, other.delta(@v), 0.01)
102
+ end
103
+
104
+ def test_bang_normalization
105
+ res=@v.normalize!
106
+ assert_equal(@v, res)
107
+ assert_equal(1.0, @v.length)
108
+
109
+ @v = SteeringBehaviors::Vector.new(0, 0)
110
+ assert_equal(0, @v.length)
111
+ res=@v.normalize!
112
+ assert_equal(@v, res)
113
+ assert_equal(0.0, @v.length)
114
+
115
+ @v = SteeringBehaviors::Vector.new(1.0, 0)
116
+ assert_equal(1, @v.length)
117
+ res=@v.normalize!
118
+ assert_equal(@v, res)
119
+ assert_equal(1.0, @v.length)
120
+
121
+ @v = SteeringBehaviors::Vector.new(0, 1.0)
122
+ assert_equal(1, @v.length)
123
+ res=@v.normalize!
124
+ assert_equal(@v, res)
125
+ assert_equal(1.0, @v.length)
126
+
127
+ @v = SteeringBehaviors::Vector.new(10, 10)
128
+ assert_equal(14.142135623730951, @v.length)
129
+ res=@v.normalize!
130
+ assert_equal(@v, res)
131
+ assert_in_delta(1.0, @v.length, 0.01)
132
+
133
+ @v = SteeringBehaviors::Vector.new(3, 4)
134
+ assert_equal(5, @v.length)
135
+ res=@v.normalize!
136
+ assert_equal(@v, res)
137
+ assert_equal(1.0, @v.length)
138
+
139
+ @v = SteeringBehaviors::Vector.new(0.5, 1.0)
140
+ res=@v.normalize!
141
+ assert_in_delta(1.0, @v.length, 0.01)
142
+ end
143
+
144
+ def test_normalization
145
+ res=@v.normalize
146
+ assert_equal(1.0, @v.length)
147
+
148
+ @v = SteeringBehaviors::Vector.new(0, 0)
149
+ assert_equal(0, @v.length)
150
+ res=@v.normalize
151
+ assert_equal(@v, res)
152
+ assert_equal(0.0, res.length)
153
+
154
+ @v = SteeringBehaviors::Vector.new(1.0, 0)
155
+ assert_equal(1, @v.length)
156
+ res=@v.normalize
157
+ assert_equal(@v, res)
158
+ assert_equal(1.0, res.length)
159
+
160
+ @v = SteeringBehaviors::Vector.new(0, 1.0)
161
+ assert_equal(1, @v.length)
162
+ res=@v.normalize
163
+ assert_equal(@v, res)
164
+ assert_equal(1.0, res.length)
165
+
166
+ @v = SteeringBehaviors::Vector.new(10, 10)
167
+ assert_equal(14.142135623730951, @v.length)
168
+ res=@v.normalize
169
+ refute_equal(@v, res)
170
+ assert_in_delta(14.142, @v.length, 0.01)
171
+ assert_in_delta(1.0, res.length, 0.01)
172
+
173
+ @v = SteeringBehaviors::Vector.new(3, 4)
174
+ assert_equal(5, @v.length)
175
+ res=@v.normalize
176
+ refute_equal(@v, res)
177
+ assert_equal(5.0, @v.length)
178
+ assert_equal(1.0, res.length)
179
+ end
180
+
181
+ def test_truncation
182
+ res = @v.truncate!(500)
183
+ assert_equal(1.0, res.length)
184
+
185
+ @v = SteeringBehaviors::Vector.new(10, 10)
186
+ assert_equal(14.142135623730951, @v.length)
187
+ res = @v.truncate!(15)
188
+ assert_equal(14.142135623730951, res.length)
189
+
190
+ res = @v.truncate!(9)
191
+ assert_equal(9.0, res.length)
192
+ end
193
+
194
+ def test_dot_product
195
+ @v1 = SteeringBehaviors::Vector.new(0.5, 1)
196
+ @v2 = SteeringBehaviors::Vector.new(1.0, 0.5)
197
+ assert_equal(1.0, @v1.dot(@v2))
198
+
199
+ @v1 = SteeringBehaviors::Vector.new(1.0, 0)
200
+ @v2 = SteeringBehaviors::Vector.new(0, 1.0)
201
+ assert_equal(0, @v1.dot(@v2))
202
+
203
+ @v1 = SteeringBehaviors::Vector.new(0, 1.0)
204
+ @v2 = SteeringBehaviors::Vector.new(-1.0, 0)
205
+ assert_equal(0, @v1.dot(@v2))
206
+
207
+ @v1 = SteeringBehaviors::Vector.new(0, 1.0)
208
+ @v2 = SteeringBehaviors::Vector.new(0.707, 0.707)
209
+ @v2.normalize!
210
+ assert_equal(0.7071067811865476, @v1.dot(@v2))
211
+
212
+ @v1 = SteeringBehaviors::Vector.new(1.0, 0)
213
+ @v2 = SteeringBehaviors::Vector.new(-0.707, 0.707)
214
+ @v2.normalize!
215
+ assert_equal(-0.7071067811865476, @v1.dot(@v2))
216
+
217
+ @v1 = SteeringBehaviors::Vector.new(1.0, 0)
218
+ @v2 = SteeringBehaviors::Vector.new(-0.707, -0.707)
219
+ @v2.normalize!
220
+ assert_equal(-0.7071067811865476, @v1.dot(@v2))
221
+
222
+ @v1 = SteeringBehaviors::Vector.new(0.5, 0.866)
223
+ @v1.normalize!
224
+ @v2 = SteeringBehaviors::Vector.new(0.866, 0.5)
225
+ @v2.normalize!
226
+ assert_equal(0.86603810567665, @v1.dot(@v2))
227
+ end
228
+
229
+ def test_perpendicular
230
+ @v2 = @v.perpendicular
231
+ assert_equal(1.0, @v2.x)
232
+ assert_equal(0, @v2.y)
233
+ end
234
+
235
+ def test_instance_sign
236
+ v1 = SteeringBehaviors::Vector.from_compass_bearing(45)
237
+ v2 = SteeringBehaviors::Vector.from_compass_bearing(115)
238
+
239
+ assert_equal(-1, v1.sign(v2))
240
+ assert_equal(1, v2.sign(v1))
241
+ end
242
+
243
+ def test_compass_bearing
244
+ @v = SteeringBehaviors::Vector.new(5, 5)
245
+ assert_in_delta(45, @v.compass_bearing, 0.1)
246
+
247
+ @v = SteeringBehaviors::Vector.new(-2, 10)
248
+ assert_in_delta(349, @v.compass_bearing, 0.5)
249
+
250
+ @v = SteeringBehaviors::Vector.new(5, 5)
251
+ assert_in_delta(135, @v.compass_bearing(true), 0.1)
252
+
253
+ @v = SteeringBehaviors::Vector.new(-2, 10)
254
+ assert_in_delta(191, @v.compass_bearing(true), 0.5)
255
+ end
256
+
257
+ def test_radians
258
+ assert_equal(0, @v.radians)
259
+
260
+ @v = SteeringBehaviors::Vector.new(1.0, 0)
261
+ assert_equal(Math::PI/2, @v.radians)
262
+
263
+ @v = SteeringBehaviors::Vector.new(0, 1.0)
264
+ assert_equal(0, @v.radians)
265
+
266
+ @v = SteeringBehaviors::Vector.new(0.707, -0.707)
267
+ assert_equal(Math::PI/4*3, @v.radians)
268
+
269
+ @v = SteeringBehaviors::Vector.new(-0.707, 0.707)
270
+ assert_equal(Math::PI/4*7, @v.radians)
271
+ end
272
+
273
+ def test_bang_from_compass_bearing
274
+ @v.from_compass_bearing!(45)
275
+ assert_in_delta(0.707, @v.x, 0.001)
276
+ assert_in_delta(0.707, @v.y, 0.001)
277
+
278
+ @v.from_compass_bearing!(135)
279
+ assert_in_delta(0.707, @v.x, 0.001)
280
+ assert_in_delta(-0.707, @v.y, 0.001)
281
+
282
+ @v.from_compass_bearing!(270)
283
+ assert_in_delta(-1.0, @v.x, 0.001)
284
+ assert_in_delta(0, @v.y, 0.001)
285
+ end
286
+
287
+ def test_bang_rotate
288
+ assert_equal(0, @v.radians)
289
+ @v.rotate!(Math::PI)
290
+ assert_equal(Math::PI, @v.radians)
291
+ assert_in_delta(0.0, @v.x, 0.0001)
292
+ assert_equal(-1.0, @v.y)
293
+
294
+ @v.rotate!(Math::PI/2)
295
+ assert_equal(Math::PI*1.5, @v.radians)
296
+ assert_in_delta(-1.0, @v.x, 0.0001)
297
+ assert_in_delta(0, @v.y, 0.0001)
298
+ end
299
+
300
+ def test_rotate
301
+ assert_equal(0, @v.radians)
302
+ v2 = @v.rotate(Math::PI)
303
+ assert_equal(0, @v.radians)
304
+ assert_equal(Math::PI, v2.radians)
305
+ assert_in_delta(0.0, v2.x, 0.0001)
306
+ assert_equal(-1.0, v2.y)
307
+
308
+ v3 = v2.rotate(Math::PI/2)
309
+ assert_equal(Math::PI*1.5, v3.radians)
310
+ assert_in_delta(-1.0, v3.x, 0.0001)
311
+ assert_in_delta(0, v3.y, 0.0001)
312
+ end
313
+
314
+ def test_rotate_never_returns_negative_rads
315
+ assert_equal(0, @v.radians)
316
+
317
+ new_vec = @v.rotate(-Math::PI/2)
318
+ assert_equal(3.0/2*Math::PI, new_vec.radians)
319
+
320
+ new_vec.rotate!(-Math::PI)
321
+ assert_in_delta(Math::PI/2.0, new_vec.radians, 0.0001)
322
+
323
+ new_vec.rotate!(2.0*Math::PI)
324
+ assert_in_delta(Math::PI/2.0, new_vec.radians, 0.0001)
325
+
326
+ new_vec.rotate!(-2.0*Math::PI)
327
+ assert_in_delta(Math::PI/2.0, new_vec.radians, 0.0001)
328
+ end
329
+
330
+ def test_degree_to_radian_conversion
331
+ assert_equal Math::PI/4, SteeringBehaviors::Vector.deg2rad(45)
332
+ assert_equal Math::PI/2, SteeringBehaviors::Vector.deg2rad(90)
333
+ assert_equal Math::PI, SteeringBehaviors::Vector.deg2rad(180)
334
+ assert_equal Math::PI*14/8, SteeringBehaviors::Vector.deg2rad(315)
335
+ end
336
+
337
+ def test_radian_to_degree_conversion
338
+ assert_equal 45, SteeringBehaviors::Vector.rad2deg(Math::PI/4)
339
+ assert_equal 90, SteeringBehaviors::Vector.rad2deg(Math::PI/2)
340
+ assert_equal 180, SteeringBehaviors::Vector.rad2deg(Math::PI)
341
+ assert_equal 315, SteeringBehaviors::Vector.rad2deg(Math::PI*14/8)
342
+ end
343
+
344
+ def test_class_from_compass_bearing
345
+ v = SteeringBehaviors::Vector.from_compass_bearing(349)
346
+ assert_equal(-0.19080899537654467, v.x)
347
+ assert_equal(0.981627183447664, v.y)
348
+
349
+ v = SteeringBehaviors::Vector.from_compass_bearing(270)
350
+ assert_in_delta(-1.0, v.x, 0.0001)
351
+ assert_in_delta(0, v.y, 0.0001)
352
+ end
353
+
354
+ def test_class_sign
355
+ v1 = SteeringBehaviors::Vector.from_compass_bearing(45)
356
+ v2 = SteeringBehaviors::Vector.from_compass_bearing(115)
357
+
358
+ assert_equal(-1, SteeringBehaviors::Vector.sign(v1, v2))
359
+ assert_equal(1, SteeringBehaviors::Vector.sign(v2, v1))
360
+ end
361
+
362
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: steering_behaviors
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Chris Powell
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-25 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: |
15
+ If you're building a game, you need your game agents and characters to move on their own. A standard way of doing this is with 'steering behaviors'. The seminal paper by Craig Reynolds established a core set of steering behaviors that could be utilized for a variety of common movement tasks and natural behaviors. This Ruby library can accomplish many/most of those tasks for your Ruby / JRuby game. The basic behaviors can be layered for more complicated and advanced behaviors, such as flocking and crowd movement.
16
+ email: cpowell@prylis.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/steering_behaviors.rb
22
+ - lib/steering_behaviors/align.rb
23
+ - lib/steering_behaviors/arrive.rb
24
+ - lib/steering_behaviors/broadside.rb
25
+ - lib/steering_behaviors/common.rb
26
+ - lib/steering_behaviors/evade.rb
27
+ - lib/steering_behaviors/flee.rb
28
+ - lib/steering_behaviors/match.rb
29
+ - lib/steering_behaviors/orthogonal.rb
30
+ - lib/steering_behaviors/pursue.rb
31
+ - lib/steering_behaviors/seek.rb
32
+ - lib/steering_behaviors/steering.rb
33
+ - lib/steering_behaviors/vector.rb
34
+ - lib/steering_behaviors/wander.rb
35
+ - CHANGELOG.md
36
+ - LICENSE
37
+ - Rakefile
38
+ - README.md
39
+ - test/all_suite.rb
40
+ - test/vector_test.rb
41
+ homepage: http://github.com/cpowell/steering-behaviors
42
+ licenses:
43
+ - LGPL
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --main
47
+ - README.md
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ none: false
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ none: false
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.24
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Steering behaviors in Ruby for autonomous game agents, useful for realistic character movement and emulating real-world and natural behaviors.
68
+ test_files: []