Module: Vector2d::Angles::ClassMethods

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

Overview

The angle methods taking both vectors as arguments, and the conversions between radians and degrees. Extended into Vector2d, so they are called on the class.

Vector2d.angle_between(Vector2d(2, 3), Vector2d(4, 5))
# => 0.0867..

Instance Method Summary collapse

Instance Method Details

#angle_between(vector1, vector2) ⇒ Float

Calculates the unsigned angle between two vectors in radians, in the range 0..PI. This is the magnitude of .angle_to, so the order of the arguments does not matter.

v1 = Vector2d(2, 3)
v2 = Vector2d(4, 5)
Vector2d.angle_between(v1, v2) # => 0.0867..
Vector2d.angle_between(v2, v1) # => 0.0867..

Only the directions matter, not the magnitudes. The zero vector has no direction, and the angle between it and anything is zero.

Vector2d.angle_between(v1, Vector2d(0, 0)) # => 0.0

Parameters:

  • vector1 (Vector2d)

    one of the vectors

  • vector2 (Vector2d)

    the other vector

Returns:

  • (Float)

    the angle in radians, in 0..PI



75
76
77
# File 'lib/vector2d/angles.rb', line 75

def angle_between(vector1, vector2)
  angle_to(vector1, vector2).abs
end

#angle_to(vector1, vector2) ⇒ Float

Calculates the signed angle in radians from the first vector to the second, in the range -PI..PI. The angle is positive when the second vector is counterclockwise from the first, and reversing the arguments flips its sign.

v1 = Vector2d(2, 3)
v2 = Vector2d(4, 5)
Vector2d.angle_to(v1, v2) # => -0.0867..
Vector2d.angle_to(v2, v1) # => 0.0867..

Only the directions matter, not the magnitudes. The zero vector has no direction, and the angle to or from it is zero.

Vector2d.angle_to(v1, Vector2d(0, 0)) # => 0.0

Parameters:

  • vector1 (Vector2d)

    the vector the angle is measured from

  • vector2 (Vector2d)

    the vector the angle is measured to

Returns:

  • (Float)

    the angle in radians, in -PI..PI



53
54
55
56
# File 'lib/vector2d/angles.rb', line 53

def angle_to(vector1, vector2)
  Math.atan2(cross_product(vector1, vector2),
             dot_product(vector1, vector2))
end

#degrees(radians) ⇒ Float

Converts an angle from radians to degrees, the inverse of .radians. The result is always a float.

Vector2d.degrees(0)            # => 0.0
Vector2d.degrees(Math::PI / 2) # => 90.0
Vector2d.degrees(Math::PI)     # => 180.0

This is the conversion #angle_in_degrees applies to #angle, and the one to reach for with the angle methods that have no degree variant.

Vector2d.degrees(Vector2d(0, 1).angle) # => 90.0

Raises ArgumentError unless the angle is a real number. Complex numbers are not angles, and are rejected.

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

Parameters:

  • radians (Integer, Float, Rational, BigDecimal)

    the angle in radians

Returns:

  • (Float)

    the angle in degrees



123
124
125
# File 'lib/vector2d/angles.rb', line 123

def degrees(radians)
  coordinate(radians).to_f * 180 / Math::PI
end

#from_degrees(angle, length = 1.0) ⇒ Vector2d

Creates a vector from an angle in degrees, with an optional length. This is .from_angle with the angle put through .radians, and is the same in every other respect: angles are measured counterclockwise from the positive x axis, and coordinates are always floats.

Vector2d.from_degrees(0)       # => Vector2d(1.0,0.0)
Vector2d.from_degrees(45)      # => Vector2d(0.7071..,0.7071..)
Vector2d.from_degrees(45, 2.0) # => Vector2d(1.4142..,1.4142..)

#angle_in_degrees takes the angle back.

Vector2d.from_degrees(90).angle_in_degrees # => 90.0

Raises ArgumentError unless both arguments are real numbers.

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

Parameters:

  • angle (Integer, Float, Rational, BigDecimal)

    the angle in degrees

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

    the length of the vector

Returns:

  • (Vector2d)

    a vector of the receiver's class



149
150
151
# File 'lib/vector2d/angles.rb', line 149

def from_degrees(angle, length = 1.0)
  from_angle(radians(angle), length)
end

#radians(degrees) ⇒ Float

Converts an angle from degrees to radians, the unit the rest of the library speaks. The result is always a float.

Vector2d.radians(0)   # => 0.0
Vector2d.radians(90)  # => 1.5707..
Vector2d.radians(180) # => 3.1415..

.degrees converts back.

Vector2d.degrees(Vector2d.radians(90)) # => 90.0

Raises ArgumentError unless the angle is a real number. Complex numbers are not angles, and are rejected.

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

Parameters:

  • degrees (Integer, Float, Rational, BigDecimal)

    the angle in degrees

Returns:

  • (Float)

    the angle in radians



98
99
100
# File 'lib/vector2d/angles.rb', line 98

def radians(degrees)
  coordinate(degrees).to_f * Math::PI / 180
end