Module: Vector2d::Constructors

Included in:
Vector2d
Defined in:
lib/vector2d/constructors.rb

Overview

The constructors that build a vector from something other than coordinates: an angle, a random draw, or a direction. They are class methods rather than constants, so a subclass gets its own.

Instance Method Summary collapse

Instance Method Details

#downVector2d

The unit vector pointing down. See .up for the direction the y axis grows in.

Vector2d.down       # => Vector2d(0,-1)
Vector2d.down.angle # => -1.5707..

Returns:

  • (Vector2d)

    a vector of the receiver's class



112
113
114
# File 'lib/vector2d/constructors.rb', line 112

def down
  build(0, -1)
end

#from_angle(angle, length = 1.0) ⇒ Vector2d

Creates a vector from an angle in radians, with an optional length. Angles are measured counterclockwise from the positive x axis, the same convention #angle follows.

Vector2d.from_angle(0)                 # => Vector2d(1.0,0.0)
Vector2d.from_angle(Math::PI / 4)      # => Vector2d(0.7071..,0.7071..)
Vector2d.from_angle(Math::PI / 4, 2.0) # => Vector2d(1.4142..,1.4142..)

Coordinates are always floats. This is the inverse of #to_polar.

length, angle = Vector2d(2, 3).to_polar
Vector2d.from_angle(angle, length) # => Vector2d(2.0,3.0)

Raises ArgumentError unless both arguments are real numbers. Complex numbers are not coordinates, and are rejected.

Vector2d.from_angle(Complex(1, 2)) # => ArgumentError

Parameters:

  • angle (Integer, Float, Rational, BigDecimal)

    the angle in radians

  • length (Integer, Float, Rational, BigDecimal) (defaults to: 1.0)

    the length of the vector

Returns:

  • (Vector2d)

    a vector of the receiver's class



30
31
32
33
34
# File 'lib/vector2d/constructors.rb', line 30

def from_angle(angle, length = 1.0)
  angle = coordinate(angle).to_f
  length = coordinate(length).to_f
  build(Math.cos(angle) * length, Math.sin(angle) * length)
end

#leftVector2d

The unit vector pointing left.

Vector2d.left       # => Vector2d(-1,0)
Vector2d.left.angle # => 3.1415..

Returns:

  • (Vector2d)

    a vector of the receiver's class



122
123
124
# File 'lib/vector2d/constructors.rb', line 122

def left
  build(-1, 0)
end

#oneVector2d

The vector with both coordinates set to one.

Vector2d.one # => Vector2d(1,1)

Returns:

  • (Vector2d)

    a vector of the receiver's class



85
86
87
# File 'lib/vector2d/constructors.rb', line 85

def one
  build(1, 1)
end

#random(length = 1.0, random: Random) ⇒ Vector2d

Creates a random vector, uniformly distributed by angle, with an optional length. Coordinates are always floats, as with .from_angle.

Vector2d.random.length.round(6)      # => 1.0
Vector2d.random(2.0).length.round(6) # => 2.0

Pass a Random to draw from a seeded sequence.

a = Vector2d.random(random: Random.new(42))
b = Vector2d.random(random: Random.new(42))
a == b # => true

Raises ArgumentError unless the length is a real number.

Vector2d.random(Complex(1, 2)) # => ArgumentError

Parameters:

  • length (Integer, Float, Rational, BigDecimal) (defaults to: 1.0)

    the length of the vector

  • random (#rand) (defaults to: Random)

    the source of randomness

Returns:

  • (Vector2d)

    a vector of the receiver's class



57
58
59
# File 'lib/vector2d/constructors.rb', line 57

def random(length = 1.0, random: Random)
  from_angle(random.rand * 2 * Math::PI, length)
end

#rightVector2d

The unit vector pointing right, along the positive x axis. This is the direction angles are measured from.

Vector2d.right       # => Vector2d(1,0)
Vector2d.right.angle # => 0.0

Returns:

  • (Vector2d)

    a vector of the receiver's class



133
134
135
# File 'lib/vector2d/constructors.rb', line 133

def right
  build(1, 0)
end

#upVector2d

The unit vector pointing up.

Vector2d.up       # => Vector2d(0,1)
Vector2d.up.angle # => 1.5707..

The y axis grows upwards here, and angles turn counterclockwise from the positive x axis. That is the convention .from_angle, #angle, #rotate and #perpendicular all follow. Libraries drawing in screen coordinates grow the y axis downwards and call (0, -1) up, so flip the y axis at that boundary.

Returns:

  • (Vector2d)

    a vector of the receiver's class



101
102
103
# File 'lib/vector2d/constructors.rb', line 101

def up
  build(0, 1)
end

#zeroVector2d

The zero vector.

Vector2d.zero # => Vector2d(0,0)

This and the five constants below have integer coordinates. They are exact, and integers keep them exact through arithmetic with integer vectors, widening to floats only when a float is involved. .from_angle returns floats instead, because a general angle has no exact coordinates.

Vector2d.zero.x       # => 0
(Vector2d.up * 2).y   # => 2
(Vector2d.up * 0.5).y # => 0.5

Returns:

  • (Vector2d)

    a vector of the receiver's class



76
77
78
# File 'lib/vector2d/constructors.rb', line 76

def zero
  build(0, 0)
end