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) ⇒ Object
-
#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.
274 275 276 |
# File 'lib/math2d/vector2d.rb', line 274 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.
369 370 371 372 |
# File 'lib/math2d/vector2d.rb', line 369 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.
393 394 395 396 397 |
# File 'lib/math2d/vector2d.rb', line 393 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) ⇒ Object
130 131 132 |
# File 'lib/math2d/vector2d.rb', line 130 def ==(other) (@x == other.x) && (@y == other.y) end |
#angle_between(other) ⇒ Float
Returns the angle between self and other in radians.
282 283 284 |
# File 'lib/math2d/vector2d.rb', line 282 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.
211 212 213 214 215 216 217 218 219 |
# File 'lib/math2d/vector2d.rb', line 211 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.
152 153 154 |
# File 'lib/math2d/vector2d.rb', line 152 def cross(other) (@x * other.y) - (other.x * @y) end |
#distance(other) ⇒ Float
Returns the Euclidean distance between self and other.
178 179 180 |
# File 'lib/math2d/vector2d.rb', line 178 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)
139 140 141 |
# File 'lib/math2d/vector2d.rb', line 139 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.
257 258 259 |
# File 'lib/math2d/vector2d.rb', line 257 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.
331 332 333 |
# File 'lib/math2d/vector2d.rb', line 331 def inverse_lerp(other, value) (value - self) / (other - self) end |
#lerp(other, amt) ⇒ Vector2D
Linear interpolate self and other with an amount amt.
322 323 324 |
# File 'lib/math2d/vector2d.rb', line 322 def lerp(other, amt) self + (other - self) * amt end |
#limit(max) ⇒ Vector2D
Limit the magnitude of self to max and returns a new vector.
193 194 195 196 197 198 199 200 201 |
# File 'lib/math2d/vector2d.rb', line 193 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.
168 169 170 |
# File 'lib/math2d/vector2d.rb', line 168 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.
237 238 239 |
# File 'lib/math2d/vector2d.rb', line 237 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.
247 248 249 |
# File 'lib/math2d/vector2d.rb', line 247 def normalized? magnitude == 1 end |
#opposite?(other) ⇒ Boolean
Checks if self is facing the opposite direction of other.
290 291 292 |
# File 'lib/math2d/vector2d.rb', line 290 def opposite?(other) dot(other) < 0 end |
#ratio ⇒ Float
Returns the ratio (x / y) of self.
185 186 187 |
# File 'lib/math2d/vector2d.rb', line 185 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.
340 341 342 343 344 345 346 |
# File 'lib/math2d/vector2d.rb', line 340 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.
356 357 358 359 360 361 362 363 364 |
# File 'lib/math2d/vector2d.rb', line 356 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.
298 299 300 301 302 303 |
# File 'lib/math2d/vector2d.rb', line 298 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.
310 311 312 313 314 315 |
# File 'lib/math2d/vector2d.rb', line 310 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.
227 228 229 230 231 |
# File 'lib/math2d/vector2d.rb', line 227 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.
161 162 163 |
# File 'lib/math2d/vector2d.rb', line 161 def squared (@x**2) + (@y**2) end |
#to_a ⇒ Array<Numeric>
Converts self to an array.
377 378 379 |
# File 'lib/math2d/vector2d.rb', line 377 def to_a [@x, @y] end |
#to_s ⇒ String
Converts self to a string.
384 385 386 |
# File 'lib/math2d/vector2d.rb', line 384 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.
265 266 267 |
# File 'lib/math2d/vector2d.rb', line 265 def y_heading Utils2D::HALF_PI - heading end |