vector2d 1.1.2 → 2.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.
- checksums.yaml +4 -4
- data/.travis.yml +7 -0
- data/Gemfile.lock +1 -1
- data/LICENSE +1 -1
- data/README.md +29 -0
- data/lib/vector2d.rb +74 -220
- data/lib/vector2d/calculations.rb +141 -0
- data/lib/vector2d/coercions.rb +64 -0
- data/lib/vector2d/fitting.rb +39 -0
- data/lib/vector2d/properties.rb +46 -0
- data/lib/vector2d/transformations.rb +57 -0
- data/lib/vector2d/version.rb +1 -1
- data/spec/lib/vector2d/calculations_spec.rb +126 -0
- data/spec/lib/vector2d/coercions_spec.rb +55 -0
- data/spec/lib/vector2d/fitting_spec.rb +48 -0
- data/spec/lib/vector2d/properties_spec.rb +43 -0
- data/spec/lib/vector2d/transformations_spec.rb +57 -0
- data/spec/lib/vector2d_spec.rb +31 -268
- data/spec/spec_helper.rb +2 -0
- data/vector2d.gemspec +2 -0
- metadata +20 -5
- data/README.rdoc +0 -61
- data/VERSION +0 -1
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Vector2d::Properties do
|
6
|
+
subject(:vector) { Vector2d.new(2, 3) }
|
7
|
+
|
8
|
+
describe "#angle" do
|
9
|
+
it "returns the angle" do
|
10
|
+
expect(vector.angle).to be_within(0.0001).of(0.9827)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#aspect_ratio" do
|
15
|
+
it "returns the aspect_ratio" do
|
16
|
+
expect(vector.aspect_ratio).to be_within(0.0001).of(0.6667)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#length" do
|
21
|
+
it "calculates the length" do
|
22
|
+
expect(vector.length).to be_within(0.0001).of(3.6055)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#squared_length" do
|
27
|
+
it "calculates the squared length" do
|
28
|
+
expect(vector.squared_length).to eq(13)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#normalized?" do
|
33
|
+
subject { vector.normalized? }
|
34
|
+
context "when vector is normalized" do
|
35
|
+
let(:vector) { Vector2d.new(2, 3).normalize }
|
36
|
+
it { should be_true }
|
37
|
+
end
|
38
|
+
context "when vector isn't normalized" do
|
39
|
+
let(:vector) { Vector2d.new(2, 3) }
|
40
|
+
it { should be_false }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Vector2d::Transformations do
|
6
|
+
subject(:vector) { Vector2d.new(2, 3) }
|
7
|
+
|
8
|
+
describe "#normalize" do
|
9
|
+
it "normalizes the vector" do
|
10
|
+
expect(vector.normalize.x).to be_within(0.0001).of(0.5547)
|
11
|
+
expect(vector.normalize.y).to be_within(0.0001).of(0.8320)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#perpendicular" do
|
16
|
+
it "returns a perpendicular vector" do
|
17
|
+
expect(vector.perpendicular).to eq(Vector2d.new(-3, 2))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#resize" do
|
22
|
+
subject(:resized) { vector.resize(2.0) }
|
23
|
+
it "modifies the vector length" do
|
24
|
+
expect(resized.length).to be_within(0.0001).of(2.0)
|
25
|
+
expect(resized.x).to be_within(0.0001).of(1.1094)
|
26
|
+
expect(resized.y).to be_within(0.0001).of(1.6641)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#reverse" do
|
31
|
+
it "reverses the vector" do
|
32
|
+
expect(vector.reverse).to eq(Vector2d.new(-2, -3))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#round" do
|
37
|
+
subject(:vector) { Vector2d.new(2.3, 3.6) }
|
38
|
+
it "rounds the vector" do
|
39
|
+
expect(vector.round).to eq(Vector2d.new(2, 4))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#truncate" do
|
44
|
+
context "when argument is longer than length" do
|
45
|
+
let(:arg) { 5.0 }
|
46
|
+
it "does not change the length" do
|
47
|
+
expect(vector.truncate(arg).length).to be_within(0.0001).of(3.6055)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context "when argument is shorter than length" do
|
51
|
+
let(:arg) { 2.5 }
|
52
|
+
it "changes the length" do
|
53
|
+
expect(vector.truncate(arg).length).to be_within(0.0001).of(arg)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/lib/vector2d_spec.rb
CHANGED
@@ -1,78 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Vector2d do
|
4
6
|
subject(:vector) { Vector2d.new(2, 3) }
|
5
7
|
|
6
|
-
shared_examples "a vector
|
8
|
+
shared_examples "a parsed vector" do |x, y|
|
7
9
|
it "receives the x and y properties" do
|
8
10
|
expect(subject.x).to eq(x)
|
9
11
|
expect(subject.y).to eq(y)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
|
-
describe "
|
15
|
+
describe "helper method" do
|
16
|
+
it "creates a vector" do
|
17
|
+
expect(Vector2d(2, 3)).to eq(Vector2d.new(2, 3))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".parse" do
|
22
|
+
context "with fixnum argument" do
|
23
|
+
subject(:vector) { Vector2d.parse(2) }
|
24
|
+
it_behaves_like "a parsed vector", [2, 2]
|
25
|
+
end
|
26
|
+
|
14
27
|
context "with two arguments, fixnum" do
|
15
|
-
subject(:vector) { Vector2d.
|
16
|
-
it_behaves_like "a vector
|
28
|
+
subject(:vector) { Vector2d.parse(1, 2) }
|
29
|
+
it_behaves_like "a parsed vector", [1, 2]
|
17
30
|
end
|
18
31
|
|
19
32
|
context "with two arguments, float" do
|
20
|
-
subject(:vector) { Vector2d.
|
21
|
-
it_behaves_like "a vector
|
33
|
+
subject(:vector) { Vector2d.parse(1.0, 2.0) }
|
34
|
+
it_behaves_like "a parsed vector", [1.0, 2.0]
|
22
35
|
end
|
23
36
|
|
24
37
|
context "with string argument, fixnum" do
|
25
|
-
subject(:vector) { Vector2d.
|
26
|
-
it_behaves_like "a vector
|
38
|
+
subject(:vector) { Vector2d.parse("1x2") }
|
39
|
+
it_behaves_like "a parsed vector", [1, 2]
|
27
40
|
end
|
28
41
|
|
29
42
|
context "with string argument, float" do
|
30
|
-
subject(:vector) { Vector2d.
|
31
|
-
it_behaves_like "a vector
|
43
|
+
subject(:vector) { Vector2d.parse("1.0x2.0") }
|
44
|
+
it_behaves_like "a parsed vector", [1.0, 2.0]
|
32
45
|
end
|
33
46
|
|
34
47
|
context "with array argument" do
|
35
|
-
subject(:vector) { Vector2d.
|
36
|
-
it_behaves_like "a vector
|
48
|
+
subject(:vector) { Vector2d.parse([1, 2]) }
|
49
|
+
it_behaves_like "a parsed vector", [1, 2]
|
37
50
|
end
|
38
51
|
|
39
52
|
context "with hash argument, symbol keys" do
|
40
|
-
subject(:vector) { Vector2d.
|
41
|
-
it_behaves_like "a vector
|
53
|
+
subject(:vector) { Vector2d.parse({:x => 1, :y => 2}) }
|
54
|
+
it_behaves_like "a parsed vector", [1, 2]
|
42
55
|
end
|
43
56
|
|
44
57
|
context "with hash argument, string keys" do
|
45
|
-
subject(:vector) { Vector2d.
|
46
|
-
it_behaves_like "a vector
|
58
|
+
subject(:vector) { Vector2d.parse({'x' => 1, 'y' => 2}) }
|
59
|
+
it_behaves_like "a parsed vector", [1, 2]
|
47
60
|
end
|
48
61
|
|
49
62
|
context "with vector argument" do
|
50
|
-
subject(:vector) { Vector2d.
|
51
|
-
it_behaves_like "a vector
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe ".cross_product" do
|
56
|
-
let(:v1) { Vector2d.new(2, 3) }
|
57
|
-
let(:v2) { Vector2d.new(4, 5) }
|
58
|
-
it "calculates the cross product between two vectors" do
|
59
|
-
expect(Vector2d.cross_product(v1, v2)).to be_within(0.0001).of(-2.0)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe ".dot_product" do
|
64
|
-
let(:v1) { Vector2d.new(2, 3) }
|
65
|
-
let(:v2) { Vector2d.new(4, 5) }
|
66
|
-
it "calculates the dot product between two vectors" do
|
67
|
-
expect(Vector2d.dot_product(v1, v2)).to be_within(0.0001).of(23.0)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe ".angle_between" do
|
72
|
-
let(:v1) { Vector2d.new(2, 3) }
|
73
|
-
let(:v2) { Vector2d.new(4, 5) }
|
74
|
-
it "calculates the angle between two vectors" do
|
75
|
-
expect(Vector2d.angle_between(v1, v2)).to be_within(0.0001).of(0.0867)
|
63
|
+
subject(:vector) { Vector2d.parse(Vector2d.new(1, 2)) }
|
64
|
+
it_behaves_like "a parsed vector", [1, 2]
|
76
65
|
end
|
77
66
|
end
|
78
67
|
|
@@ -94,230 +83,4 @@ describe Vector2d do
|
|
94
83
|
it { should be_false }
|
95
84
|
end
|
96
85
|
end
|
97
|
-
|
98
|
-
describe "#to_s" do
|
99
|
-
it "renders a string" do
|
100
|
-
expect(vector.to_s).to eq('2.0x3.0')
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
describe "#length" do
|
105
|
-
it "calculates the length" do
|
106
|
-
expect(vector.length).to be_within(0.0001).of(3.6055)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe "#length_squared" do
|
111
|
-
it "calculates the squared length" do
|
112
|
-
expect(vector.length_squared).to be_within(0.0001).of(13.0)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
describe "#length=" do
|
117
|
-
it "modifies the vector length" do
|
118
|
-
vector.length = 2.0
|
119
|
-
expect(vector.length).to be_within(0.0001).of(2.0)
|
120
|
-
expect(vector.x).to be_within(0.0001).of(1.1094)
|
121
|
-
expect(vector.y).to be_within(0.0001).of(1.6641)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe "#normalize" do
|
126
|
-
it "normalizes the vector" do
|
127
|
-
expect(vector.normalize.x).to be_within(0.0001).of(0.5547)
|
128
|
-
expect(vector.normalize.y).to be_within(0.0001).of(0.8320)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
describe "#normalize!" do
|
133
|
-
it "normalizes the vector in place" do
|
134
|
-
vector.normalize!
|
135
|
-
expect(vector).to eq(vector.normalize)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
describe "#round" do
|
140
|
-
subject(:vector) { Vector2d.new(2.3, 3.6) }
|
141
|
-
it "rounds the vector" do
|
142
|
-
expect(vector.round).to eq(Vector2d.new(2, 4))
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe "#round!" do
|
147
|
-
subject(:vector) { Vector2d.new(2.3, 3.6) }
|
148
|
-
it "rounds the vector in place" do
|
149
|
-
vector.round!
|
150
|
-
expect(vector).to eq(Vector2d.new(2, 4))
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
describe "*" do
|
155
|
-
context "with vector" do
|
156
|
-
subject(:vector) { Vector2d.new(2, 3) * Vector2d.new(3, 4) }
|
157
|
-
it "multiplies the vectors" do
|
158
|
-
expect(vector).to eq(Vector2d.new(6, 12))
|
159
|
-
end
|
160
|
-
end
|
161
|
-
context "with number" do
|
162
|
-
subject(:vector) { Vector2d.new(2, 3) * 3 }
|
163
|
-
it "multiplies both members" do
|
164
|
-
expect(vector).to eq(Vector2d.new(6, 9))
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
describe "/" do
|
170
|
-
context "with vector" do
|
171
|
-
subject(:vector) { Vector2d.new(6, 12) / Vector2d.new(2, 3) }
|
172
|
-
it "divides the vectors" do
|
173
|
-
expect(vector).to eq(Vector2d.new(3, 4))
|
174
|
-
end
|
175
|
-
end
|
176
|
-
context "with number" do
|
177
|
-
subject(:vector) { Vector2d.new(6, 12) / 3 }
|
178
|
-
it "divides both members" do
|
179
|
-
expect(vector).to eq(Vector2d.new(2, 4))
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
describe "+" do
|
185
|
-
context "with vector" do
|
186
|
-
subject(:vector) { Vector2d.new(2, 3) + Vector2d.new(3, 4) }
|
187
|
-
it "adds the vectors" do
|
188
|
-
expect(vector).to eq(Vector2d.new(5, 7))
|
189
|
-
end
|
190
|
-
end
|
191
|
-
context "with number" do
|
192
|
-
subject(:vector) { Vector2d.new(2, 3) + 2 }
|
193
|
-
it "adds to both members" do
|
194
|
-
expect(vector).to eq(Vector2d.new(4, 5))
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
describe "-" do
|
200
|
-
context "with vector" do
|
201
|
-
subject(:vector) { Vector2d.new(3, 5) - Vector2d.new(1, 2) }
|
202
|
-
it "subtracts the vectors" do
|
203
|
-
expect(vector).to eq(Vector2d.new(2, 3))
|
204
|
-
end
|
205
|
-
end
|
206
|
-
context "with number" do
|
207
|
-
subject(:vector) { Vector2d.new(2, 3) - 2 }
|
208
|
-
it "subtracts from both members" do
|
209
|
-
expect(vector).to eq(Vector2d.new(0, 1))
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
describe "#perpendicular" do
|
215
|
-
it "returns a perpendicular vector" do
|
216
|
-
expect(vector.perpendicular).to eq(Vector2d.new(-3, 2))
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
describe "#distance" do
|
221
|
-
let(:comp) { Vector2d.new(3, 4) }
|
222
|
-
it "returns the distance between two vectors" do
|
223
|
-
expect(vector.distance(comp)).to be_within(0.0001).of(1.4142)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
describe "#distance_sq" do
|
228
|
-
let(:comp) { Vector2d.new(5, 6) }
|
229
|
-
it "returns the squared distance between two vectors" do
|
230
|
-
expect(vector.distance_sq(comp)).to be_within(0.0001).of(18.0)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
describe "#angle" do
|
235
|
-
it "returns the angle" do
|
236
|
-
expect(vector.angle).to be_within(0.0001).of(0.9827)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
describe "#truncate" do
|
241
|
-
context "when argument is longer than length" do
|
242
|
-
let(:arg) { 5.0 }
|
243
|
-
it "does not change the length" do
|
244
|
-
expect(vector.truncate(arg).length).to be_within(0.0001).of(3.6055)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
context "when argument is shorter than length" do
|
248
|
-
let(:arg) { 2.5 }
|
249
|
-
it "changes the length" do
|
250
|
-
expect(vector.truncate(arg).length).to be_within(0.0001).of(arg)
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
describe "#reverse" do
|
256
|
-
it "reverses the vector" do
|
257
|
-
expect(vector.reverse).to eq(Vector2d.new(-2, -3))
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
describe "#cross_product" do
|
262
|
-
let(:comp) { Vector2d.new(3, 4) }
|
263
|
-
it "calulates the cross product" do
|
264
|
-
expect(vector.cross_product(comp)).to eq(Vector2d.cross_product(vector, comp))
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
describe "#dot_product" do
|
269
|
-
let(:comp) { Vector2d.new(3, 4) }
|
270
|
-
it "calulates the dot product" do
|
271
|
-
expect(vector.dot_product(comp)).to eq(Vector2d.dot_product(vector, comp))
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
describe "#angle_between" do
|
276
|
-
let(:comp) { Vector2d.new(3, 4) }
|
277
|
-
it "calculates the angle between vectors" do
|
278
|
-
expect(vector.angle_between(comp)).to eq(Vector2d.angle_between(vector, comp))
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
describe "#contrain_both" do
|
283
|
-
let(:original) { Vector2d.new(300, 300) }
|
284
|
-
subject(:vector) { original.constrain_both(comp) }
|
285
|
-
|
286
|
-
context "when scaling by height" do
|
287
|
-
let(:comp) { Vector2d.new(200, 150) }
|
288
|
-
it "should fit within the other vector" do
|
289
|
-
expect(vector.x).to be_within(0.0001).of(150)
|
290
|
-
expect(vector.y).to be_within(0.0001).of(150)
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
context "when scaling by width" do
|
295
|
-
let(:comp) { Vector2d.new(150, 200) }
|
296
|
-
it "should fit within the other vector" do
|
297
|
-
expect(vector.x).to be_within(0.0001).of(150)
|
298
|
-
expect(vector.y).to be_within(0.0001).of(150)
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
describe "#contrain_one" do
|
304
|
-
let(:original) { Vector2d.new(300, 300) }
|
305
|
-
subject(:vector) { original.constrain_one(comp) }
|
306
|
-
|
307
|
-
context "when width is largest" do
|
308
|
-
let(:comp) { Vector2d.new(200, 150) }
|
309
|
-
it "should be the same width" do
|
310
|
-
expect(vector.x).to be_within(0.0001).of(200)
|
311
|
-
expect(vector.y).to be_within(0.0001).of(200)
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
context "when height is largest" do
|
316
|
-
let(:comp) { Vector2d.new(150, 200) }
|
317
|
-
it "should be the same height" do
|
318
|
-
expect(vector.x).to be_within(0.0001).of(200)
|
319
|
-
expect(vector.y).to be_within(0.0001).of(200)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
end
|
323
86
|
end
|
data/spec/spec_helper.rb
CHANGED
data/vector2d.gemspec
CHANGED
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
22
|
s.require_paths = ["lib"]
|
23
23
|
|
24
|
+
s.required_ruby_version = '>= 1.9.2'
|
25
|
+
|
24
26
|
# specify any dependencies here; for example:
|
25
27
|
s.add_development_dependency "rake", "~> 10.3"
|
26
28
|
s.add_development_dependency "rspec", "~> 2.1"
|