Class: Math2D::Vector2D

Inherits:
Object
  • Object
show all
Defined in:
lib/math2d/vector2d.rb

Overview

Note:

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x = 0, y = 0) ⇒ Vector2D

Creates a new vector (x, y).

Parameters:

  • x (Numeric) (defaults to: 0)
  • y (Numeric) (defaults to: 0)


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

#xNumeric

The x coordinate of the Vector

Returns:

  • (Numeric)

    the current value of x



12
13
14
# File 'lib/math2d/vector2d.rb', line 12

def x
  @x
end

#yNumeric

The y coordinate of the Vector

Returns:

  • (Numeric)

    the current value of y



12
13
14
# File 'lib/math2d/vector2d.rb', line 12

def y
  @y
end

Class Method Details

.downVector2D

Shorthand for writing Vector2D.new(0, 1).

Returns:



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.

Parameters:

  • theta (Numeric)
  • len (Numeric) (defaults to: 1)

Returns:



264
265
266
# File 'lib/math2d/vector2d.rb', line 264

def self.from_angle(theta, len = 1)
  Vector2D.new(len * Math.cos(theta), len * Math.sin(theta))
end

.leftVector2D

Shorthand for writing Vector2D.new(-1, 0).

Returns:



70
71
72
# File 'lib/math2d/vector2d.rb', line 70

def self.left
  Vector2D.new(-1, 0)
end

.oneVector2D

Shorthand for writing Vector2D.new(1, 1).

Returns:



48
49
50
# File 'lib/math2d/vector2d.rb', line 48

def self.one
  Vector2D.new(1, 1)
end

.randomVector2D

Returns a new Vector2D with random components but magnitude equal to 1.

Returns:



310
311
312
313
# File 'lib/math2d/vector2d.rb', line 310

def self.random
  theta = rand(-Utils2D::TWO_PI..Utils2D::TWO_PI)
  Vector2D.new(Math.cos(theta), Math.sin(theta))
end

.rightVector2D

Shorthand for writing Vector2D.new(1, 0).

Returns:



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.

Parameters:

  • arr (Array<Numeric>)

Returns:

Raises:

  • (ArgumentError)


334
335
336
337
338
# File 'lib/math2d/vector2d.rb', line 334

def self.to_vector(arr)
  raise ArgumentError, '`arr` must be an Array' if arr.class != Array

  Vector2D.new(arr[0], arr[1])
end

.upVector2D

Shorthand for writing Vector2D.new(0, -1). NOTE: the y-axis is inverted as per Ruby2D’s y-axis orientation

Returns:



56
57
58
# File 'lib/math2d/vector2d.rb', line 56

def self.up
  Vector2D.new(0, -1)
end

.zeroVector2D

Shorthand for writing Vector2D.new(0, 0).

Returns:



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.

Parameters:

Returns:



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.

Parameters:

Returns:



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.

Parameters:

Returns:



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.

Returns:



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.

Parameters:

Returns:



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

#angle_between(other) ⇒ Float

Returns the angle between self and other in radians.

Parameters:

Returns:

  • (Float)


272
273
274
# File 'lib/math2d/vector2d.rb', line 272

def angle_between(other)
  Math.acos((@x * other.x + @y * other.y) / (magnitude * other.magnitude))
end

#constrain(a, b) ⇒ Vector2D Also known as: clamp

Note:

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.

Parameters:

  • a (Numeric)
  • b (Numeric)

Returns:



201
202
203
204
205
206
207
208
209
# File 'lib/math2d/vector2d.rb', line 201

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

Calculates the cross product between self and other, where: AxB (A cross B) = (Ax * By) - (Bx * Ay) HOWEVER, the cross product is NOT defined in a 2D space, so the operation simply returns the magnitude of the resulting cross-product 3D vector.

Parameters:

Returns:

  • (Numeric)


146
147
148
# File 'lib/math2d/vector2d.rb', line 146

def cross(other)
  (@x * other.y) - (other.x * @y)
end

#distance(other) ⇒ Float

Returns the Euclidean distance between self and other.

Parameters:

Returns:

  • (Float)


168
169
170
# File 'lib/math2d/vector2d.rb', line 168

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)

Parameters:

Returns:

  • (Numeric)


135
136
137
# File 'lib/math2d/vector2d.rb', line 135

def dot(other)
  (@x * other.x) + (@y * other.y)
end

#headingFloat

Returns the x-heading angle of self in radians. The x-heading angle is the angle formed between self and the x-axis.

Returns:

  • (Float)


247
248
249
# File 'lib/math2d/vector2d.rb', line 247

def heading
  Math.atan2(@y.to_f, @x)
end

#lerp(other, amt) ⇒ Vector2D

Linear interpolate self and other with an amount amt.

Parameters:

  • other (Numeric, Vector2D)
  • amt (Numeric)

Returns:



290
291
292
# File 'lib/math2d/vector2d.rb', line 290

def lerp(other, amt)
  self + (other - self) * amt
end

#limit(max) ⇒ Vector2D

Limit the magnitude of self to max and returns a new vector.

Parameters:

  • max (Numeric)

Returns:



183
184
185
186
187
188
189
190
191
# File 'lib/math2d/vector2d.rb', line 183

def limit(max)
  msq = squared
  vec = self
  if msq > (max**2)
    vec /= Math.sqrt(msq)
    vec *= max
  end
  vec
end

#magnitudeFloat

Returns the magnitude of self.

Returns:

  • (Float)


160
161
162
# File 'lib/math2d/vector2d.rb', line 160

def magnitude
  Math.sqrt(@x**2 + @y**2)
end

#normalizeVector2D Also known as: unit

Normalizes self (set the magnitude to 1). unit is an alias for this method.

Returns:



227
228
229
# File 'lib/math2d/vector2d.rb', line 227

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.

Returns:

  • (Boolean)


237
238
239
# File 'lib/math2d/vector2d.rb', line 237

def normalized?
  magnitude == 1
end

#ratioFloat

Returns the ratio (x / y) of self.

Returns:

  • (Float)


175
176
177
# File 'lib/math2d/vector2d.rb', line 175

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.

Parameters:

Returns:



299
300
301
302
303
304
305
# File 'lib/math2d/vector2d.rb', line 299

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

#rotate(angle) ⇒ Vector2D

Rotates self angle radians and returns it as a new Vector2D.

Parameters:

  • angle (Numeric)

Returns:



280
281
282
283
# File 'lib/math2d/vector2d.rb', line 280

def rotate(angle)
  Vector2D.new(@x * Math.cos(angle) - @y * Math.sin(angle),
               @x * Math.sin(angle) + @y * Math.cos(angle))
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.

Parameters:

  • x (Numeric) (defaults to: self.x)
  • y (Numeric) (defaults to: self.y)

Returns:



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.

Parameters:

  • new_mag (Numeric)

Returns:



217
218
219
220
221
# File 'lib/math2d/vector2d.rb', line 217

def set_magnitude(new_mag)
  mag = magnitude
  mag = mag.zero? ? Float::INFINITY : mag
  Vector2D.new((@x * new_mag) / mag, (@y * new_mag) / mag)
end

#squaredNumeric

Returns the magnitude squared of self.

Returns:

  • (Numeric)


153
154
155
# File 'lib/math2d/vector2d.rb', line 153

def squared
  (@x**2) + (@y**2)
end

#to_aArray<Numeric>

Converts self to an array.

Returns:

  • (Array<Numeric>)


318
319
320
# File 'lib/math2d/vector2d.rb', line 318

def to_a
  [@x, @y]
end

#to_sString

Converts self to a string.

Returns:

  • (String)


325
326
327
# File 'lib/math2d/vector2d.rb', line 325

def to_s
  to_a.to_s
end

#y_headingFloat

Returns the y-heading angle of self in radians. The y-heading angle is the angle formed between self and the y-axis.

Returns:

  • (Float)


255
256
257
# File 'lib/math2d/vector2d.rb', line 255

def y_heading
  Utils2D::HALF_PI - heading
end