steering_behaviors 1.0.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.
@@ -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: []