Class: Math2D::Vector2D
- Inherits:
-
Object
- Object
- Math2D::Vector2D
- Defined in:
- lib/math2d/vector2d.rb
Overview
MOST methods return a NEW Vector2D instead of changing self and returning it, so be careful.
Vector2D
-
An implementation of various 2-dimensional vector methods.
Instance Attribute Summary collapse
-
#x ⇒ Numeric
The x coordinate of the Vector.
-
#y ⇒ Numeric
The y coordinate of the Vector.
Class Method Summary collapse
-
.down ⇒ Vector2D
Shorthand for writing Vector2D.new(0, 1).
-
.from_angle(theta, len = 1) ⇒ Vector2D
Returns a new Vector2D from a given angle
thetawith lengthlen. -
.left ⇒ Vector2D
Shorthand for writing Vector2D.new(-1, 0).
-
.one ⇒ Vector2D
Shorthand for writing Vector2D.new(1, 1).
-
.random ⇒ Vector2D
Returns a new Vector2D with random components but magnitude equal to 1.
-
.right ⇒ Vector2D
Shorthand for writing Vector2D.new(1, 0).
-
.to_vector(arr) ⇒ Vector2D
Returns a new Vector2D from an array
arr. -
.up ⇒ Vector2D
Shorthand for writing Vector2D.new(0, -1).
-
.zero ⇒ Vector2D
Shorthand for writing Vector2D.new(0, 0).
Instance Method Summary collapse
-
#*(other) ⇒ Vector2D
Multiplies
selfby another vector or by a scalar. -
#+(other) ⇒ Vector2D
Adds
selfto another vector or to a scalar. -
#-(other) ⇒ Vector2D
Subtracts
selfto another vector or to a scalar. -
#-@ ⇒ Vector2D
(also: #negate)
Negates both x and y values of
selfand returns a new Vector2D. -
#/(other) ⇒ Vector2D
Divides
selfby another vector or by a scalar. -
#==(other) ⇒ Boolean
Compares
selfandotheraccording to their components. -
#angle_between(other) ⇒ Float
Returns the angle between
selfandotherin radians. -
#constrain(a, b) ⇒ Vector2D
(also: #clamp)
Constrains the magnitude of
selfbetween a minimum valueaand maximum valueb. -
#cross(other) ⇒ Numeric
(also: #wedge)
Calculates the “cross product” (see note) between
selfandother, where: A^B (A wedge B) = (Ax * By) - (Bx * Ay). -
#distance(other) ⇒ Float
Returns the Euclidean distance between
selfandother. -
#dot(other) ⇒ Numeric
Calculates the dot product between
selfandother, where: A.B (A dot B) = (Ax * Bx) + (Ay * By). -
#heading ⇒ Float
Returns the x-heading angle of
selfin radians. -
#initialize(x = 0, y = 0) ⇒ Vector2D
constructor
Creates a new vector (x, y).
-
#inverse_lerp(other, value) ⇒ Vector2D
Calculates the parameter t of the
#lerpmethod betweenselfandothergiven an interpolantvalue. -
#lerp(other, amt) ⇒ Vector2D
Linear interpolate
selfandotherwith an amountamt. -
#limit(max) ⇒ Vector2D
Limit the magnitude of
selftomaxand returns a new vector. -
#magnitude ⇒ Float
(also: #length)
Returns the magnitude of
self. -
#normalize ⇒ Vector2D
(also: #unit)
Normalizes
self(set the magnitude to 1). -
#normalized? ⇒ Boolean
(also: #unit?)
Returns true if the magnitude of
selfis equal to 1, false otherwise. -
#opposite?(other) ⇒ Boolean
Checks if
selfis facing the opposite direction ofother. -
#ratio ⇒ Float
Returns the ratio (x / y) of
self. -
#reflect(other) ⇒ Vector2D
Reflects
selfand returns it as a new Vector2D. -
#refract(other, refractive_index) ⇒ Vector2D
Refracts
selfand returns it as a new Vector2D. -
#rotate(angle) ⇒ Vector2D
Clockwise rotates
selfangleradians and returns it as a new Vector2D. -
#rotate_around(pivot, angle) ⇒ Vector2D
Clockwise rotates
selfangleradians around apivotpoint and returns it as a new Vector2D. -
#set(x = self.x, y = self.y) ⇒ Vector2D
Sets the
xandycomponents of the vector. -
#set_magnitude(new_mag) ⇒ Vector2D
Sets the magnitude of
selftonew_mag. -
#squared ⇒ Numeric
Returns the magnitude squared of
self. -
#to_a ⇒ Array<Numeric>
Converts
selfto an array. -
#to_s ⇒ String
Converts
selfto a string. -
#y_heading ⇒ Float
Returns the y-heading angle of
selfin radians.
Constructor Details
#initialize(x = 0, y = 0) ⇒ Vector2D
Creates a new vector (x, y).
20 21 22 23 |
# File 'lib/math2d/vector2d.rb', line 20 def initialize(x = 0, y = 0) @x = x @y = y end |
Instance Attribute Details
#x ⇒ Numeric
The x coordinate of the Vector
12 13 14 |
# File 'lib/math2d/vector2d.rb', line 12 def x @x end |
#y ⇒ Numeric
The y coordinate of the Vector
12 13 14 |
# File 'lib/math2d/vector2d.rb', line 12 def y @y end |
Class Method Details
.down ⇒ Vector2D
Shorthand for writing Vector2D.new(0, 1).
63 64 65 |
# File 'lib/math2d/vector2d.rb', line 63 def self.down Vector2D.new(0, 1) end |
.from_angle(theta, len = 1) ⇒ Vector2D
Returns a new Vector2D from a given angle theta with length len.
278 279 280 |
# File 'lib/math2d/vector2d.rb', line 278 def self.from_angle(theta, len = 1) Vector2D.new(len * Math.cos(theta), len * Math.sin(theta)) end |
.left ⇒ Vector2D
Shorthand for writing Vector2D.new(-1, 0).
70 71 72 |
# File 'lib/math2d/vector2d.rb', line 70 def self.left Vector2D.new(-1, 0) end |
.one ⇒ Vector2D
Shorthand for writing Vector2D.new(1, 1).
48 49 50 |
# File 'lib/math2d/vector2d.rb', line 48 def self.one Vector2D.new(1, 1) end |
.random ⇒ Vector2D
Returns a new Vector2D with random components but magnitude equal to 1.
373 374 375 376 |
# File 'lib/math2d/vector2d.rb', line 373 def self.random theta = rand(-Utils2D::TWO_PI..Utils2D::TWO_PI) Vector2D.new(Math.cos(theta), Math.sin(theta)) end |
.right ⇒ Vector2D
Shorthand for writing Vector2D.new(1, 0).
77 78 79 |
# File 'lib/math2d/vector2d.rb', line 77 def self.right Vector2D.new(1, 0) end |
.to_vector(arr) ⇒ Vector2D
Returns a new Vector2D from an array arr. If the array is bigger than 2 elements, only the first 2 will be considered.
397 398 399 400 401 |
# File 'lib/math2d/vector2d.rb', line 397 def self.to_vector(arr) raise ArgumentError, '`arr` must be an Array' if arr.class != Array Vector2D.new(arr[0], arr[1]) end |
.up ⇒ Vector2D
Shorthand for writing Vector2D.new(0, -1). NOTE: the y-axis is inverted as per Ruby2D’s y-axis orientation
56 57 58 |
# File 'lib/math2d/vector2d.rb', line 56 def self.up Vector2D.new(0, -1) end |
.zero ⇒ Vector2D
Shorthand for writing Vector2D.new(0, 0).
41 42 43 |
# File 'lib/math2d/vector2d.rb', line 41 def self.zero Vector2D.new(0, 0) end |
Instance Method Details
#*(other) ⇒ Vector2D
Multiplies self by another vector or by a scalar.
114 115 116 117 118 |
# File 'lib/math2d/vector2d.rb', line 114 def *(other) return Vector2D.new(@x * other.x, @y * other.y) if other.instance_of?(Vector2D) Vector2D.new(@x * other, @y * other) end |
#+(other) ⇒ Vector2D
Adds self to another vector or to a scalar.
94 95 96 97 98 |
# File 'lib/math2d/vector2d.rb', line 94 def +(other) return Vector2D.new(@x + other.x, @y + other.y) if other.instance_of?(Vector2D) Vector2D.new(@x + other, @y + other) end |
#-(other) ⇒ Vector2D
Subtracts self to another vector or to a scalar.
104 105 106 107 108 |
# File 'lib/math2d/vector2d.rb', line 104 def -(other) return Vector2D.new(@x - other.x, @y - other.y) if other.instance_of?(Vector2D) Vector2D.new(@x - other, @y - other) end |
#-@ ⇒ Vector2D Also known as: negate
Negates both x and y values of self and returns a new Vector2D.
84 85 86 |
# File 'lib/math2d/vector2d.rb', line 84 def -@ Vector2D.new(-@x, -@y) end |
#/(other) ⇒ Vector2D
Divides self by another vector or by a scalar.
124 125 126 127 128 |
# File 'lib/math2d/vector2d.rb', line 124 def /(other) return Vector2D.new(@x / other.x, @y / other.y) if other.instance_of?(Vector2D) Vector2D.new(@x / other, @y / other) end |
#==(other) ⇒ Boolean
Compares self and other according to their components.
134 135 136 |
# File 'lib/math2d/vector2d.rb', line 134 def ==(other) (@x == other.x) && (@y == other.y) end |
#angle_between(other) ⇒ Float
Returns the angle between self and other in radians.
286 287 288 |
# File 'lib/math2d/vector2d.rb', line 286 def angle_between(other) Math.acos((@x * other.x + @y * other.y) / (magnitude * other.magnitude)) end |
#constrain(a, b) ⇒ Vector2D Also known as: clamp
I haven’t experienced this with other methods (yet), so I’m only going to document this here: you may end up with a broken magnitude (1.99999999 instead of 2, for example), so always remember to check and round according to your need.
Constrains the magnitude of self between a minimum value a and maximum value b.
215 216 217 218 219 220 221 222 223 |
# File 'lib/math2d/vector2d.rb', line 215 def constrain(a, b) mag = magnitude v = Vector2D.one if mag > b v.set_magnitude(b) elsif mag < a v.set_magnitude(a) end end |
#cross(other) ⇒ Numeric Also known as: wedge
Strictly speaking, the cross product is not defined in a 2-dimensional space,
Calculates the “cross product” (see note) between self and other, where: A^B (A wedge B) = (Ax * By) - (Bx * Ay)
instead what is being calculated here is called a ‘wedge product`, which is defined in any space of dimension greater than 1.
156 157 158 |
# File 'lib/math2d/vector2d.rb', line 156 def cross(other) (@x * other.y) - (other.x * @y) end |
#distance(other) ⇒ Float
Returns the Euclidean distance between self and other.
182 183 184 |
# File 'lib/math2d/vector2d.rb', line 182 def distance(other) Math.sqrt((other.x - @x)**2 + (other.y - @y)**2) end |
#dot(other) ⇒ Numeric
Calculates the dot product between self and other, where: A.B (A dot B) = (Ax * Bx) + (Ay * By)
143 144 145 |
# File 'lib/math2d/vector2d.rb', line 143 def dot(other) (@x * other.x) + (@y * other.y) end |
#heading ⇒ Float
Returns the x-heading angle of self in radians. The x-heading angle is the angle formed between self and the x-axis.
261 262 263 |
# File 'lib/math2d/vector2d.rb', line 261 def heading Math.atan2(@y.to_f, @x) end |
#inverse_lerp(other, value) ⇒ Vector2D
Calculates the parameter t of the #lerp method between self and other given an interpolant value.
335 336 337 |
# File 'lib/math2d/vector2d.rb', line 335 def inverse_lerp(other, value) (value - self) / (other - self) end |
#lerp(other, amt) ⇒ Vector2D
Linear interpolate self and other with an amount amt.
326 327 328 |
# File 'lib/math2d/vector2d.rb', line 326 def lerp(other, amt) self + (other - self) * amt end |
#limit(max) ⇒ Vector2D
Limit the magnitude of self to max and returns a new vector.
197 198 199 200 201 202 203 204 205 |
# File 'lib/math2d/vector2d.rb', line 197 def limit(max) msq = squared vec = self if msq > (max**2) vec /= Math.sqrt(msq) vec *= max end vec end |
#magnitude ⇒ Float Also known as: length
Returns the magnitude of self.
172 173 174 |
# File 'lib/math2d/vector2d.rb', line 172 def magnitude Math.sqrt(@x**2 + @y**2) end |
#normalize ⇒ Vector2D Also known as: unit
Normalizes self (set the magnitude to 1). unit is an alias for this method.
241 242 243 |
# File 'lib/math2d/vector2d.rb', line 241 def normalize set_magnitude(1) end |
#normalized? ⇒ Boolean Also known as: unit?
Returns true if the magnitude of self is equal to 1, false otherwise. unit? is an alias for this method.
251 252 253 |
# File 'lib/math2d/vector2d.rb', line 251 def normalized? magnitude == 1 end |
#opposite?(other) ⇒ Boolean
Checks if self is facing the opposite direction of other.
294 295 296 |
# File 'lib/math2d/vector2d.rb', line 294 def opposite?(other) dot(other) < 0 end |
#ratio ⇒ Float
Returns the ratio (x / y) of self.
189 190 191 |
# File 'lib/math2d/vector2d.rb', line 189 def ratio x.to_f / y end |
#reflect(other) ⇒ Vector2D
Reflects self and returns it as a new Vector2D. other is the normal of the plane where self is reflected.
344 345 346 347 348 349 350 |
# File 'lib/math2d/vector2d.rb', line 344 def reflect(other) other = other.normalize dot_prod = other.dot(self) x = @x - dot_prod * other.x * 2 y = @y - dot_prod * other.y * 2 Vector2D.new(x, y) end |
#refract(other, refractive_index) ⇒ Vector2D
Refracts self and returns it as a new Vector2D. other is the normal of the plane where self is refracted.
360 361 362 363 364 365 366 367 368 |
# File 'lib/math2d/vector2d.rb', line 360 def refract(other, refractive_index) dot_prod = other.dot(self) k = 1.0 - refractive_index * refractive_index * (1.0 - dot_prod * dot_prod) return Vector2D.zero if k.negative? x = refractive_index * @x - (refractive_index * dot_prod * Math.sqrt(k)) * other.x y = refractive_index * @y - (refractive_index * dot_prod * Math.sqrt(k)) * other.y Vector2D.new(x, y) end |
#rotate(angle) ⇒ Vector2D
Clockwise rotates self angle radians and returns it as a new Vector2D.
302 303 304 305 306 307 |
# File 'lib/math2d/vector2d.rb', line 302 def rotate(angle) Vector2D.new( @x * Math.cos(angle) - @y * Math.sin(angle), @x * Math.sin(angle) + @y * Math.cos(angle) ) end |
#rotate_around(pivot, angle) ⇒ Vector2D
Clockwise rotates self angle radians around a pivot point and returns it as a new Vector2D.
314 315 316 317 318 319 |
# File 'lib/math2d/vector2d.rb', line 314 def rotate_around(pivot, angle) x_rotated = pivot.x + ((@x - pivot.x) * Math.cos(angle)) - ((@y - pivot.y) * Math.sin(angle)) y_rotated = pivot.y + ((@x - pivot.x) * Math.sin(angle)) + ((@y - pivot.y) * Math.cos(angle)) Vector2D.new(x_rotated, y_rotated) end |
#set(x = self.x, y = self.y) ⇒ Vector2D
Sets the x and y components of the vector. Each argument is optional, so you can change a single component and keep the other one’s current value.
32 33 34 35 36 |
# File 'lib/math2d/vector2d.rb', line 32 def set(x = self.x, y = self.y) @x = x @y = y self end |
#set_magnitude(new_mag) ⇒ Vector2D
Sets the magnitude of self to new_mag.
231 232 233 234 235 |
# File 'lib/math2d/vector2d.rb', line 231 def set_magnitude(new_mag) mag = magnitude mag = mag.zero? ? Float::INFINITY : mag Vector2D.new((@x * new_mag) / mag, (@y * new_mag) / mag) end |
#squared ⇒ Numeric
Returns the magnitude squared of self.
165 166 167 |
# File 'lib/math2d/vector2d.rb', line 165 def squared (@x**2) + (@y**2) end |
#to_a ⇒ Array<Numeric>
Converts self to an array.
381 382 383 |
# File 'lib/math2d/vector2d.rb', line 381 def to_a [@x, @y] end |
#to_s ⇒ String
Converts self to a string.
388 389 390 |
# File 'lib/math2d/vector2d.rb', line 388 def to_s to_a.to_s end |
#y_heading ⇒ Float
Returns the y-heading angle of self in radians. The y-heading angle is the angle formed between self and the y-axis.
269 270 271 |
# File 'lib/math2d/vector2d.rb', line 269 def y_heading Utils2D::HALF_PI - heading end |