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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7dbfd81a3fed2f7614e10055078fdbdd37755693
4
- data.tar.gz: e3e0f41142cba937a0eba3a16b94a33ebd8d3a7e
2
+ SHA256:
3
+ metadata.gz: fc16e15dbb07e3fe138a13fdc3cc8edd6c1369e53bf337a47b8034359b826fa2
4
+ data.tar.gz: b4077e6730cd248749960253a22b78a89a9f876ebfd5ca4a097d42c44c246aa7
5
5
  SHA512:
6
- metadata.gz: 526d578d2c1ca5b1c47c7e5552b0fd7493188ac58bf80a21768d5c2e0ce42baab3bbbd22e256c16561f30546c8cdf3aa46426857713da6494c27809171e3cedb
7
- data.tar.gz: 5a139955b82cee23628966909c1dd8d12e46e7e8bafc539c48c9339e57fddc43bdf1712345f1576b5998a103a44df4fc1b220ace19b1b96cf8498b18ff776a87
6
+ metadata.gz: a93da54adf875ed88cc5f2fc7ab31a8f919d8352ddf2ee7259290ac2ed0a160b8edbf178f40788fd0e1f57c1c125877a20b6f3bbc3f8320d3929efb64da6862c
7
+ data.tar.gz: d1ed6fab76e6c0cd4c74104ed997927fb377dad0fd75790f576777392fc73d235b5e828a73b2d7c3bc2b00c54246c21a48fc36539f00870eb23c07767a80b477
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: Build
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - develop
8
+ pull_request:
9
+ jobs:
10
+ rubocop-test:
11
+ name: Rubocop
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v1
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: 3.2
18
+ bundler-cache: true
19
+ - name: Check code
20
+ run: bundle exec rubocop
21
+
22
+ rspec-test:
23
+ name: RSpec
24
+ runs-on: ubuntu-latest
25
+ strategy:
26
+ matrix:
27
+ ruby: ['2.7', '3.0', '3.1', '3.2']
28
+ steps:
29
+ - uses: actions/checkout@v1
30
+ - uses: ruby/setup-ruby@v1
31
+ with:
32
+ ruby-version: ${{ matrix.ruby }}
33
+ bundler-cache: true
34
+ - name: Run tests
35
+ run: bundle exec rspec
36
+ - name: Send results to Code Climate
37
+ uses: paambaati/codeclimate-action@v3.2.0
38
+ env:
39
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
40
+ with:
41
+ coverageCommand: ls
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
+ coverage
1
2
  rdoc
2
3
  pkg
data/.rubocop.yml ADDED
@@ -0,0 +1,26 @@
1
+ require:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ NewCops: enable
7
+ TargetRubyVersion: 2.7
8
+
9
+ Style/StringLiterals:
10
+ EnforcedStyle: double_quotes
11
+
12
+ Style/Documentation:
13
+ Enabled: false
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - "*.gemspec"
18
+ - "**/*_spec.rb"
19
+
20
+ Naming/MethodName:
21
+ Enabled: false
22
+
23
+ Naming/MethodParameterName:
24
+ AllowedNames:
25
+ - "x"
26
+ - "y"
data/.travis.yml CHANGED
@@ -1,11 +1,10 @@
1
- addons:
2
- code_climate:
3
- repo_token: bf65d5faaf8dc80d0d58f2e7c663323734237c0a3e91cba16b1c556a98b0971e
4
1
  language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ dist: bionic
5
5
  rvm:
6
- - 1.9.3
7
- - 2.0.0
8
- - 2.1.2
9
- - 2.2.2
6
+ - 2.4.5
7
+ - 2.6.3
8
+ - 2.7.1
10
9
  script:
11
10
  - bundle exec rspec spec
data/Gemfile CHANGED
@@ -1,7 +1,15 @@
1
- source "http://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
2
4
 
3
5
  gemspec
4
6
 
5
- group :test do
6
- gem "codeclimate-test-reporter", require: false
7
- end
7
+ group :development, :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.8"
10
+ gem "rspec-its", "~> 1.3"
11
+ gem "rubocop", require: false
12
+ gem "rubocop-rake", require: false
13
+ gem "rubocop-rspec", require: false
14
+ gem "simplecov", "~> 0.17.1"
15
+ end
data/Gemfile.lock CHANGED
@@ -1,43 +1,77 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vector2d (2.2.3)
5
- contracts (~> 0.9.0)
4
+ vector2d (2.2.4)
6
5
 
7
6
  GEM
8
- remote: http://rubygems.org/
7
+ remote: https://rubygems.org/
9
8
  specs:
10
- codeclimate-test-reporter (0.4.7)
11
- simplecov (>= 0.7.1, < 1.0.0)
12
- contracts (0.9)
13
- diff-lcs (1.2.5)
14
- docile (1.1.5)
15
- json (1.8.3)
16
- rake (10.4.2)
17
- rspec (3.3.0)
18
- rspec-core (~> 3.3.0)
19
- rspec-expectations (~> 3.3.0)
20
- rspec-mocks (~> 3.3.0)
21
- rspec-core (3.3.2)
22
- rspec-support (~> 3.3.0)
23
- rspec-expectations (3.3.1)
9
+ ast (2.4.2)
10
+ diff-lcs (1.5.0)
11
+ docile (1.4.0)
12
+ json (2.6.3)
13
+ parallel (1.22.1)
14
+ parser (3.2.0.0)
15
+ ast (~> 2.4.1)
16
+ rainbow (3.1.1)
17
+ rake (13.0.6)
18
+ regexp_parser (2.6.2)
19
+ rexml (3.2.5)
20
+ rspec (3.12.0)
21
+ rspec-core (~> 3.12.0)
22
+ rspec-expectations (~> 3.12.0)
23
+ rspec-mocks (~> 3.12.0)
24
+ rspec-core (3.12.1)
25
+ rspec-support (~> 3.12.0)
26
+ rspec-expectations (3.12.2)
24
27
  diff-lcs (>= 1.2.0, < 2.0)
25
- rspec-support (~> 3.3.0)
26
- rspec-mocks (3.3.2)
28
+ rspec-support (~> 3.12.0)
29
+ rspec-its (1.3.0)
30
+ rspec-core (>= 3.0.0)
31
+ rspec-expectations (>= 3.0.0)
32
+ rspec-mocks (3.12.3)
27
33
  diff-lcs (>= 1.2.0, < 2.0)
28
- rspec-support (~> 3.3.0)
29
- rspec-support (3.3.0)
30
- simplecov (0.10.0)
31
- docile (~> 1.1.0)
32
- json (~> 1.8)
34
+ rspec-support (~> 3.12.0)
35
+ rspec-support (3.12.0)
36
+ rubocop (1.44.1)
37
+ json (~> 2.3)
38
+ parallel (~> 1.10)
39
+ parser (>= 3.2.0.0)
40
+ rainbow (>= 2.2.2, < 4.0)
41
+ regexp_parser (>= 1.8, < 3.0)
42
+ rexml (>= 3.2.5, < 4.0)
43
+ rubocop-ast (>= 1.24.1, < 2.0)
44
+ ruby-progressbar (~> 1.7)
45
+ unicode-display_width (>= 2.4.0, < 3.0)
46
+ rubocop-ast (1.24.1)
47
+ parser (>= 3.1.1.0)
48
+ rubocop-capybara (2.17.0)
49
+ rubocop (~> 1.41)
50
+ rubocop-rake (0.6.0)
51
+ rubocop (~> 1.0)
52
+ rubocop-rspec (2.18.1)
53
+ rubocop (~> 1.33)
54
+ rubocop-capybara (~> 2.17)
55
+ ruby-progressbar (1.11.0)
56
+ simplecov (0.17.1)
57
+ docile (~> 1.1)
58
+ json (>= 1.8, < 3)
33
59
  simplecov-html (~> 0.10.0)
34
- simplecov-html (0.10.0)
60
+ simplecov-html (0.10.2)
61
+ unicode-display_width (2.4.2)
35
62
 
36
63
  PLATFORMS
37
64
  ruby
38
65
 
39
66
  DEPENDENCIES
40
- codeclimate-test-reporter
41
- rake (~> 10.3)
42
- rspec (~> 3.2)
67
+ rake
68
+ rspec (~> 3.8)
69
+ rspec-its (~> 1.3)
70
+ rubocop
71
+ rubocop-rake
72
+ rubocop-rspec
73
+ simplecov (~> 0.17.1)
43
74
  vector2d!
75
+
76
+ BUNDLED WITH
77
+ 2.2.3
data/README.md CHANGED
@@ -1,4 +1,9 @@
1
- # Vector2d [![Build Status](https://travis-ci.org/elektronaut/vector2d.png)](https://travis-ci.org/elektronaut/vector2d) [![Code Climate](https://codeclimate.com/github/elektronaut/vector2d.png)](https://codeclimate.com/github/elektronaut/vector2d) [![Code Climate](https://codeclimate.com/github/elektronaut/vector2d/coverage.png)](https://codeclimate.com/github/elektronaut/vector2d)
1
+ [![Version](https://img.shields.io/gem/v/vector2d.svg?style=flat)](https://rubygems.org/gems/vector2d)
2
+ ![Build](https://github.com/elektronaut/vector2d/workflows/Build/badge.svg)
3
+ [![Code Climate](https://codeclimate.com/github/elektronaut/vector2d/badges/gpa.svg)](https://codeclimate.com/github/elektronaut/vector2d)
4
+ [![Code Climate](https://codeclimate.com/github/elektronaut/vector2d/badges/coverage.svg)](https://codeclimate.com/github/elektronaut/vector2d)
5
+
6
+ # Vector2d
2
7
 
3
8
  Vector2d handles two-dimensional coordinates and vectors.
4
9
  Vectors are immutable, meaning this is a purely functional library.
@@ -24,10 +29,10 @@ Vector2d.parse("50x70") # => Vector2d(50,70)
24
29
 
25
30
  ## Documentation
26
31
 
27
- [API documentation](http://rdoc.info/github/elektronaut/vector2d)
32
+ [API documentation](https://rdoc.info/github/elektronaut/vector2d/main)
28
33
 
29
34
  ## License
30
35
 
31
- Copyright (c) 2006-2014 Inge Jørgensen
36
+ Copyright (c) 2006-2019 Inge Jørgensen
32
37
 
33
- Vector2d is released under the [MIT License](http://www.opensource.org/licenses/MIT).
38
+ Vector2d is released under the [MIT License](http://www.opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
4
6
  RSpec::Core::RakeTask.new
5
7
 
6
- task :default => :spec
7
- task :test => :spec
8
+ task default: :spec
9
+
10
+ desc "Run tests"
11
+ task test: :spec
@@ -1,21 +1,16 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Calculations
5
- include Contracts
6
-
7
5
  module ClassMethods
8
- include Contracts
9
-
10
6
  # Calculates cross product of two vectors.
11
7
  #
12
8
  # v1 = Vector2d(2, 1)
13
9
  # v2 = Vector2d(2, 3)
14
10
  # Vector2d.cross_product(v1, v2) # => 4
15
11
  #
16
- Contract Vector2d, Vector2d => Num
17
12
  def cross_product(vector1, vector2)
18
- vector1.x * vector2.y - vector1.y * vector2.x
13
+ (vector1.x * vector2.y) - (vector1.y * vector2.x)
19
14
  end
20
15
 
21
16
  # Calculates dot product of two vectors.
@@ -24,9 +19,8 @@ class Vector2d
24
19
  # v2 = Vector2d(2, 3)
25
20
  # Vector2d.dot_product(v1, v2) # => 10
26
21
  #
27
- Contract Vector2d, Vector2d => Num
28
22
  def dot_product(vector1, vector2)
29
- vector1.x * vector2.x + vector1.y * vector2.y
23
+ (vector1.x * vector2.x) + (vector1.y * vector2.y)
30
24
  end
31
25
 
32
26
  # Calculates angle between two vectors in radians.
@@ -35,11 +29,10 @@ class Vector2d
35
29
  # v2 = Vector2d(4, 5)
36
30
  # Vector2d.angle_between(v1, v2) # => 0.0867..
37
31
  #
38
- Contract Vector2d, Vector2d => Num
39
32
  def angle_between(vector1, vector2)
40
33
  one = vector1.normalized? ? vector1 : vector1.normalize
41
34
  two = vector2.normalized? ? vector2 : vector2.normalize
42
- Math.acos(self.dot_product(one, two))
35
+ Math.acos(dot_product(one, two))
43
36
  end
44
37
  end
45
38
 
@@ -48,7 +41,6 @@ class Vector2d
48
41
  # Vector2d(1, 2) * Vector2d(2, 3) # => Vector2d(2, 6)
49
42
  # Vector2d(1, 2) * 2 # => Vector2d(2, 4)
50
43
  #
51
- Contract VectorLike => Vector2d
52
44
  def *(other)
53
45
  calculate_each(:*, other)
54
46
  end
@@ -58,7 +50,6 @@ class Vector2d
58
50
  # Vector2d(4, 2) / Vector2d(2, 1) # => Vector2d(2, 2)
59
51
  # Vector2d(4, 2) / 2 # => Vector2d(2, 1)
60
52
  #
61
- Contract VectorLike => Vector2d
62
53
  def /(other)
63
54
  calculate_each(:/, other)
64
55
  end
@@ -68,7 +59,6 @@ class Vector2d
68
59
  # Vector2d(1, 2) + Vector2d(2, 3) # => Vector2d(3, 5)
69
60
  # Vector2d(1, 2) + 2 # => Vector2d(3, 4)
70
61
  #
71
- Contract VectorLike => Vector2d
72
62
  def +(other)
73
63
  calculate_each(:+, other)
74
64
  end
@@ -78,7 +68,6 @@ class Vector2d
78
68
  # Vector2d(2, 3) - Vector2d(2, 1) # => Vector2d(0, 2)
79
69
  # Vector2d(4, 3) - 1 # => Vector2d(3, 2)
80
70
  #
81
- Contract VectorLike => Vector2d
82
71
  def -(other)
83
72
  calculate_each(:-, other)
84
73
  end
@@ -89,7 +78,6 @@ class Vector2d
89
78
  # v2 = Vector2d(5, 6)
90
79
  # v1.distance(v2) # => 1.4142..
91
80
  #
92
- Contract VectorLike => Num
93
81
  def distance(other)
94
82
  Math.sqrt(squared_distance(other))
95
83
  end
@@ -100,12 +88,11 @@ class Vector2d
100
88
  # v2 = Vector2d(5, 6)
101
89
  # v1.distance_squared(v2) # => 18
102
90
  #
103
- Contract VectorLike => Num
104
91
  def squared_distance(other)
105
- v, _ = coerce(other)
92
+ v, = coerce(other)
106
93
  dx = v.x - x
107
94
  dy = v.y - y
108
- dx * dx + dy * dy
95
+ (dx * dx) + (dy * dy)
109
96
  end
110
97
 
111
98
  # Dot product of this vector and another vector.
@@ -114,9 +101,8 @@ class Vector2d
114
101
  # v2 = Vector2d(2, 3)
115
102
  # v1.dot_product(v2) # => 10
116
103
  #
117
- Contract VectorLike => Num
118
104
  def dot_product(other)
119
- v, _ = coerce(other)
105
+ v, = coerce(other)
120
106
  self.class.dot_product(self, v)
121
107
  end
122
108
 
@@ -126,9 +112,8 @@ class Vector2d
126
112
  # v2 = Vector2d(2, 3)
127
113
  # v1.cross_product(v2) # => 4
128
114
  #
129
- Contract VectorLike => Num
130
115
  def cross_product(other)
131
- v, _ = coerce(other)
116
+ v, = coerce(other)
132
117
  self.class.cross_product(self, v)
133
118
  end
134
119
 
@@ -138,16 +123,15 @@ class Vector2d
138
123
  # v2 = Vector2d(4, 5)
139
124
  # v1.angle_between(v2) # => 0.0867..
140
125
  #
141
- Contract VectorLike => Num
142
126
  def angle_between(other)
143
- v, _ = coerce(other)
127
+ v, = coerce(other)
144
128
  self.class.angle_between(self, v)
145
129
  end
146
130
 
147
131
  private
148
132
 
149
133
  def calculate_each(method, other)
150
- v, _ = coerce(other)
134
+ v, = coerce(other)
151
135
  self.class.new(
152
136
  x.send(method, v.x),
153
137
  y.send(method, v.y)
@@ -1,10 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Coercions
5
- include Contracts
6
-
7
- Contract VectorLike => [Vector2d, Vector2d]
8
5
  def coerce(other)
9
6
  case other
10
7
  when Vector2d
@@ -20,7 +17,6 @@ class Vector2d
20
17
  #
21
18
  # Vector2d(2, 3).inspect # => "Vector2d(2,3)"
22
19
  #
23
- Contract None => String
24
20
  def inspect
25
21
  "Vector2d(#{x},#{y})"
26
22
  end
@@ -29,7 +25,6 @@ class Vector2d
29
25
  #
30
26
  # Vector2d(2, 3).to_a # => [2,3]
31
27
  #
32
- Contract None => [Num, Num]
33
28
  def to_a
34
29
  [x, y]
35
30
  end
@@ -38,7 +33,6 @@ class Vector2d
38
33
  #
39
34
  # Vector2d(2, 3).to_hash # => {x: 2, y: 3}
40
35
  #
41
- Contract None => Hash
42
36
  def to_hash
43
37
  { x: x, y: y }
44
38
  end
@@ -47,7 +41,6 @@ class Vector2d
47
41
  #
48
42
  # Vector2d(2.0, 3.0).to_i_vector # => Vector2d(2,3)
49
43
  #
50
- Contract None => Vector2d
51
44
  def to_i_vector
52
45
  self.class.new(x.to_i, y.to_i)
53
46
  end
@@ -56,7 +49,6 @@ class Vector2d
56
49
  #
57
50
  # Vector2d(2, 3).to_f_vector # => Vector2d(2.0,3.0)
58
51
  #
59
- Contract None => Vector2d
60
52
  def to_f_vector
61
53
  self.class.new(x.to_f, y.to_f)
62
54
  end
@@ -65,7 +57,6 @@ class Vector2d
65
57
  #
66
58
  # Vector2d.new(150, 100).to_s # => "150x100"
67
59
  #
68
- Contract None => String
69
60
  def to_s
70
61
  "#{x}x#{y}"
71
62
  end
@@ -1,9 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Fitting
5
- include Contracts
6
-
7
5
  # Scales down the given vector unless it fits inside.
8
6
  #
9
7
  # vector = Vector2d(20, 20)
@@ -11,46 +9,52 @@ class Vector2d
11
9
  # vector.contain(Vector2d(40, 20)) # => Vector2d(20,10)
12
10
  # vector.contain(Vector2d(20, 40)) # => Vector2d(10,20)
13
11
  #
14
- Contract VectorLike => Vector2d
15
12
  def contain(other)
16
- v, _ = coerce(other)
17
- (v.x > x || v.y > y) ? other.fit(self) : other
13
+ v, = coerce(other)
14
+ v.x > x || v.y > y ? other.fit(self) : other
18
15
  end
19
16
 
20
- # Scales the vector to fit inside another vector, retaining the aspect ratio.
17
+ # Scales the vector to fit inside another vector, retaining the
18
+ # aspect ratio.
21
19
  #
22
20
  # vector = Vector2d(20, 10)
23
21
  # vector.fit(Vector2d(10, 10)) # => Vector2d(10,5)
24
22
  # vector.fit(Vector2d(20, 20)) # => Vector2d(20,10)
25
23
  # vector.fit(Vector2d(40, 40)) # => Vector2d(40,20)
26
24
  #
27
- # Note: Either axis will be disregarded if zero or nil. This is a feature, not a bug.
25
+ # Note: Either axis will be disregarded if zero or nil. This is a
26
+ # feature, not a bug.
28
27
  #
29
- Contract VectorLike => Vector2d
30
28
  def fit(other)
31
- v, _ = coerce(other)
29
+ v, = coerce(other)
32
30
  scale = v.to_f_vector / self
33
- self * ((scale.y == 0 || (scale.x > 0 && scale.x < scale.y)) ? scale.x : scale.y)
31
+ self * (
32
+ if scale.y.zero? || (scale.x.positive? && scale.x < scale.y)
33
+ scale.x
34
+ else
35
+ scale.y
36
+ end
37
+ )
34
38
  end
35
- alias_method :constrain_both, :fit
39
+ alias constrain_both fit
36
40
 
37
- # Constrain/expand so that one of the coordinates fit within (the square implied by) another vector.
41
+ # Constrain/expand so that one of the coordinates fit within (the
42
+ # square implied by) another vector.
38
43
  #
39
44
  # constraint = Vector2d(5, 5)
40
45
  # Vector2d(20, 10).fit_either(constraint) # => Vector2d(10,5)
41
46
  # Vector2d(10, 20).fit_either(constraint) # => Vector2d(5,10)
42
47
  #
43
- Contract VectorLike => Vector2d
44
48
  def fit_either(other)
45
- v, _ = coerce(other)
49
+ v, = coerce(other)
46
50
  scale = v.to_f_vector / self
47
- if (scale.x > 0 && scale.y > 0)
48
- scale = (scale.x < scale.y) ? scale.y : scale.x
51
+ if scale.x.positive? && scale.y.positive?
52
+ scale = [scale.x, scale.y].max
49
53
  self * scale
50
54
  else
51
55
  fit(v)
52
56
  end
53
57
  end
54
- alias_method :constrain_one, :fit_either
58
+ alias constrain_one fit_either
55
59
  end
56
60
  end
@@ -1,14 +1,11 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Vector2d
4
4
  module Properties
5
- include Contracts
6
-
7
5
  # Angle of vector.
8
6
  #
9
7
  # Vector2d(2, 3).angle # => 0.9827..
10
8
  #
11
- Contract None => Num
12
9
  def angle
13
10
  Math.atan2(y, x)
14
11
  end
@@ -17,16 +14,14 @@ class Vector2d
17
14
  #
18
15
  # Vector2d(2, 3).aspect_ratio # => 0.6667..
19
16
  #
20
- Contract None => Num
21
17
  def aspect_ratio
22
- (x.to_f / y.to_f).abs
18
+ (x.to_f / y).abs
23
19
  end
24
20
 
25
21
  # Length of vector.
26
22
  #
27
23
  # Vector2d(2, 3).length # => 3.6055..
28
24
  #
29
- Contract None => Num
30
25
  def length
31
26
  Math.sqrt(squared_length)
32
27
  end
@@ -35,9 +30,8 @@ class Vector2d
35
30
  #
36
31
  # Vector2d(2, 3).squared_length # => 13
37
32
  #
38
- Contract None => Num
39
33
  def squared_length
40
- x * x + y * y
34
+ (x * x) + (y * y)
41
35
  end
42
36
 
43
37
  # Is this a normalized vector?
@@ -45,9 +39,8 @@ class Vector2d
45
39
  # Vector2d(0, 1).normalized? # => true
46
40
  # Vector2d(2, 3).normalized? # => false
47
41
  #
48
- Contract None => Bool
49
42
  def normalized?
50
- self.length.to_f == 1.0
43
+ (length.to_f - 1.0).abs < Float::EPSILON
51
44
  end
52
45
  end
53
46
  end