# abstract struct Geode::Angle(T)

## Overview

Base unit class for all rotation measurements.

The T type parameter is the type used to store the angle's value. It should be a numerical type, preferably `Float32` or `Float64`.

## Defined in:

geode/angles/angle.cr
geode/angles/comparison.cr
geode/angles/operations.cr

## Constructor Detail

def self.new(value : T) #

Creates an angle from the specified value.

def self.zero : self #

Creates an angle initialized at zero.

## Instance Method Detail

def %(amount : Number) : Angle #

Computes the remainder after dividing the angle by the specified amount.

``25.degrees % 10 # => 5°``

def %(other : self) : Number #

Computes the remainder after dividing the angle by another.

``30.degrees % 4.degrees # => 2``

def %(other : Angle) : Number #

Computes the remainder after dividing the angle by another of a different type.

``200.degrees % (Math::PI.radians / 3) # => 20``

def &*(amount : Number) : Angle #

Multiplies the angle by the specified amount.

Values will wrap instead of overflowing and raising an error.

``15.degrees &* 5 # => 75°``

def &+(other : self) : self #

Values will wrap instead of overflowing and raising an error.

``30.degrees &+ 45.degrees # => 75°``

def &-(other : self) : self #

Subtracts another angle from this one.

Values will wrap instead of overflowing and raising an error.

``90.degrees &- 30.degrees # => 60°``

def *(amount : Number) : Angle #

Multiplies the angle by the specified amount.

``15.degrees * 5 # => 75°``

def +(other : self) : self #

``30.degrees + 45.degrees # => 75°``

def +(other : Angle) : Angle #

Adds two angles of different types together.

``30.degrees + Math::PI.radians / 2 # => 120.0°``

def -(other : self) : self #

Subtracts another angle from this one.

``90.degrees - 30.degrees # => 60°``

def -(other : Angle) : Angle #

Subtracts another angle of a different type from this one.

``180.degrees - Math::PI.radians / 2 # => 90.0°``

def - : self #

Returns a negated angle.

``-(45.degrees) # => -45°``

def /(amount : Number) : Angle #

Divides the angle by the specified amount.

``90.degrees / 4 # => 22.5°``

def /(other : self) : Number #

Divides the angle by another.

``180.degrees / 45.degrees # => 4.0``

def /(other : Angle) : Number #

Divides the angle by another of a different type.

``180.degrees / (Math::PI.radians / 3) # => 3.0``

def //(amount : Number) : Angle #

Divides the angle by the specified amount.

Uses integer division.

``25.degrees // 10 # => 2°``

def //(other : self) : Number #

Divides the angle by another.

Uses integer division.

``30.degrees // 4.degrees # => 7``

def //(other : Angle) : Number #

Divides the angle by another of a different type.

Uses integer division.

``200.degrees // (Math::PI.radians / 3) # => 3``

def <=>(other : self) #

Compares this angle to another.

The return value will be:

• -1 if this angle is less than other.
• 0 if the angles are equal.
• 1 if this angle is greater than other.
``````45.degrees <=> 90.degrees # => -1
60.degrees <=> 60.degrees # => 0
90.degrees <=> 45.degrees # => 1``````

def <=>(other : Angle) #

Compares this angle to another of a different type.

The return value will be:

• -1 if this angle is less than other.
• 0 if the angles are equal.
• 1 if this angle is greater than other.
``````45.degrees <=> (Math::PI).radians     # => -1
180.degrees <=> (Math::PI).radians    # => 0
90.degrees <=> (Math::PI / 4).radians # => 1``````

def abs : self #

Returns the absolute value of the angle.

``-45.degrees.abs # => 45°``

def abs2 : self #

Returns the angle squared.

``5.degrees.abs2 # => 25°``

def acute? #

Returns true if the angle is greater than zero and less than a right-angle (quarter revolution).

``````0.degrees.acute?  # => false
45.degrees.acute? # => true
90.degrees.acute? # => false``````

def ceil : self #

Returns an angle rounded up to the nearest integer.

``25.3.degrees.ceil # => 26.0°``

def floor : self #

Returns an angle rounded down to the nearest integer.

``5.7.degrees.floor # => 5.0°``

def fraction : self #

Returns the fraction portion of the angle's value.

This is effectively equal to:

``fraction(v) = v - floor(v)``
``1.2.degrees.fraction # => 0.2°``

def full? #

Returns true if the angle is a full angle (one revolution).

Multiples of full revolutions are not considered full angles.

``````0.degrees.full?   # => false
360.degrees.full? # => true
720.degrees.full? # => false``````

def lerp(other : self, t : Number) : self #

Calculates the linear interpolation between two angles.

t is a value from 0 to 1, where 0 represents this angle and 1 represents other. Any value between 0 and 1 will result in a proportional amount of this angle and other.

This method uses the precise calculation that does not suffer precision loss from high exponential differences.

def near_zero?(tolerance : self) #

Checks if the angle is close to zero.

The value must be within tolerance of zero.

``````0.degrees.near_zero?(1.degrees)  # => true
1.degrees.near_zero?(1.degrees)  # => true
30.degrees.near_zero?(1.degrees) # => false``````

def near_zero?(tolerance : Angle) #

Checks if the angle is close to zero.

The value must be within tolerance of zero.

``````0.radians.near_zero?(1.degrees)        # => true

def near_zero?(tolerance : Number) #

Checks if the angle is close to zero.

The value must be within tolerance of zero.

``````0.degrees.near_zero?(1)  # => true
1.degrees.near_zero?(1)  # => true
30.degrees.near_zero?(1) # => false``````

def negative? #

Checks if the angle is negative.

``````-5.degrees.negative? # => true
5.degrees.negative?  # => false``````

def normalize : self #

Returns an angle corrected to be between zero and one revolution.

``````30.degrees.normalize  # => 30°
-90.degrees.normalize # => 270°
360.degrees.normalize # => 0°
540.degrees.normalize # => 180°``````

def oblique? #

Returns true if the angle isn't a multiple of a right angle.

``````45.degrees.oblique?  # => true
90.degrees.oblique?  # => false
180.degrees.oblique? # => false
360.degrees.oblique? # => false``````

def obtuse? #

Returns true if the angle is greater than a right angle and less than a straight angle.

``````90.degrees.obtuse?  # => false
135.degrees.obtuse? # => true
180.degrees.obtuse? # => false``````

def positive? #

Checks if the angle is positive.

``````5.degrees.positive?  # => true
-5.degrees.positive? # => false``````

def reflex? #

Returns true if the angle is greater than a straight angle and less than a full angle.

``````180.degrees.reflex? # => false
270.degrees.reflex? # => true
360.degrees.reflex? # => false``````

def right? #

Returns true if the angle is a right angle (quarter revolution).

Multiples of quarter revolutions are not considered right angles.

``````0.degrees.right?   # => false
90.degrees.right?  # => true
180.degrees.right? # => false
270.degrees.right? # => false``````

def round(mode : Number::RoundingMode = :ties_even) : self #

Returns a rounded angle.

See `Number#round` for details.

``90.1.degrees.round # => 90.0°``

def round(digits : Number, base = 10, *, mode : Number::RoundingMode = :ties_even) : self #

Returns a rounded angle.

See `Number#round` for details.

``12.34.degrees.round(1) # => 12.3°``

def sign #

Returns a value equal to its original sign.

1 is used for positive values, -1 for negative values, and 0 for zero.

``-5.degrees.sign # => -1``

def signed_normalize : self #

Returns an angle corrected to be between negative half a revolution to positive half a revolution.

``````30.degrees.normalize   # => 30°
-45.degrees.normalize  # => -45°
360.degrees.normalize  # => 0°
270.degrees.normalize  # => -90°
-225.degrees.normalize # => 135°``````

def straight? #

Returns true if the angle is a straight angle (half revolution).

Multiples of half revolutions are not considered straight angles.

``````0.degrees.straight?   # => false
180.degrees.straight? # => true
360.degrees.straight? # => false``````

def to_f : Float #

Converts the angle to radians and returns it as a floating-point value.

def to_unsafe #

Converts the angle to radians and returns it as a floating-point value.

def value : T #

Underlying value.

def zero? #

Checks if the angle is zero.

``````0.degrees.zero?  # => true
90.degrees.zero? # => false``````