Class: Vector2
- Includes:
- Enumerable, MinMaxHelpers
- Defined in:
- lib/gamebox/lib/vector2.rb
Overview
The Vector2 class implements two-dimensional vectors. It is used to represent positions, movements, and velocities in 2D space.
Constant Summary collapse
- RAD_TO_DEG =
180.0 / Math::PI
- DEG_TO_RAD =
Math::PI / 180.0
- MAX_UDOT_PRODUCT =
1.0
- MIN_UDOT_PRODUCT =
-1.0
Instance Attribute Summary collapse
-
#x ⇒ Object
Returns the value of attribute x.
-
#y ⇒ Object
Returns the value of attribute y.
Class Method Summary collapse
-
.many(*pairs) ⇒ Object
call-seq: Vector2.many( [x1,y1], [x2,y2], … ).
-
.new_polar(angle_rad, magnitude) ⇒ Object
Creates a new Vector2 from an angle in radians and a magnitude.
-
.new_polar_deg(angle_deg, magnitude) ⇒ Object
Creates a new Vector2 from an angle in degrees and a magnitude.
Instance Method Summary collapse
-
#*(scalar) ⇒ Object
Multiplies this vector by the given scalar (Numeric), and return the resulting vector.
-
#+(vector) ⇒ Object
Adds the given vector to this one and return the resulting vector.
-
#-(vector) ⇒ Object
Subtracts the given vector from this one and return the resulting vector.
-
#-@ ⇒ Object
Returns the opposite of this vector, i.e.
-
#==(vector) ⇒ Object
True if the given vector’s x and y components are equal to this vector’s components (within a small margin of error to compensate for floating point imprecision).
-
#[](index) ⇒ Object
(also: #at)
Returns a component of this vector as if it were an [x,y] Array.
-
#angle ⇒ Object
Returns the angle of this vector, relative to the positive X axis, in radians.
-
#angle=(angle_rad) ⇒ Object
Sets the vector’s angle in radians.
-
#angle_deg ⇒ Object
Returns the angle of this vector, relative to the positive X axis, in degrees.
-
#angle_deg=(angle_deg) ⇒ Object
Sets the vector’s angle in degrees.
-
#angle_deg_with(vector) ⇒ Object
Returns the angle of this vector relative to the other vector, in degrees.
-
#angle_with(vector) ⇒ Object
Returns the angle of this vector relative to the other vector, in radians.
-
#cross(vector) ⇒ Object
Returns the cross product between this vector and the other vector.
-
#dot(vector) ⇒ Object
Returns the dot product between this vector and the other vector.
-
#each {|@x| ... } ⇒ Object
Iterates over this vector as if it were an [x,y] Array.
-
#hash ⇒ Object
:nodoc:.
-
#initialize(x, y) ⇒ Vector2
constructor
Creates a new Vector2 with the given x and y values.
-
#magnitude ⇒ Object
Returns the magnitude (distance) of this vector.
-
#magnitude=(mag) ⇒ Object
Sets the vector’s magnitude (distance).
-
#move(x, y = nil) ⇒ Object
call-seq: move( [x,y] ) move( x,y ).
-
#move!(x, y = nil) ⇒ Object
call-seq: move!( [x,y] ) move!( x,y ).
-
#perp ⇒ Object
Returns a copy of this vector, but rotated 90 degrees counter-clockwise.
-
#project_onto!(vector) ⇒ Object
Sets this vector to the vector projection (aka vector resolute) of this vector onto the other vector.
-
#projected_onto(vector) ⇒ Object
Like #project_onto!, but returns a new vector.
-
#reverse ⇒ Object
Like #reverse!, but returns a new vector.
-
#reverse! ⇒ Object
Reverses the vector’s direction, i.e.
-
#rotate(angle_rad) ⇒ Object
Like #rotate!, but returns a new vector.
-
#rotate!(angle_rad) ⇒ Object
Rotates the vector the given number of radians.
-
#rotate_deg(angle_deg) ⇒ Object
Like #rotate_deg!, but returns a new vector.
-
#rotate_deg!(angle_deg) ⇒ Object
Rotates the vector the given number of degrees.
-
#scale(scale_x, scale_y = scale_x) ⇒ Object
Like #scale!, but returns a new vector.
-
#scale!(scale_x, scale_y = scale_x) ⇒ Object
call-seq: scale!( scale ) scale!( scale_x, scale_y ).
-
#set!(x, y) ⇒ Object
Sets this vector’s x and y components.
-
#set_polar!(angle_rad, mag) ⇒ Object
Sets this vector’s angle (in radians) and magnitude.
-
#set_polar_deg!(angle_deg, mag) ⇒ Object
Sets this vector’s angle (in degrees) and magnitude.
-
#to_ary ⇒ Object
(also: #to_a)
Returns this vector as an [x,y] Array.
- #to_s ⇒ Object (also: #inspect)
-
#udot(vector) ⇒ Object
Returns the dot product of this vector’s #unit and the other vector’s #unit.
-
#unit ⇒ Object
(also: #normalized)
Like #unit!, but returns a new vector.
-
#unit! ⇒ Object
(also: #normalize!)
Sets this vector’s magnitude to 1.
Methods included from MinMaxHelpers
Constructor Details
#initialize(x, y) ⇒ Vector2
Creates a new Vector2 with the given x and y values.
71 72 73 |
# File 'lib/gamebox/lib/vector2.rb', line 71 def initialize( x, y ) @x, @y = x.to_f, y.to_f end |
Instance Attribute Details
#x ⇒ Object
Returns the value of attribute x.
75 76 77 |
# File 'lib/gamebox/lib/vector2.rb', line 75 def x @x end |
#y ⇒ Object
Returns the value of attribute y.
75 76 77 |
# File 'lib/gamebox/lib/vector2.rb', line 75 def y @y end |
Class Method Details
.many(*pairs) ⇒ Object
call-seq:
Vector2.many( [x1,y1], [x2,y2], ... )
Converts multiple [x,y] Arrays to Vector2s. Returns the resulting vectors in an Array.
63 64 65 |
# File 'lib/gamebox/lib/vector2.rb', line 63 def many( *pairs ) pairs.collect { |pair| self.new(*pair) } end |
.new_polar(angle_rad, magnitude) ⇒ Object
Creates a new Vector2 from an angle in radians and a magnitude. Use #new_polar_deg for degrees.
43 44 45 46 |
# File 'lib/gamebox/lib/vector2.rb', line 43 def new_polar( angle_rad, magnitude ) self.new( Math::cos(angle_rad)*magnitude, Math::sin(angle_rad)*magnitude ) end |
.new_polar_deg(angle_deg, magnitude) ⇒ Object
Creates a new Vector2 from an angle in degrees and a magnitude. Use #new_polar for radians.
52 53 54 |
# File 'lib/gamebox/lib/vector2.rb', line 52 def new_polar_deg( angle_deg, magnitude ) self.new_polar( angle_deg * DEG_TO_RAD, magnitude ) end |
Instance Method Details
#*(scalar) ⇒ Object
Multiplies this vector by the given scalar (Numeric), and return the resulting vector.
189 190 191 |
# File 'lib/gamebox/lib/vector2.rb', line 189 def *( scalar ) self.class.new( @x * scalar, @y * scalar ) end |
#+(vector) ⇒ Object
Adds the given vector to this one and return the resulting vector.
126 127 128 |
# File 'lib/gamebox/lib/vector2.rb', line 126 def +( vector ) self.class.new( @x + vector.at(0), @y + vector.at(1) ) end |
#-(vector) ⇒ Object
Subtracts the given vector from this one and return the resulting vector.
162 163 164 |
# File 'lib/gamebox/lib/vector2.rb', line 162 def -( vector ) self.class.new( @x - vector.at(0), @y - vector.at(1) ) end |
#-@ ⇒ Object
Returns the opposite of this vector, i.e. Vector2[-x, -y].
168 169 170 |
# File 'lib/gamebox/lib/vector2.rb', line 168 def -@ self.class.new( -@x, -@y ) end |
#==(vector) ⇒ Object
True if the given vector’s x and y components are equal to this vector’s components (within a small margin of error to compensate for floating point imprecision).
198 199 200 201 |
# File 'lib/gamebox/lib/vector2.rb', line 198 def ==( vector ) return false if vector.nil? _nearly_equal?(@x, vector.at(0)) and _nearly_equal?(@y, vector.at(1)) end |
#[](index) ⇒ Object Also known as: at
Returns a component of this vector as if it were an
- x,y
-
Array.
207 208 209 210 211 212 213 214 215 216 |
# File 'lib/gamebox/lib/vector2.rb', line 207 def []( index ) case index when 0 @x when 1 @y else nil end end |
#angle ⇒ Object
Returns the angle of this vector, relative to the positive X axis, in radians. Use #angle_deg for degrees.
237 238 239 |
# File 'lib/gamebox/lib/vector2.rb', line 237 def angle Math.atan2( @y, @x ) end |
#angle=(angle_rad) ⇒ Object
Sets the vector’s angle in radians. The vector keeps the same magnitude as before.
245 246 247 248 249 250 251 252 |
# File 'lib/gamebox/lib/vector2.rb', line 245 def angle=( angle_rad ) raise "can't modify frozen object" if frozen? m = magnitude @x = Math::cos(angle_rad) * m @y = Math::sin(angle_rad) * m @hash = nil self end |
#angle_deg ⇒ Object
Returns the angle of this vector, relative to the positive X axis, in degrees. Use #angle for radians.
266 267 268 |
# File 'lib/gamebox/lib/vector2.rb', line 266 def angle_deg angle * RAD_TO_DEG end |
#angle_deg=(angle_deg) ⇒ Object
Sets the vector’s angle in degrees. The vector keeps the same magnitude as before.
274 275 276 277 |
# File 'lib/gamebox/lib/vector2.rb', line 274 def angle_deg=( angle_deg ) self.angle = angle_deg * DEG_TO_RAD self end |
#angle_deg_with(vector) ⇒ Object
Returns the angle of this vector relative to the other vector, in degrees. Use #angle_with for radians.
283 284 285 |
# File 'lib/gamebox/lib/vector2.rb', line 283 def angle_deg_with( vector ) angle_with(vector) * RAD_TO_DEG end |
#angle_with(vector) ⇒ Object
Returns the angle of this vector relative to the other vector, in radians. Use #angle_deg_with for degrees.
258 259 260 |
# File 'lib/gamebox/lib/vector2.rb', line 258 def angle_with( vector ) Math.acos( max(min(udot(vector),MAX_UDOT_PRODUCT), MIN_UDOT_PRODUCT) ) end |
#cross(vector) ⇒ Object
Returns the cross product between this vector and the other vector.
295 296 297 |
# File 'lib/gamebox/lib/vector2.rb', line 295 def cross( vector ) (@x * vector.y) - (@y * vector.x) end |
#dot(vector) ⇒ Object
Returns the dot product between this vector and the other vector.
289 290 291 |
# File 'lib/gamebox/lib/vector2.rb', line 289 def dot( vector ) (@x * vector.at(0)) + (@y * vector.at(1)) end |
#each {|@x| ... } ⇒ Object
Iterates over this vector as if it were an [x,y] Array.
228 229 230 231 |
# File 'lib/gamebox/lib/vector2.rb', line 228 def each yield @x yield @y end |
#hash ⇒ Object
:nodoc:
221 222 223 |
# File 'lib/gamebox/lib/vector2.rb', line 221 def hash # :nodoc: @hash ||= [@x, @y, self.class].hash end |
#magnitude ⇒ Object
Returns the magnitude (distance) of this vector.
301 302 303 |
# File 'lib/gamebox/lib/vector2.rb', line 301 def magnitude Math.hypot( @x, @y ) end |
#magnitude=(mag) ⇒ Object
Sets the vector’s magnitude (distance). The vector keeps the same angle as before.
309 310 311 312 313 314 315 316 |
# File 'lib/gamebox/lib/vector2.rb', line 309 def magnitude=( mag ) raise "can't modify frozen object" if frozen? angle_rad = angle @x = Math::cos(angle_rad) * mag @y = Math::sin(angle_rad) * mag @hash = nil self end |
#move(x, y = nil) ⇒ Object
call-seq:
move( [x,y] )
move( x,y )
Like #move!, but returns a new vector.
154 155 156 |
# File 'lib/gamebox/lib/vector2.rb', line 154 def move( x, y=nil ) self.dup.move!(x, y) end |
#move!(x, y = nil) ⇒ Object
call-seq:
move!( [x,y] )
move!( x,y )
Moves the vector by the given x and y amounts.
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/gamebox/lib/vector2.rb', line 135 def move!( x, y=nil ) raise "can't modify frozen object" if frozen? if y.nil? a = x.to_ary @x += a[0] @y += a[1] else @x += x @y += y end @hash = nil self end |
#perp ⇒ Object
Returns a copy of this vector, but rotated 90 degrees counter-clockwise.
322 323 324 |
# File 'lib/gamebox/lib/vector2.rb', line 322 def perp self.class.new( -@y, @x ) end |
#project_onto!(vector) ⇒ Object
Sets this vector to the vector projection (aka vector resolute) of this vector onto the other vector. See also #projected_onto.
329 330 331 332 333 334 335 |
# File 'lib/gamebox/lib/vector2.rb', line 329 def project_onto!( vector ) raise "can't modify frozen object" if frozen? b = vector.unit @x, @y = *(b.scale(self.dot(b))) @hash = nil self end |
#projected_onto(vector) ⇒ Object
Like #project_onto!, but returns a new vector.
339 340 341 |
# File 'lib/gamebox/lib/vector2.rb', line 339 def projected_onto( vector ) dup.project_onto!( vector ) end |
#reverse ⇒ Object
Like #reverse!, but returns a new vector.
181 182 183 |
# File 'lib/gamebox/lib/vector2.rb', line 181 def reverse self.dup.reverse! end |
#reverse! ⇒ Object
Reverses the vector’s direction, i.e. Vector2[-x, -y].
173 174 175 176 177 178 |
# File 'lib/gamebox/lib/vector2.rb', line 173 def reverse! raise "can't modify frozen object" if frozen? @x, @y = -@x, -@y @hash = nil self end |
#rotate(angle_rad) ⇒ Object
Like #rotate!, but returns a new vector.
353 354 355 |
# File 'lib/gamebox/lib/vector2.rb', line 353 def rotate( angle_rad ) dup.rotate!( angle_rad ) end |
#rotate!(angle_rad) ⇒ Object
Rotates the vector the given number of radians. Use #rotate_deg! for degrees.
347 348 349 350 |
# File 'lib/gamebox/lib/vector2.rb', line 347 def rotate!( angle_rad ) self.angle += angle_rad self end |
#rotate_deg(angle_deg) ⇒ Object
Like #rotate_deg!, but returns a new vector.
367 368 369 |
# File 'lib/gamebox/lib/vector2.rb', line 367 def rotate_deg( angle_deg ) dup.rotate_deg!( angle_deg ) end |
#rotate_deg!(angle_deg) ⇒ Object
Rotates the vector the given number of degrees. Use #rotate for radians.
361 362 363 364 |
# File 'lib/gamebox/lib/vector2.rb', line 361 def rotate_deg!( angle_deg ) self.angle_deg += angle_deg self end |
#scale(scale_x, scale_y = scale_x) ⇒ Object
Like #scale!, but returns a new vector.
396 397 398 |
# File 'lib/gamebox/lib/vector2.rb', line 396 def scale( scale_x, scale_y = scale_x ) dup.scale!(scale_x, scale_y) end |
#scale!(scale_x, scale_y = scale_x) ⇒ Object
call-seq:
scale!( scale )
scale!( scale_x, scale_y )
Multiplies this vector’s x and y values.
If one number is given, the vector will be equal to Vector2[x*scale, y*scale]. If two numbers are given, it will be equal to Vector2[x*scale_x, y*scale_y].
Example:
v = Vector2[1.5,2.5]
v.scale!( 2 ) # => Vector2[3,5]
v.scale!( 3, 4 ) # => Vector2[9,20]
388 389 390 391 392 393 |
# File 'lib/gamebox/lib/vector2.rb', line 388 def scale!( scale_x, scale_y = scale_x ) raise "can't modify frozen object" if frozen? @x, @y = @x * scale_x, @y * scale_y @hash = nil self end |
#set!(x, y) ⇒ Object
Sets this vector’s x and y components.
93 94 95 96 97 98 99 |
# File 'lib/gamebox/lib/vector2.rb', line 93 def set!( x, y ) raise "can't modify frozen object" if frozen? @x = x.to_f @y = y.to_f @hash = nil self end |
#set_polar!(angle_rad, mag) ⇒ Object
Sets this vector’s angle (in radians) and magnitude. Use #set_polar_deg! for degrees.
105 106 107 108 109 110 111 |
# File 'lib/gamebox/lib/vector2.rb', line 105 def set_polar!( angle_rad, mag ) raise "can't modify frozen object" if frozen? @x = Math::cos(angle_rad) * mag @y = Math::sin(angle_rad) * mag @hash = nil self end |
#set_polar_deg!(angle_deg, mag) ⇒ Object
Sets this vector’s angle (in degrees) and magnitude. Use #set_polar! for radians.
117 118 119 120 |
# File 'lib/gamebox/lib/vector2.rb', line 117 def set_polar_deg!( angle_deg, mag ) set_polar!( angle_deg * DEG_TO_RAD, mag ) self end |
#to_ary ⇒ Object Also known as: to_a
Returns this vector as an [x,y] Array.
402 403 404 |
# File 'lib/gamebox/lib/vector2.rb', line 402 def to_ary [@x, @y] end |
#to_s ⇒ Object Also known as: inspect
409 410 411 |
# File 'lib/gamebox/lib/vector2.rb', line 409 def to_s "Vector2[#{@x}, #{@y}]" end |
#udot(vector) ⇒ Object
Returns the dot product of this vector’s #unit and the other vector’s #unit.
419 420 421 |
# File 'lib/gamebox/lib/vector2.rb', line 419 def udot( vector ) unit.dot( vector.unit ) end |
#unit ⇒ Object Also known as: normalized
Like #unit!, but returns a new vector.
436 437 438 |
# File 'lib/gamebox/lib/vector2.rb', line 436 def unit self.dup.unit! end |
#unit! ⇒ Object Also known as: normalize!
Sets this vector’s magnitude to 1.
425 426 427 428 429 430 431 |
# File 'lib/gamebox/lib/vector2.rb', line 425 def unit! raise "can't modify frozen object" if frozen? scale = 1/magnitude @x, @y = @x * scale, @y * scale @hash = nil self end |