Module: Vector2d::Angles
- Included in:
- Vector2d
- Defined in:
- lib/vector2d/angles.rb
Overview
The angle API. Radians are the native unit: every angle is measured counterclockwise from the positive x axis, and every method takes and returns radians unless its name says degrees.
The degree methods are conversions layered on top, not a second angle API. Two general converters, .radians and .degrees, do the arithmetic once. Three degree variants build on them, each one the radian method with the angle converted: .from_degrees is .from_angle, #angle_in_degrees is #angle, and #rotate_degrees is #rotate. The rest of the angle API stays radians only. Convert at the call site for those.
Vector2d(2, 3).rotate_around(Vector2d(1, 1), Vector2d.radians(90))
# => Vector2d(-1.0,2.0)
Vector2d.degrees(Vector2d(2, 3).angle_to(Vector2d(4, 5)))
# => -4.9697..
Porting note: pygame's rotate() and Unity's Vector2.Angle are in degrees, so those angles need .radians on the way in. Godot and Rust's glam are radians like this library, and their angles carry over unconverted.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#angle ⇒ Float
Angle of vector.
-
#angle_between(other) ⇒ Float
(also: #angle_with)
Unsigned angle in radians between this vector and another vector, in the range 0..PI.
-
#angle_in_degrees ⇒ Float
Angle of the vector in degrees.
-
#angle_to(other) ⇒ Float
Signed angle in radians from this vector to another vector, in the range -PI..PI.
-
#perpendicular ⇒ self
Returns the vector rotated a quarter turn counterclockwise.
-
#perpendicular_cw ⇒ self
Returns the vector rotated a quarter turn clockwise.
-
#rotate(angle) ⇒ self
Rotates the vector around the origin.
-
#rotate_around(center, angle) ⇒ self
Rotates the vector around another point.
-
#rotate_degrees(angle) ⇒ self
Rotates the vector around the origin by an angle in degrees.
-
#to_polar ⇒ Array(Float, Float)
Polar coordinates of vector, as a [length, angle] array.
Instance Method Details
#angle ⇒ Float
Angle of vector.
Vector2d(2, 3).angle # => 0.9827..
159 160 161 |
# File 'lib/vector2d/angles.rb', line 159 def angle Math.atan2(y, x) end |
#angle_between(other) ⇒ Float Also known as: angle_with
Unsigned angle in radians between this vector and another vector, in the range 0..PI. This is the magnitude of #angle_to, so it is the same in either direction.
v1 = Vector2d(2, 3)
v2 = Vector2d(4, 5)
v1.angle_between(v2) # => 0.0867..
v2.angle_between(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.
v1.angle_between(Vector2d(0, 0)) # => 0.0
200 201 202 |
# File 'lib/vector2d/angles.rb', line 200 def angle_between(other) angle_to(other).abs end |
#angle_in_degrees ⇒ Float
Angle of the vector in degrees. This is #angle put through .degrees, and follows the same convention: angles are measured counterclockwise from the positive x axis, in the range -180..180.
Vector2d(1, 0).angle_in_degrees # => 0.0
Vector2d(0, 1).angle_in_degrees # => 90.0
Vector2d(2, 3).angle_in_degrees # => 56.3099..
Vector2d(0, -1).angle_in_degrees # => -90.0
Vector2d.from_degrees takes the angle back.
Vector2d.from_degrees(Vector2d(2, 3).angle_in_degrees, 5.0)
# => Vector2d(2.7735..,4.1602..)
289 290 291 |
# File 'lib/vector2d/angles.rb', line 289 def angle_in_degrees self.class.degrees(angle) end |
#angle_to(other) ⇒ Float
Signed angle in radians from this vector to another vector, in the range -PI..PI. The angle is positive when the other vector is counterclockwise from this one.
v1 = Vector2d(2, 3)
v2 = Vector2d(4, 5)
v1.angle_to(v2) # => -0.0867..
v2.angle_to(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.
v1.angle_to(Vector2d(0, 0)) # => 0.0
179 180 181 182 |
# File 'lib/vector2d/angles.rb', line 179 def angle_to(other) v = coerce_vector(other) self.class.angle_to(self, v) end |
#perpendicular ⇒ self
Returns the vector rotated a quarter turn counterclockwise.
Vector2d(2, 3).perpendicular # => Vector2d(-3,2)
Counterclockwise is the same positive direction #rotate turns in. Use #perpendicular_cw for the other one.
260 261 262 |
# File 'lib/vector2d/angles.rb', line 260 def perpendicular build(-y, x) end |
#perpendicular_cw ⇒ self
Returns the vector rotated a quarter turn clockwise.
Vector2d(2, 3).perpendicular_cw # => Vector2d(3,-2)
269 270 271 |
# File 'lib/vector2d/angles.rb', line 269 def perpendicular_cw build(y, -x) end |
#rotate(angle) ⇒ self
230 231 232 233 234 235 |
# File 'lib/vector2d/angles.rb', line 230 def rotate(angle) angle = coordinate(angle) cos = Math.cos(angle) sin = Math.sin(angle) build((x * cos) - (y * sin), (x * sin) + (y * cos)) end |
#rotate_around(center, angle) ⇒ self
247 248 249 250 |
# File 'lib/vector2d/angles.rb', line 247 def rotate_around(center, angle) center_v = coerce_vector(center) (self - center_v).rotate(angle) + center_v end |
#rotate_degrees(angle) ⇒ self
Rotates the vector around the origin by an angle in degrees. This is #rotate with the angle put through .radians, and turns the same way: a positive angle turns counterclockwise.
Vector2d(2, 3).rotate_degrees(90) # => Vector2d(-3.0,2.0)
The two agree exactly wherever .radians lands on the angle #rotate would have been given.
Vector2d(2, 3).rotate_degrees(90) == Vector2d(2, 3).rotate(Math::PI / 2)
# => true
Raises ArgumentError unless the angle is a real number.
Vector2d(2, 3).rotate_degrees(Complex(1, 2)) # => ArgumentError
311 312 313 |
# File 'lib/vector2d/angles.rb', line 311 def rotate_degrees(angle) rotate(self.class.radians(angle)) end |
#to_polar ⇒ Array(Float, Float)
215 216 217 |
# File 'lib/vector2d/angles.rb', line 215 def to_polar [length, angle] end |