Class: Math2D::Vector2D
- Inherits:
-
Object
- Object
- Math2D::Vector2D
- Defined in:
- lib/math2d/vector2d.rb
Overview
ALL ! (bang) methods that return a vector (e.g. #normalize!, #add!) change the vector in place and return self.
MOST (but not all) regular methods that return a vector create NEW Vector2D. Some however change the vector in place and return self, 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
theta
with 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
self
by another vector, scalar, or array of two scalars. -
#+(other) ⇒ Vector2D
Adds
self
to another vector, scalar, or array of two scalars. -
#-(other) ⇒ Vector2D
Subtracts
self
from another vector, scalar, or array of two scalars. -
#-@ ⇒ Vector2D
(also: #negate, #reverse)
Negates both x and y values of
self
and returns a new Vector2D. -
#/(other) ⇒ Vector2D
Divides
self
by another vector, scalar, or array of two scalars. -
#==(other) ⇒ Boolean
Compares
self
andother
according to their components. -
#add!(dx, dy) ⇒ Vector2d
Add
dx
anddy
to the current vector’s components, respectively. -
#angle_between(other) ⇒ Float
Returns the angle between
self
andother
in radians. -
#constrain(min, max) ⇒ Vector2D
(also: #clamp)
Constrains the magnitude of
self
between a minimum valuemin
and maximum valuemax
, returns a new vector or itself. -
#cross(other) ⇒ Numeric
(also: #wedge)
Calculates the “cross product” (see note) between
self
andother
, where: A^B (A wedge B) = (Ax * By) - (Bx * Ay). -
#distance(other) ⇒ Float
Returns the Euclidean distance between
self
andother
. -
#distance2(other) ⇒ Float
Returns the squared Euclidean distance between
self
andother
. -
#divide_by!(delta) ⇒ Vector2D
Divides
self
bydelta
in place. -
#dot(other) ⇒ Numeric
Calculates the dot product between
self
andother
, where: A.B (A dot B) = (Ax * Bx) + (Ay * By). -
#heading ⇒ Float
Returns the x-heading angle of
self
in radians. -
#initialize(x = 0, y = 0) ⇒ Vector2D
constructor
Creates a new vector (x, y).
-
#initialize_copy(other) ⇒ Vector2D
Creates a copy of the
other
vector. -
#inverse_lerp(other, value) ⇒ Vector2D
Calculates the parameter t of the
#lerp
method betweenself
andother
given an interpolantvalue
. -
#lerp(other, amt) ⇒ Vector2D
Linear interpolate
self
andother
with an amountamt
. -
#limit(max) ⇒ Vector2D
Limit the magnitude of
self
tomax
and returns a new vector. -
#magnitude ⇒ Float
(also: #length)
Returns the magnitude of
self
. -
#minus!(delta) ⇒ Vector2D
Subtracts
delta
fromself
in place. -
#normalize ⇒ Vector2D
(also: #unit)
Normalizes
self
(set the magnitude to 1) and returns a new vector. -
#normalize! ⇒ Vector2D
(also: #unit!)
Normalizes
self
(set the magnitude to 1) *in place*. -
#normalized? ⇒ Boolean
(also: #unit?)
Returns true if the magnitude of
self
is equal to 1, false otherwise. -
#opposite?(other) ⇒ Boolean
Checks if
self
is facing the opposite direction ofother
. -
#plus!(delta) ⇒ Vector2D
Adds
delta
toself
in place. -
#ratio ⇒ Float
Returns the ratio (x / y) of
self
. -
#reflect(other) ⇒ Vector2D
Reflects
self
and returns it as a new Vector2D. -
#refract(other, refractive_index) ⇒ Vector2D
Refracts
self
and returns it as a new Vector2D. -
#replace!(other) ⇒ Vector2D
Replace contents of this vector with contents of
other
*in place*. -
#reverse! ⇒ Vector2D
(also: #negate!)
Negate this vector, modifying it in place.
-
#rotate(angle) ⇒ Vector2D
Clockwise rotates
self
angle
radians and returns it as a new Vector2D. -
#rotate!(angle) ⇒ Vector2D
Clockwise rotates
self
byangle
radians *in place*. -
#rotate_around(pivot, angle) ⇒ Vector2D
Clockwise rotates
self
angle
radians around apivot
point and returns it as a new Vector2D. -
#rotate_around!(pivot, angle) ⇒ Vector2D
Clockwise rotates
self
byangle
radians around apivot
point *in place*. -
#set(x = self.x, y = self.y) ⇒ Vector2D
Sets the
x
andy
components of the vector. -
#set_magnitude(new_mag) ⇒ Vector2D
(also: #magnitude!)
Sets the magnitude of
self
tonew_mag
. -
#squared ⇒ Numeric
(also: #magnitude2)
Returns the magnitude squared of
self
. -
#subtract!(dx, dy) ⇒ Vector2d
Subtract
dx
anddy
from the current vector’s components, respectively. -
#times!(delta) ⇒ Vector2D
Multiplies
self
bydelta
in place. -
#to_a ⇒ Array<Numeric>
Converts
self
to an array. -
#to_s ⇒ String
Converts
self
to a string. -
#vector_cross_product ⇒ Vector2D
(also: #perp)
Returns a *new vector* of the clockwise perpendicular to this vector.
-
#vector_cross_product! ⇒ Vector2D
(also: #perp!)
Replace this vector with it’s clockwise perpendicular.
-
#y_heading ⇒ Float
Returns the y-heading angle of
self
in radians.
Constructor Details
#initialize(x = 0, y = 0) ⇒ Vector2D
Creates a new vector (x, y).
22 23 24 25 |
# File 'lib/math2d/vector2d.rb', line 22 def initialize(x = 0, y = 0) @x = x.to_f @y = y.to_f end |
Instance Attribute Details
#x ⇒ Numeric
The x coordinate of the Vector
14 15 16 |
# File 'lib/math2d/vector2d.rb', line 14 def x @x end |
#y ⇒ Numeric
The y coordinate of the Vector
14 15 16 |
# File 'lib/math2d/vector2d.rb', line 14 def y @y end |
Class Method Details
.down ⇒ Vector2D
Shorthand for writing Vector2D.new(0, 1).
84 85 86 |
# File 'lib/math2d/vector2d.rb', line 84 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
.
328 329 330 |
# File 'lib/math2d/vector2d.rb', line 328 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).
91 92 93 |
# File 'lib/math2d/vector2d.rb', line 91 def self.left Vector2D.new(-1, 0) end |
.one ⇒ Vector2D
Shorthand for writing Vector2D.new(1, 1).
69 70 71 |
# File 'lib/math2d/vector2d.rb', line 69 def self.one Vector2D.new(1, 1) end |
.random ⇒ Vector2D
Returns a new Vector2D with random components but magnitude equal to 1.
449 450 451 452 |
# File 'lib/math2d/vector2d.rb', line 449 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).
98 99 100 |
# File 'lib/math2d/vector2d.rb', line 98 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.
493 494 495 496 497 |
# File 'lib/math2d/vector2d.rb', line 493 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
77 78 79 |
# File 'lib/math2d/vector2d.rb', line 77 def self.up Vector2D.new(0, -1) end |
.zero ⇒ Vector2D
Shorthand for writing Vector2D.new(0, 0).
62 63 64 |
# File 'lib/math2d/vector2d.rb', line 62 def self.zero Vector2D.new(0, 0) end |
Instance Method Details
#*(other) ⇒ Vector2D
Multiplies self
by another vector, scalar, or array of two scalars
144 145 146 |
# File 'lib/math2d/vector2d.rb', line 144 def *(other) clone.times!(other) end |
#+(other) ⇒ Vector2D
Adds self
to another vector, scalar, or array of two scalars
128 129 130 |
# File 'lib/math2d/vector2d.rb', line 128 def +(other) clone.plus!(other) end |
#-(other) ⇒ Vector2D
Subtracts self
from another vector, scalar, or array of two scalars
136 137 138 |
# File 'lib/math2d/vector2d.rb', line 136 def -(other) clone.minus!(other) end |
#-@ ⇒ Vector2D Also known as: negate, reverse
Negates both x and y values of self
and returns a new Vector2D.
105 106 107 |
# File 'lib/math2d/vector2d.rb', line 105 def -@ Vector2D.new(-@x, -@y) end |
#/(other) ⇒ Vector2D
Divides self
by another vector, scalar, or array of two scalars
152 153 154 |
# File 'lib/math2d/vector2d.rb', line 152 def /(other) clone.divide_by!(other) end |
#==(other) ⇒ Boolean
Compares self
and other
according to their components.
160 161 162 |
# File 'lib/math2d/vector2d.rb', line 160 def ==(other) (@x == other.x) && (@y == other.y) end |
#add!(dx, dy) ⇒ Vector2d
Add dx
and dy
to the current vector’s components, respectively
580 581 582 583 584 |
# File 'lib/math2d/vector2d.rb', line 580 def add!(dx, dy) @x += dx @y += dy self end |
#angle_between(other) ⇒ Float
Returns the angle between self
and other
in radians.
336 337 338 |
# File 'lib/math2d/vector2d.rb', line 336 def angle_between(other) Math.acos((@x * other.x + @y * other.y) / (magnitude * other.magnitude)) end |
#constrain(min, max) ⇒ 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 min
and maximum value max
, returns a new vector or itself.
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/math2d/vector2d.rb', line 251 def constrain(min, max) min, max = max, min if min > max # swap mag2 = magnitude2 if mag2 > max.abs2 Vector2D.one.set_magnitude(max) elsif mag2 < min.abs2 Vector2D.one.set_magnitude(min) else self 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.
182 183 184 |
# File 'lib/math2d/vector2d.rb', line 182 def cross(other) (@x * other.y) - (other.x * @y) end |
#distance(other) ⇒ Float
Returns the Euclidean distance between self
and other
.
220 221 222 |
# File 'lib/math2d/vector2d.rb', line 220 def distance(other) Math.sqrt((other.x - @x)**2 + (other.y - @y)**2) end |
#distance2(other) ⇒ Float
Returns the squared Euclidean distance between self
and other
. When comparing distances, comparing the squared distance yields the same result without the overhead of a square-root operation.
212 213 214 |
# File 'lib/math2d/vector2d.rb', line 212 def distance2(other) (other.x - @x)**2 + (other.y - @y)**2 end |
#divide_by!(delta) ⇒ Vector2D
Divides self
by delta
in place.
560 561 562 563 564 565 566 567 568 569 570 571 572 573 |
# File 'lib/math2d/vector2d.rb', line 560 def divide_by!(delta) case delta when Vector2D @x /= delta.x @y /= delta.y when Array @x /= delta[0] @y /= delta[1] else @x /= delta @y /= delta end self end |
#dot(other) ⇒ Numeric
Calculates the dot product between self
and other
, where: A.B (A dot B) = (Ax * Bx) + (Ay * By)
169 170 171 |
# File 'lib/math2d/vector2d.rb', line 169 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.
311 312 313 |
# File 'lib/math2d/vector2d.rb', line 311 def heading Math.atan2(@y.to_f, @x) end |
#initialize_copy(other) ⇒ Vector2D
Creates a copy of the other
vector.
31 32 33 34 |
# File 'lib/math2d/vector2d.rb', line 31 def initialize_copy(other) @x = other.x @y = other.y end |
#inverse_lerp(other, value) ⇒ Vector2D
Calculates the parameter t of the #lerp
method between self
and other
given an interpolant value
.
410 411 412 |
# File 'lib/math2d/vector2d.rb', line 410 def inverse_lerp(other, value) (value - self) / (other - self) end |
#lerp(other, amt) ⇒ Vector2D
Linear interpolate self
and other
with an amount amt
.
399 400 401 402 403 |
# File 'lib/math2d/vector2d.rb', line 399 def lerp(other, amt) Vector2D.new @x + (other.x - @x) * amt, @y + (other.y - @y) * amt # self + (other - self) * amt end |
#limit(max) ⇒ Vector2D
Limit the magnitude of self
to max
and returns a new vector.
235 236 237 238 239 240 |
# File 'lib/math2d/vector2d.rb', line 235 def limit(max) msq = squared return self if msq <= (max**2) self * (max / Math.sqrt(msq)) end |
#magnitude ⇒ Float Also known as: length
Returns the magnitude of self
.
200 201 202 |
# File 'lib/math2d/vector2d.rb', line 200 def magnitude Math.sqrt(@x**2 + @y**2) end |
#minus!(delta) ⇒ Vector2D
Subtracts delta
from self
in place.
522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/math2d/vector2d.rb', line 522 def minus!(delta) case delta when Vector2D @x -= delta.x @y -= delta.y when Array @x -= delta[0] @y -= delta[1] else @x -= delta @y -= delta end self end |
#normalize ⇒ Vector2D Also known as: unit
Normalizes self
(set the magnitude to 1) and returns a new vector. unit
is an alias for this method.
281 282 283 |
# File 'lib/math2d/vector2d.rb', line 281 def normalize clone.set_magnitude(1) end |
#normalize! ⇒ Vector2D Also known as: unit!
Normalizes self
(set the magnitude to 1) *in place*. unit!
is an alias for this method.
291 292 293 |
# File 'lib/math2d/vector2d.rb', line 291 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.
301 302 303 |
# File 'lib/math2d/vector2d.rb', line 301 def normalized? magnitude == 1 end |
#opposite?(other) ⇒ Boolean
Checks if self
is facing the opposite direction of other
.
344 345 346 |
# File 'lib/math2d/vector2d.rb', line 344 def opposite?(other) dot(other).negative? end |
#plus!(delta) ⇒ Vector2D
Adds delta
to self
in place.
541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
# File 'lib/math2d/vector2d.rb', line 541 def plus!(delta) case delta when Vector2D @x += delta.x @y += delta.y when Array @x += delta[0] @y += delta[1] else @x += delta @y += delta end self end |
#ratio ⇒ Float
Returns the ratio (x / y) of self
.
227 228 229 |
# File 'lib/math2d/vector2d.rb', line 227 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.
419 420 421 422 423 424 |
# File 'lib/math2d/vector2d.rb', line 419 def reflect(other) other = other.normalize dot_prod = other.dot(self) Vector2D.new @x - dot_prod * other.x * 2, @y - dot_prod * other.y * 2 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.
435 436 437 438 439 440 441 442 443 444 |
# File 'lib/math2d/vector2d.rb', line 435 def refract(other, refractive_index) dot_prod = other.dot(self) k = 1.0 - refractive_index.abs2 * (1.0 - dot_prod.abs2) return Vector2D.zero if k.negative? other_refraction = (refractive_index * dot_prod * Math.sqrt(k)) x = refractive_index * @x - other_refraction * other.x y = refractive_index * @y - other_refraction * other.y Vector2D.new(x, y) end |
#replace!(other) ⇒ Vector2D
Replace contents of this vector with contents of other
*in place*.
40 41 42 43 44 |
# File 'lib/math2d/vector2d.rb', line 40 def replace!(other) @x = other.x @y = other.y self end |
#reverse! ⇒ Vector2D Also known as: negate!
Negate this vector, modifying it in place
116 117 118 119 120 |
# File 'lib/math2d/vector2d.rb', line 116 def reverse! @x = -@x @y = -@y self end |
#rotate(angle) ⇒ Vector2D
Clockwise rotates self
angle
radians and returns it as a new Vector2D.
352 353 354 |
# File 'lib/math2d/vector2d.rb', line 352 def rotate(angle) clone.rotate!(angle) end |
#rotate!(angle) ⇒ Vector2D
Clockwise rotates self
by angle
radians *in place*
360 361 362 363 364 365 366 |
# File 'lib/math2d/vector2d.rb', line 360 def rotate!(angle) sin_ang = Math.sin(angle) cos_ang = Math.cos(angle) @x = @x * cos_ang - @y * sin_ang @y = @x * sin_ang + @y * cos_ang self end |
#rotate_around(pivot, angle) ⇒ Vector2D
Clockwise rotates self
angle
radians around a pivot
point and returns it as a new Vector2D.
373 374 375 |
# File 'lib/math2d/vector2d.rb', line 373 def rotate_around(pivot, angle) clone.rotate_around!(pivot, angle) end |
#rotate_around!(pivot, angle) ⇒ Vector2D
Clockwise rotates self
by angle
radians around a pivot
point *in place*
382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/math2d/vector2d.rb', line 382 def rotate_around!(pivot, angle) pivot_x = pivot.x pivot_y = pivot.y dx = (@x - pivot_x) dy = (@y - pivot_y) sin_ang = Math.sin(angle) cos_ang = Math.cos(angle) @x = pivot_x + (dx * cos_ang) - (dy * sin_ang) @y = pivot_y + (dx * sin_ang) + (dy * cos_ang) self 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.
53 54 55 56 57 |
# File 'lib/math2d/vector2d.rb', line 53 def set(x = self.x, y = self.y) @x = x.to_f @y = y.to_f self end |
#set_magnitude(new_mag) ⇒ Vector2D Also known as: magnitude!
Sets the magnitude of self
to new_mag
.
269 270 271 272 273 |
# File 'lib/math2d/vector2d.rb', line 269 def set_magnitude(new_mag) mag = magnitude mag = Float::INFINITY if mag.zero? times!(new_mag / mag) end |
#squared ⇒ Numeric Also known as: magnitude2
Returns the magnitude squared of self
.
191 192 193 |
# File 'lib/math2d/vector2d.rb', line 191 def squared (@x**2) + (@y**2) end |
#subtract!(dx, dy) ⇒ Vector2d
Subtract dx
and dy
from the current vector’s components, respectively
591 592 593 594 595 |
# File 'lib/math2d/vector2d.rb', line 591 def subtract!(dx, dy) @x -= dx @y -= dy self end |
#times!(delta) ⇒ Vector2D
Multiplies self
by delta
in place.
503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
# File 'lib/math2d/vector2d.rb', line 503 def times!(delta) case delta when Vector2D @x *= delta.x @y *= delta.y when Array @x *= delta[0] @y *= delta[1] else @x *= delta @y *= delta end self end |
#to_a ⇒ Array<Numeric>
Converts self
to an array.
457 458 459 |
# File 'lib/math2d/vector2d.rb', line 457 def to_a [@x, @y] end |
#to_s ⇒ String
Converts self
to a string.
464 465 466 |
# File 'lib/math2d/vector2d.rb', line 464 def to_s to_a.to_s end |
#vector_cross_product ⇒ Vector2D Also known as: perp
Returns a *new vector* of the clockwise perpendicular to this vector.
472 473 474 |
# File 'lib/math2d/vector2d.rb', line 472 def vector_cross_product Vector2D.new @y, -@x end |
#vector_cross_product! ⇒ Vector2D Also known as: perp!
Replace this vector with it’s clockwise perpendicular
481 482 483 484 |
# File 'lib/math2d/vector2d.rb', line 481 def vector_cross_product! @x, @y = @y, -@x self 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.
319 320 321 |
# File 'lib/math2d/vector2d.rb', line 319 def y_heading Utils2D::HALF_PI - heading end |