Module: Vector2d::Lengths
- Included in:
- Vector2d
- Defined in:
- lib/vector2d/lengths.rb
Overview
The length of a vector, the distance between two, and the operations that change the length while keeping the direction.
Instance Method Summary collapse
-
#approx_zero?(tolerance = nil) ⇒ Boolean
Is this the zero vector, give or take floating point drift? See #approx_equal? for what the tolerance is.
-
#chebyshev_distance(other) ⇒ Integer, ...
Calculates the Chebyshev distance between two vectors, the largest absolute difference along any axis.
-
#clamp_length(min, max = nil) ⇒ self
Clamps the length of the vector between a minimum and a maximum, scaling it up if it is shorter than min and down if it is longer than max.
-
#direction_to(other) ⇒ self
Unit vector pointing from this vector to another vector, the direction a step from here to there would take.
-
#distance(other) ⇒ Float
Calculates the distance between two vectors.
-
#distance_squared(other) ⇒ Integer, ...
Calculate squared distance between vectors.
-
#length ⇒ Float
(also: #magnitude, #norm)
Length of vector.
-
#length_squared ⇒ Integer, ...
Squared length of vector.
-
#limit_length(max) ⇒ self
Limits the length of the vector, scaling it down if it is longer than max.
-
#manhattan_distance(other) ⇒ Integer, ...
Calculates the Manhattan distance between two vectors, the sum of the absolute differences along each axis.
-
#normalize ⇒ self
Normalizes the vector.
-
#normalized? ⇒ Boolean
Is this a normalized vector?.
-
#resize(new_length) ⇒ self
Changes magnitude of vector.
-
#squared_distance(other) ⇒ Integer, ...
deprecated
Deprecated.
Use #distance_squared instead.
-
#squared_length ⇒ Integer, ...
deprecated
Deprecated.
Use #length_squared instead.
-
#zero? ⇒ Boolean
Is this the zero vector?.
Instance Method Details
#approx_zero?(tolerance = nil) ⇒ Boolean
Is this the zero vector, give or take floating point drift? See #approx_equal? for what the tolerance is.
Vector2d(0, 0).approx_zero? # => true
Vector2d(1e-17, 0).approx_zero? # => true
Vector2d(1e-15, 0).approx_zero? # => false
An explicit tolerance is an absolute length.
Vector2d(0.2, 0).approx_zero?(0.5) # => true
60 61 62 63 64 |
# File 'lib/vector2d/lengths.rb', line 60 def approx_zero?(tolerance = nil) return length <= coordinate(tolerance) unless tolerance.nil? near_zero?(length) end |
#chebyshev_distance(other) ⇒ Integer, ...
233 234 235 |
# File 'lib/vector2d/lengths.rb', line 233 def chebyshev_distance(other) (self - other).abs.to_a.max end |
#clamp_length(min, max) ⇒ self #clamp_length(range) ⇒ self
Clamps the length of the vector between a minimum and a maximum, scaling it up if it is shorter than min and down if it is longer than max. The direction is kept.
vector = Vector2d(2.0, 3.0)
vector.clamp_length(5.0, 10.0) # => Vector2d(2.7735.., 4.1602..)
vector.clamp_length(1.0, 10.0) # => Vector2d(2.0, 3.0)
The bounds can also be given as a single range, which may be beginless or endless to clamp only one side, as in #clamp.
vector.clamp_length(5.0..10.0) # => Vector2d(2.7735.., 4.1602..)
vector.clamp_length(..1.0) # => Vector2d(0.5547.., 0.8320..)
vector.clamp_length(5.0..) # => Vector2d(2.7735.., 4.1602..)
A maximum on its own is #limit_length.
The range must not exclude its end, as with Comparable#clamp.
vector.clamp_length(5.0...10.0) # => ArgumentError
The zero vector has no direction, and is returned unchanged. It can't be scaled up to a minimum length.
Vector2d(0, 0).clamp_length(1.0, 2.0) # => Vector2d(0,0)
Lengths can't be negative, and min can't exceed max.
Vector2d(2, 3).clamp_length(-1.0, 1.0) # => ArgumentError
Vector2d(2, 3).clamp_length(4.0, 2.0) # => ArgumentError
172 173 174 175 |
# File 'lib/vector2d/lengths.rb', line 172 def clamp_length(min, max = nil) min_length, max_length = clamp_length_bounds(min, max) resize(length.clamp(Range.new(min_length, max_length))) end |
#direction_to(other) ⇒ self
Unit vector pointing from this vector to another vector, the direction a step from here to there would take. The other vector is coerced, so scalars work too.
v1 = Vector2d(2, 3)
v1.direction_to(Vector2d(2, 6)) # => Vector2d(0.0,1.0)
v1.direction_to(Vector2d(5, 7)) # => Vector2d(0.6000..,0.8)
This is (other - self).normalize. #distance measures the same step, and #move_toward takes it.
There is no direction to where you already are. The zero vector has no direction, and is returned.
v1.direction_to(v1) # => Vector2d(0,0)
255 256 257 258 |
# File 'lib/vector2d/lengths.rb', line 255 def direction_to(other) v = coerce_vector(other) build(v.x - x, v.y - y).normalize end |
#distance(other) ⇒ Float
185 186 187 |
# File 'lib/vector2d/lengths.rb', line 185 def distance(other) (self - other).length end |
#distance_squared(other) ⇒ Integer, ...
198 199 200 |
# File 'lib/vector2d/lengths.rb', line 198 def distance_squared(other) (self - other).length_squared end |
#length ⇒ Float Also known as: magnitude, norm
Length of vector.
Vector2d(2, 3).length # => 3.6055..
12 13 14 |
# File 'lib/vector2d/lengths.rb', line 12 def length Math.sqrt(length_squared) end |
#length_squared ⇒ Integer, ...
Squared length of vector. Avoids the square root when lengths are only being compared to each other.
Vector2d(2, 3).length_squared # => 13
24 25 26 |
# File 'lib/vector2d/lengths.rb', line 24 def length_squared (x * x) + (y * y) end |
#limit_length(max) ⇒ self
Limits the length of the vector, scaling it down if it is longer than max. The direction is kept.
vector = Vector2d(2.0, 3.0)
vector.limit_length(5.0) # => Vector2d(2.0, 3.0)
vector.limit_length(1.0) # => Vector2d(0.5547.., 0.8320..)
#clamp_length bounds the length at both ends.
The zero vector has no direction, and is returned unchanged.
Vector2d(0, 0).limit_length(1.0) # => Vector2d(0,0)
Lengths can't be negative.
Vector2d(2, 3).limit_length(-1.0) # => ArgumentError
131 132 133 |
# File 'lib/vector2d/lengths.rb', line 131 def limit_length(max) resize(length.clamp(..length_bound(max, "max"))) end |
#manhattan_distance(other) ⇒ Integer, ...
220 221 222 |
# File 'lib/vector2d/lengths.rb', line 220 def manhattan_distance(other) (self - other).abs.to_a.sum end |
#normalize ⇒ self
87 88 89 |
# File 'lib/vector2d/lengths.rb', line 87 def normalize resize(1.0) end |
#normalized? ⇒ Boolean
72 73 74 |
# File 'lib/vector2d/lengths.rb', line 72 def normalized? near_zero?(length - 1.0) end |
#resize(new_length) ⇒ self
105 106 107 108 109 110 |
# File 'lib/vector2d/lengths.rb', line 105 def resize(new_length) new_length = coordinate(new_length) return self if zero? self * (new_length / length) end |
#squared_distance(other) ⇒ Integer, ...
Use #distance_squared instead.
206 207 208 209 |
# File 'lib/vector2d/lengths.rb', line 206 def squared_distance(other) warn_deprecated("Vector2d#squared_distance is deprecated. Use #distance_squared instead.") distance_squared(other) end |
#squared_length ⇒ Integer, ...
Use #length_squared instead.
31 32 33 34 |
# File 'lib/vector2d/lengths.rb', line 31 def squared_length warn_deprecated("Vector2d#squared_length is deprecated. Use #length_squared instead.") length_squared end |