vector2d 2.2.3 → 2.2.4
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 +5 -5
- data/.github/workflows/build.yml +41 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +26 -0
- data/.travis.yml +6 -7
- data/Gemfile +12 -4
- data/Gemfile.lock +62 -28
- data/README.md +9 -4
- data/Rakefile +6 -2
- data/lib/vector2d/calculations.rb +10 -26
- data/lib/vector2d/coercions.rb +1 -10
- data/lib/vector2d/fitting.rb +22 -18
- data/lib/vector2d/properties.rb +4 -11
- data/lib/vector2d/transformations.rb +6 -17
- data/lib/vector2d/version.rb +2 -2
- data/lib/vector2d.rb +25 -51
- data/spec/lib/vector2d/calculations_spec.rb +29 -5
- data/spec/lib/vector2d/coercions_spec.rb +19 -15
- data/spec/lib/vector2d/fitting_spec.rb +26 -32
- data/spec/lib/vector2d/properties_spec.rb +8 -4
- data/spec/lib/vector2d/transformations_spec.rb +56 -18
- data/spec/lib/vector2d_spec.rb +39 -22
- data/spec/spec_helper.rb +5 -4
- data/vector2d.gemspec +12 -17
- metadata +14 -61
@@ -1,14 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Vector2d
|
4
4
|
module Transformations
|
5
|
-
include Contracts
|
6
|
-
|
7
5
|
# Rounds vector to up nearest integer.
|
8
6
|
#
|
9
7
|
# Vector2d(2.4, 3.6).ceil # => Vector2d(3,4)
|
10
8
|
#
|
11
|
-
Contract None => Vector2d
|
12
9
|
def ceil
|
13
10
|
self.class.new(x.ceil, y.ceil)
|
14
11
|
end
|
@@ -17,7 +14,6 @@ class Vector2d
|
|
17
14
|
#
|
18
15
|
# Vector2d(2.4, 3.6).floor # => Vector2d(2,3)
|
19
16
|
#
|
20
|
-
Contract None => Vector2d
|
21
17
|
def floor
|
22
18
|
self.class.new(x.floor, y.floor)
|
23
19
|
end
|
@@ -28,7 +24,6 @@ class Vector2d
|
|
28
24
|
# vector.normalize # => Vector2d(0.5547.., 0.8320..)
|
29
25
|
# vector.normalize.length # => 1.0
|
30
26
|
#
|
31
|
-
Contract None => Vector2d
|
32
27
|
def normalize
|
33
28
|
resize(1.0)
|
34
29
|
end
|
@@ -37,7 +32,6 @@ class Vector2d
|
|
37
32
|
#
|
38
33
|
# Vector2d(2, 3).perpendicular # => Vector2d(-3,2)
|
39
34
|
#
|
40
|
-
Contract None => Vector2d
|
41
35
|
def perpendicular
|
42
36
|
Vector2d.new(-y, x)
|
43
37
|
end
|
@@ -46,16 +40,14 @@ class Vector2d
|
|
46
40
|
#
|
47
41
|
# Vector2d(2, 3).resize(1.0) # => Vector2d(0.5547.., 0.8320..)
|
48
42
|
#
|
49
|
-
Contract Num => Vector2d
|
50
43
|
def resize(new_length)
|
51
|
-
self * (new_length /
|
44
|
+
self * (new_length / length)
|
52
45
|
end
|
53
46
|
|
54
47
|
# Reverses the vector.
|
55
48
|
#
|
56
49
|
# Vector2d(2, 3).reverse # => Vector2d(-2,-3)
|
57
50
|
#
|
58
|
-
Contract None => Vector2d
|
59
51
|
def reverse
|
60
52
|
self.class.new(-x, -y)
|
61
53
|
end
|
@@ -64,11 +56,10 @@ class Vector2d
|
|
64
56
|
#
|
65
57
|
# Vector2d(1, 0).rotate(Math:PI/2) => Vector2d(1,0)
|
66
58
|
#
|
67
|
-
Contract Num => Vector2d
|
68
59
|
def rotate(angle)
|
69
60
|
Vector2d.new(
|
70
|
-
x * Math.cos(angle) - y * Math.sin(angle),
|
71
|
-
x * Math.sin(angle) + y * Math.cos(angle)
|
61
|
+
(x * Math.cos(angle)) - (y * Math.sin(angle)),
|
62
|
+
(x * Math.sin(angle)) + (y * Math.cos(angle))
|
72
63
|
)
|
73
64
|
end
|
74
65
|
|
@@ -77,8 +68,7 @@ class Vector2d
|
|
77
68
|
# Vector2d(2.4, 3.6).round # => Vector2d(2,4)
|
78
69
|
# Vector2d(2.4444, 3.666).round(2) # => Vector2d(2.44, 3.67)
|
79
70
|
#
|
80
|
-
|
81
|
-
def round(digits=0)
|
71
|
+
def round(digits = 0)
|
82
72
|
self.class.new(x.round(digits), y.round(digits))
|
83
73
|
end
|
84
74
|
|
@@ -88,9 +78,8 @@ class Vector2d
|
|
88
78
|
# vector.truncate(5.0) # => Vector2d(2.0, 3.0)
|
89
79
|
# vector.truncate(1.0) # => Vector2d(0.5547.., 0.8320..)
|
90
80
|
#
|
91
|
-
Contract Num => Vector2d
|
92
81
|
def truncate(max)
|
93
|
-
resize([max,
|
82
|
+
resize([max, length].min)
|
94
83
|
end
|
95
84
|
end
|
96
85
|
end
|
data/lib/vector2d/version.rb
CHANGED
data/lib/vector2d.rb
CHANGED
@@ -1,25 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
{ x: Num, y: Num },
|
10
|
-
{ 'x' => Num, 'y' => Num },
|
11
|
-
Num,
|
12
|
-
String,
|
13
|
-
Vector2d
|
14
|
-
]
|
15
|
-
end
|
16
|
-
|
17
|
-
require 'vector2d/calculations'
|
18
|
-
require 'vector2d/coercions'
|
19
|
-
require 'vector2d/fitting'
|
20
|
-
require 'vector2d/properties'
|
21
|
-
require 'vector2d/transformations'
|
22
|
-
require 'vector2d/version'
|
3
|
+
require "vector2d/calculations"
|
4
|
+
require "vector2d/coercions"
|
5
|
+
require "vector2d/fitting"
|
6
|
+
require "vector2d/properties"
|
7
|
+
require "vector2d/transformations"
|
8
|
+
require "vector2d/version"
|
23
9
|
|
24
10
|
class Vector2d
|
25
11
|
extend Vector2d::Calculations::ClassMethods
|
@@ -41,55 +27,44 @@ class Vector2d
|
|
41
27
|
# Vector2d.parse({x: 150, y: 100})
|
42
28
|
# Vector2d.parse({"x" => 150.0, "y" => 100.0})
|
43
29
|
# Vector2d.parse(Vector2d(150, 100))
|
44
|
-
Contract VectorLike, Maybe[Num] => Vector2d
|
45
30
|
def parse(arg, second_arg = nil)
|
46
31
|
if second_arg.nil?
|
47
32
|
parse_single_arg(arg)
|
48
33
|
else
|
49
|
-
|
34
|
+
new(arg, second_arg)
|
50
35
|
end
|
51
36
|
end
|
52
37
|
|
53
38
|
private
|
54
39
|
|
55
|
-
Contract VectorLike => Vector2d
|
56
40
|
def parse_single_arg(arg)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
parse_str(arg)
|
64
|
-
when Hash
|
65
|
-
parse_hash(arg.dup)
|
66
|
-
else
|
67
|
-
self.new(arg, arg)
|
68
|
-
end
|
41
|
+
return arg if arg.is_a?(Vector2d)
|
42
|
+
return parse(*arg) if arg.is_a?(Array)
|
43
|
+
return parse_str(arg) if arg.is_a?(String)
|
44
|
+
return parse_hash(arg.dup) if arg.is_a?(Hash)
|
45
|
+
|
46
|
+
new(arg, arg)
|
69
47
|
end
|
70
48
|
|
71
|
-
Contract Hash => Vector2d
|
72
49
|
def parse_hash(hash)
|
73
|
-
hash[:x] ||= hash[
|
74
|
-
hash[:y] ||= hash[
|
75
|
-
|
50
|
+
hash[:x] ||= hash["x"] if hash.key?("x")
|
51
|
+
hash[:y] ||= hash["y"] if hash.key?("y")
|
52
|
+
new(hash[:x], hash[:y])
|
76
53
|
end
|
77
54
|
|
78
|
-
Contract String => Vector2d
|
79
55
|
def parse_str(str)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
fail ArgumentError, "not a valid string input"
|
85
|
-
end
|
56
|
+
raise ArgumentError, "not a valid string input" unless /^\s*[\d.]*\s*x\s*[\d.]*\s*$/.match?(str)
|
57
|
+
|
58
|
+
x, y = str.split("x")
|
59
|
+
new(x.to_f, y.to_f)
|
86
60
|
end
|
87
61
|
end
|
88
62
|
|
89
63
|
attr_reader :x, :y
|
90
64
|
|
91
65
|
def initialize(x, y)
|
92
|
-
@x
|
66
|
+
@x = x
|
67
|
+
@y = y
|
93
68
|
end
|
94
69
|
|
95
70
|
# Compares two vectors
|
@@ -97,9 +72,8 @@ class Vector2d
|
|
97
72
|
# Vector2d(2, 3) == Vector2d(2, 3) # => true
|
98
73
|
# Vector2d(2, 3) == Vector2d(1, 0) # => false
|
99
74
|
#
|
100
|
-
|
101
|
-
|
102
|
-
comp.x === x && comp.y === y
|
75
|
+
def ==(other)
|
76
|
+
other.x == x && other.y == y
|
103
77
|
end
|
104
78
|
end
|
105
79
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe Vector2d::Calculations do
|
6
6
|
subject(:vector) { Vector2d.new(2, 3) }
|
@@ -8,6 +8,7 @@ describe Vector2d::Calculations do
|
|
8
8
|
describe ".cross_product" do
|
9
9
|
let(:v1) { Vector2d.new(2, 3) }
|
10
10
|
let(:v2) { Vector2d.new(4, 5) }
|
11
|
+
|
11
12
|
it "calculates the cross product between two vectors" do
|
12
13
|
expect(Vector2d.cross_product(v1, v2)).to eq(-2.0)
|
13
14
|
end
|
@@ -16,6 +17,7 @@ describe Vector2d::Calculations do
|
|
16
17
|
describe ".dot_product" do
|
17
18
|
let(:v1) { Vector2d.new(2, 3) }
|
18
19
|
let(:v2) { Vector2d.new(4, 5) }
|
20
|
+
|
19
21
|
it "calculates the dot product between two vectors" do
|
20
22
|
expect(Vector2d.dot_product(v1, v2)).to eq(23)
|
21
23
|
end
|
@@ -24,6 +26,7 @@ describe Vector2d::Calculations do
|
|
24
26
|
describe ".angle_between" do
|
25
27
|
let(:v1) { Vector2d.new(2, 3) }
|
26
28
|
let(:v2) { Vector2d.new(4, 5) }
|
29
|
+
|
27
30
|
it "calculates the angle between two vectors" do
|
28
31
|
expect(Vector2d.angle_between(v1, v2)).to be_within(0.0001).of(0.0867)
|
29
32
|
end
|
@@ -32,12 +35,15 @@ describe Vector2d::Calculations do
|
|
32
35
|
describe "*" do
|
33
36
|
context "with vector" do
|
34
37
|
subject(:vector) { Vector2d.new(2, 3) * Vector2d.new(3, 4) }
|
38
|
+
|
35
39
|
it "multiplies the vectors" do
|
36
40
|
expect(vector).to eq(Vector2d.new(6, 12))
|
37
41
|
end
|
38
42
|
end
|
43
|
+
|
39
44
|
context "with number" do
|
40
45
|
subject(:vector) { Vector2d.new(2, 3) * 3 }
|
46
|
+
|
41
47
|
it "multiplies both members" do
|
42
48
|
expect(vector).to eq(Vector2d.new(6, 9))
|
43
49
|
end
|
@@ -47,12 +53,15 @@ describe Vector2d::Calculations do
|
|
47
53
|
describe "/" do
|
48
54
|
context "with vector" do
|
49
55
|
subject(:vector) { Vector2d.new(6, 12) / Vector2d.new(2, 3) }
|
56
|
+
|
50
57
|
it "divides the vectors" do
|
51
58
|
expect(vector).to eq(Vector2d.new(3, 4))
|
52
59
|
end
|
53
60
|
end
|
61
|
+
|
54
62
|
context "with number" do
|
55
63
|
subject(:vector) { Vector2d.new(6, 12) / 3 }
|
64
|
+
|
56
65
|
it "divides both members" do
|
57
66
|
expect(vector).to eq(Vector2d.new(2, 4))
|
58
67
|
end
|
@@ -62,12 +71,15 @@ describe Vector2d::Calculations do
|
|
62
71
|
describe "+" do
|
63
72
|
context "with vector" do
|
64
73
|
subject(:vector) { Vector2d.new(2, 3) + Vector2d.new(3, 4) }
|
74
|
+
|
65
75
|
it "adds the vectors" do
|
66
76
|
expect(vector).to eq(Vector2d.new(5, 7))
|
67
77
|
end
|
68
78
|
end
|
79
|
+
|
69
80
|
context "with number" do
|
70
81
|
subject(:vector) { Vector2d.new(2, 3) + 2 }
|
82
|
+
|
71
83
|
it "adds to both members" do
|
72
84
|
expect(vector).to eq(Vector2d.new(4, 5))
|
73
85
|
end
|
@@ -77,12 +89,15 @@ describe Vector2d::Calculations do
|
|
77
89
|
describe "-" do
|
78
90
|
context "with vector" do
|
79
91
|
subject(:vector) { Vector2d.new(3, 5) - Vector2d.new(1, 2) }
|
92
|
+
|
80
93
|
it "subtracts the vectors" do
|
81
94
|
expect(vector).to eq(Vector2d.new(2, 3))
|
82
95
|
end
|
83
96
|
end
|
97
|
+
|
84
98
|
context "with number" do
|
85
99
|
subject(:vector) { Vector2d.new(2, 3) - 2 }
|
100
|
+
|
86
101
|
it "subtracts from both members" do
|
87
102
|
expect(vector).to eq(Vector2d.new(0, 1))
|
88
103
|
end
|
@@ -91,13 +106,17 @@ describe Vector2d::Calculations do
|
|
91
106
|
|
92
107
|
describe "#cross_product" do
|
93
108
|
let(:comp) { Vector2d.new(3, 4) }
|
109
|
+
|
94
110
|
it "calulates the cross product" do
|
95
|
-
expect(
|
111
|
+
expect(
|
112
|
+
vector.cross_product(comp)
|
113
|
+
).to eq(Vector2d.cross_product(vector, comp))
|
96
114
|
end
|
97
115
|
end
|
98
116
|
|
99
117
|
describe "#distance" do
|
100
118
|
let(:comp) { Vector2d.new(3, 4) }
|
119
|
+
|
101
120
|
it "returns the distance between two vectors" do
|
102
121
|
expect(vector.distance(comp)).to be_within(0.0001).of(1.4142)
|
103
122
|
end
|
@@ -105,6 +124,7 @@ describe Vector2d::Calculations do
|
|
105
124
|
|
106
125
|
describe "#squared_distance" do
|
107
126
|
let(:comp) { Vector2d.new(5, 6) }
|
127
|
+
|
108
128
|
it "returns the squared distance between two vectors" do
|
109
129
|
expect(vector.squared_distance(comp)).to eq(18)
|
110
130
|
end
|
@@ -112,6 +132,7 @@ describe Vector2d::Calculations do
|
|
112
132
|
|
113
133
|
describe "#dot_product" do
|
114
134
|
let(:comp) { Vector2d.new(3, 4) }
|
135
|
+
|
115
136
|
it "calulates the dot product" do
|
116
137
|
expect(vector.dot_product(comp)).to eq(Vector2d.dot_product(vector, comp))
|
117
138
|
end
|
@@ -119,8 +140,11 @@ describe Vector2d::Calculations do
|
|
119
140
|
|
120
141
|
describe "#angle_between" do
|
121
142
|
let(:comp) { Vector2d.new(3, 4) }
|
143
|
+
|
122
144
|
it "calculates the angle between vectors" do
|
123
|
-
expect(
|
145
|
+
expect(
|
146
|
+
vector.angle_between(comp)
|
147
|
+
).to eq(Vector2d.angle_between(vector, comp))
|
124
148
|
end
|
125
149
|
end
|
126
|
-
end
|
150
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe Vector2d::Coercions do
|
6
6
|
subject(:vector) { Vector2d.new(2, 3) }
|
@@ -18,38 +18,42 @@ describe Vector2d::Coercions do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "#to_f_vector" do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
subject { vector.to_f_vector }
|
22
|
+
|
23
|
+
its(:x) { is_expected.to be_a(Float) }
|
24
|
+
its(:y) { is_expected.to be_a(Float) }
|
25
25
|
end
|
26
26
|
|
27
27
|
describe "#to_hash" do
|
28
28
|
it "returns a hash" do
|
29
|
-
expect(vector.to_hash).to eq(
|
29
|
+
expect(vector.to_hash).to eq(x: 2, y: 3)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
describe "#to_i_vector" do
|
34
|
-
subject
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
subject { vector.to_i_vector }
|
35
|
+
|
36
|
+
let(:vector) { Vector2d.new(2.0, 3.0) }
|
37
|
+
|
38
|
+
its(:x) { is_expected.to be_a(Integer) }
|
39
|
+
its(:y) { is_expected.to be_a(Integer) }
|
39
40
|
end
|
40
41
|
|
41
42
|
describe "#to_s" do
|
42
43
|
context "when fixnum" do
|
43
44
|
subject(:vector) { Vector2d.new(2, 3) }
|
45
|
+
|
44
46
|
it "renders a string" do
|
45
|
-
expect(vector.to_s).to eq(
|
47
|
+
expect(vector.to_s).to eq("2x3")
|
46
48
|
end
|
47
49
|
end
|
50
|
+
|
48
51
|
context "when float" do
|
49
52
|
subject(:vector) { Vector2d.new(2.0, 3.0) }
|
53
|
+
|
50
54
|
it "renders a string" do
|
51
|
-
expect(vector.to_s).to eq(
|
55
|
+
expect(vector.to_s).to eq("2.0x3.0")
|
52
56
|
end
|
53
57
|
end
|
54
58
|
end
|
55
|
-
end
|
59
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe Vector2d::Fitting do
|
6
6
|
let(:original) { Vector2d.new(300, 300) }
|
@@ -10,26 +10,23 @@ describe Vector2d::Fitting do
|
|
10
10
|
|
11
11
|
context "when vector is smaller" do
|
12
12
|
let(:comp) { Vector2d.new(150, 100) }
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
13
|
+
|
14
|
+
its(:x) { is_expected.to eq(150) }
|
15
|
+
its(:y) { is_expected.to eq(100) }
|
17
16
|
end
|
18
17
|
|
19
18
|
context "when vector is wider" do
|
20
19
|
let(:comp) { Vector2d.new(400, 300) }
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
20
|
+
|
21
|
+
its(:x) { is_expected.to eq(300) }
|
22
|
+
its(:y) { is_expected.to eq(225) }
|
25
23
|
end
|
26
24
|
|
27
25
|
context "when vector is higher" do
|
28
26
|
let(:comp) { Vector2d.new(300, 400) }
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
27
|
+
|
28
|
+
its(:x) { is_expected.to eq(225) }
|
29
|
+
its(:y) { is_expected.to eq(300) }
|
33
30
|
end
|
34
31
|
end
|
35
32
|
|
@@ -38,39 +35,36 @@ describe Vector2d::Fitting do
|
|
38
35
|
|
39
36
|
context "when scaling by height" do
|
40
37
|
let(:comp) { Vector2d.new(200, 150) }
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
38
|
+
|
39
|
+
its(:x) { is_expected.to eq(150) }
|
40
|
+
its(:y) { is_expected.to eq(150) }
|
45
41
|
end
|
46
42
|
|
47
43
|
context "when scaling by width" do
|
48
44
|
let(:comp) { Vector2d.new(150, 200) }
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
45
|
+
|
46
|
+
its(:x) { is_expected.to eq(150) }
|
47
|
+
its(:y) { is_expected.to eq(150) }
|
53
48
|
end
|
54
49
|
end
|
55
50
|
|
56
51
|
describe "#fit_either" do
|
57
|
-
let(:original) { Vector2d.new(300, 300) }
|
58
52
|
subject(:vector) { original.fit_either(comp) }
|
59
53
|
|
54
|
+
let(:original) { Vector2d.new(300, 300) }
|
55
|
+
|
60
56
|
context "when width is largest" do
|
61
57
|
let(:comp) { Vector2d.new(200, 150) }
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
58
|
+
|
59
|
+
its(:x) { is_expected.to eq(200) }
|
60
|
+
its(:y) { is_expected.to eq(200) }
|
66
61
|
end
|
67
62
|
|
68
63
|
context "when height is largest" do
|
69
64
|
let(:comp) { Vector2d.new(150, 200) }
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
65
|
+
|
66
|
+
its(:x) { is_expected.to eq(200) }
|
67
|
+
its(:y) { is_expected.to eq(200) }
|
74
68
|
end
|
75
69
|
end
|
76
|
-
end
|
70
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe Vector2d::Properties do
|
6
6
|
subject(:vector) { Vector2d.new(2, 3) }
|
@@ -31,13 +31,17 @@ describe Vector2d::Properties do
|
|
31
31
|
|
32
32
|
describe "#normalized?" do
|
33
33
|
subject { vector.normalized? }
|
34
|
+
|
34
35
|
context "when vector is normalized" do
|
35
36
|
let(:vector) { Vector2d.new(2, 3).normalize }
|
36
|
-
|
37
|
+
|
38
|
+
it { is_expected.to be(true) }
|
37
39
|
end
|
40
|
+
|
38
41
|
context "when vector isn't normalized" do
|
39
42
|
let(:vector) { Vector2d.new(2, 3) }
|
40
|
-
|
43
|
+
|
44
|
+
it { is_expected.to be(false) }
|
41
45
|
end
|
42
46
|
end
|
43
47
|
end
|
@@ -1,12 +1,13 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe Vector2d::Transformations do
|
6
6
|
subject(:vector) { Vector2d.new(2, 3) }
|
7
7
|
|
8
8
|
describe "#ceil" do
|
9
9
|
subject(:vector) { Vector2d.new(2.3, 3.3) }
|
10
|
+
|
10
11
|
it "rounds the vector up" do
|
11
12
|
expect(vector.ceil).to eq(Vector2d.new(3, 4))
|
12
13
|
end
|
@@ -14,16 +15,17 @@ describe Vector2d::Transformations do
|
|
14
15
|
|
15
16
|
describe "#floor" do
|
16
17
|
subject(:vector) { Vector2d.new(2.7, 3.6) }
|
18
|
+
|
17
19
|
it "rounds the vector down" do
|
18
20
|
expect(vector.floor).to eq(Vector2d.new(2, 3))
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
24
|
describe "#normalize" do
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
subject { vector.normalize }
|
26
|
+
|
27
|
+
its(:x) { is_expected.to be_within(0.0001).of(0.5547) }
|
28
|
+
its(:y) { is_expected.to be_within(0.0001).of(0.8320) }
|
27
29
|
end
|
28
30
|
|
29
31
|
describe "#perpendicular" do
|
@@ -34,9 +36,16 @@ describe Vector2d::Transformations do
|
|
34
36
|
|
35
37
|
describe "#resize" do
|
36
38
|
subject(:resized) { vector.resize(2.0) }
|
39
|
+
|
37
40
|
it "modifies the vector length" do
|
38
41
|
expect(resized.length).to be_within(0.0001).of(2.0)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "modifies the x property" do
|
39
45
|
expect(resized.x).to be_within(0.0001).of(1.1094)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "modifies the y property" do
|
40
49
|
expect(resized.y).to be_within(0.0001).of(1.6641)
|
41
50
|
end
|
42
51
|
end
|
@@ -48,37 +57,66 @@ describe Vector2d::Transformations do
|
|
48
57
|
end
|
49
58
|
|
50
59
|
describe "#rotate" do
|
60
|
+
subject { vector.rotate(rotation).round(3) }
|
61
|
+
|
51
62
|
let(:vector) { Vector2d.new(1, 0) }
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
63
|
+
|
64
|
+
context "when roating by PI" do
|
65
|
+
let(:rotation) { Math::PI }
|
66
|
+
|
67
|
+
it { is_expected.to eq(Vector2d.new(-1, 0)) }
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when roating by PI/2" do
|
71
|
+
let(:rotation) { Math::PI / 2 }
|
72
|
+
|
73
|
+
it { is_expected.to eq(Vector2d.new(0, 1)) }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when roating by -PI/2" do
|
77
|
+
let(:rotation) { -Math::PI / 2 }
|
78
|
+
|
79
|
+
it { is_expected.to eq(Vector2d.new(0, -1)) }
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when roating by PI/4" do
|
83
|
+
let(:rotation) { Math::PI / 4 }
|
84
|
+
|
85
|
+
it { is_expected.to eq(Vector2d.new(0.707, 0.707)) }
|
57
86
|
end
|
58
87
|
end
|
59
88
|
|
60
89
|
describe "#round" do
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
90
|
+
let(:vector) { Vector2d.new(2.3333, 3.666) }
|
91
|
+
|
92
|
+
context "without argument" do
|
93
|
+
subject { vector.round }
|
94
|
+
|
95
|
+
it { is_expected.to eq(Vector2d.new(2, 4)) }
|
96
|
+
end
|
97
|
+
|
98
|
+
context "with precision" do
|
99
|
+
subject { vector.round(2) }
|
100
|
+
|
101
|
+
it { is_expected.to eq(Vector2d.new(2.33, 3.67)) }
|
65
102
|
end
|
66
103
|
end
|
67
104
|
|
68
105
|
describe "#truncate" do
|
69
106
|
context "when argument is longer than length" do
|
70
107
|
let(:arg) { 5.0 }
|
108
|
+
|
71
109
|
it "does not change the length" do
|
72
110
|
expect(vector.truncate(arg).length).to be_within(0.0001).of(3.6055)
|
73
111
|
end
|
74
112
|
end
|
113
|
+
|
75
114
|
context "when argument is shorter than length" do
|
76
115
|
let(:arg) { 2.5 }
|
116
|
+
|
77
117
|
it "changes the length" do
|
78
118
|
expect(vector.truncate(arg).length).to be_within(0.0001).of(arg)
|
79
119
|
end
|
80
120
|
end
|
81
121
|
end
|
82
|
-
|
83
|
-
|
84
|
-
end
|
122
|
+
end
|