Module: Sevgi::Function::Math

Included in:
Sevgi::Function
Defined in:
lib/sevgi/function/math.rb

Overview

Numeric and trigonometric helpers used by geometry and DSL code.

Constant Summary collapse

PRECISION =

Default decimal precision used by approximate comparisons.

6

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.precisionInteger

Returns the current thread's default numeric precision.

Returns:

  • (Integer)

    current thread precision, or PRECISION when no override is set



16
17
18
19
20
# File 'lib/sevgi/function/math.rb', line 16

def self.precision
  precision = Thread.current.thread_variable_get(PRECISION_KEY)

  precision.nil? ? PRECISION : precision
end

.precision=(precision) ⇒ Integer?

Sets or clears the current thread's default numeric precision.

Parameters:

  • precision (Integer, nil)

    precision override, or nil to return to PRECISION

Returns:

  • (Integer, nil)

    assigned precision



25
26
27
# File 'lib/sevgi/function/math.rb', line 25

def self.precision=(precision)
  Thread.current.thread_variable_set(PRECISION_KEY, precision)
end

Instance Method Details

#acos(value) ⇒ Float

Returns the inverse cosine in degrees.

Parameters:

  • value (Numeric)

    cosine value

Returns:

  • (Float)

Raises:

  • (Math::DomainError)

    when value is outside -1..1



33
# File 'lib/sevgi/function/math.rb', line 33

def acos(value) = to_degrees(::Math.acos(value))

#acot(value) ⇒ Float

Returns the inverse cotangent in degrees.

Parameters:

  • value (Numeric)

    cotangent value

Returns:

  • (Float)


38
# File 'lib/sevgi/function/math.rb', line 38

def acot(value) = 90.0 - to_degrees(::Math.atan(value))

#approx(float, precision = nil) ⇒ Numeric

Rounds a float with an explicit or thread-local precision.

Parameters:

  • float (Numeric)

    value to round

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Numeric)

    rounded value

Raises:

  • (TypeError)

    when float cannot be rounded



45
46
47
# File 'lib/sevgi/function/math.rb', line 45

def approx(float, precision = nil)
  float.round(precision.nil? ? Function::Math.precision : precision)
end

#asin(value) ⇒ Float

Returns the inverse sine in degrees.

Parameters:

  • value (Numeric)

    sine value

Returns:

  • (Float)

Raises:

  • (Math::DomainError)

    when value is outside -1..1



53
# File 'lib/sevgi/function/math.rb', line 53

def asin(value) = to_degrees(::Math.asin(value))

#atan(value) ⇒ Float

Returns the inverse tangent in degrees.

Parameters:

  • value (Numeric)

    tangent value

Returns:

  • (Float)


58
# File 'lib/sevgi/function/math.rb', line 58

def atan(value) = to_degrees(::Math.atan(value))

#atan2(y, x) ⇒ Float

Returns the quadrant-aware inverse tangent in degrees.

Parameters:

  • y (Numeric)

    y component

  • x (Numeric)

    x component

Returns:

  • (Float)


64
# File 'lib/sevgi/function/math.rb', line 64

def atan2(y, x) = to_degrees(::Math.atan2(y, x))

#cos(degrees) ⇒ Float

Returns the cosine of an angle expressed in degrees.

Parameters:

  • degrees (Numeric)

    angle in degrees

Returns:

  • (Float)


69
# File 'lib/sevgi/function/math.rb', line 69

def cos(degrees) = ::Math.cos(to_radians(degrees))

#cot(degrees) ⇒ Float

Returns the cotangent of an angle expressed in degrees.

Parameters:

  • degrees (Numeric)

    angle in degrees

Returns:

  • (Float)


74
# File 'lib/sevgi/function/math.rb', line 74

def cot(degrees) = 1.0 / ::Math.tan(to_radians(degrees))

#count(length, division) ⇒ Integer

Counts complete divisions in a length.

Parameters:

  • length (Numeric)

    total length

  • division (Numeric)

    division size

Returns:

  • (Integer)

Raises:

  • (ZeroDivisionError)

    when division is zero



81
# File 'lib/sevgi/function/math.rb', line 81

def count(length, division) = (length / division.to_f).to_i

#eq?(left, right, precision: nil) ⇒ Boolean

Compares two numeric values after approximate rounding.

Parameters:

  • left (Numeric)

    left operand

  • right (Numeric)

    right operand

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Boolean)


88
# File 'lib/sevgi/function/math.rb', line 88

def eq?(left, right, precision: nil) = approx(left, precision) == approx(right, precision)

#ge?(left, right, precision: nil) ⇒ Boolean

Checks whether the rounded left operand is greater than or equal to the rounded right operand.

Parameters:

  • left (Numeric)

    left operand

  • right (Numeric)

    right operand

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Boolean)


95
# File 'lib/sevgi/function/math.rb', line 95

def ge?(left, right, precision: nil) = approx(left, precision) >= approx(right, precision)

#gt?(left, right, precision: nil) ⇒ Boolean

Checks whether the rounded left operand is greater than the rounded right operand.

Parameters:

  • left (Numeric)

    left operand

  • right (Numeric)

    right operand

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Boolean)


102
# File 'lib/sevgi/function/math.rb', line 102

def gt?(left, right, precision: nil) = approx(left, precision) > approx(right, precision)

#le?(left, right, precision: nil) ⇒ Boolean

Checks whether the rounded left operand is less than or equal to the rounded right operand.

Parameters:

  • left (Numeric)

    left operand

  • right (Numeric)

    right operand

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Boolean)


109
# File 'lib/sevgi/function/math.rb', line 109

def le?(left, right, precision: nil) = approx(left, precision) <= approx(right, precision)

#lt?(left, right, precision: nil) ⇒ Boolean

Checks whether the rounded left operand is less than the rounded right operand.

Parameters:

  • left (Numeric)

    left operand

  • right (Numeric)

    right operand

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Boolean)


116
# File 'lib/sevgi/function/math.rb', line 116

def lt?(left, right, precision: nil) = approx(left, precision) < approx(right, precision)

#round(float, precision) ⇒ Numeric

Rounds a value only when precision is present.

Parameters:

  • float (Numeric)

    value to round

  • precision (Integer, nil)

    explicit precision, or nil to return float unchanged

Returns:

  • (Numeric)


122
# File 'lib/sevgi/function/math.rb', line 122

def round(float, precision) = precision ? float.round(precision) : float

#sin(degrees) ⇒ Float

Returns the sine of an angle expressed in degrees.

Parameters:

  • degrees (Numeric)

    angle in degrees

Returns:

  • (Float)


127
# File 'lib/sevgi/function/math.rb', line 127

def sin(degrees) = ::Math.sin(to_radians(degrees))

#tan(degrees) ⇒ Float

Returns the tangent of an angle expressed in degrees.

Parameters:

  • degrees (Numeric)

    angle in degrees

Returns:

  • (Float)


132
# File 'lib/sevgi/function/math.rb', line 132

def tan(degrees) = ::Math.tan(to_radians(degrees))

#to_degrees(radians) ⇒ Float

Converts radians to degrees.

Parameters:

  • radians (Numeric)

    angle in radians

Returns:

  • (Float)


137
# File 'lib/sevgi/function/math.rb', line 137

def to_degrees(radians) = radians.to_f * 180 / ::Math::PI

#to_radians(degrees) ⇒ Float

Converts degrees to radians.

Parameters:

  • degrees (Numeric)

    angle in degrees

Returns:

  • (Float)


142
# File 'lib/sevgi/function/math.rb', line 142

def to_radians(degrees) = degrees.to_f / 180 * ::Math::PI

#with_precision(precision) { ... } ⇒ Object

Runs a block with a current-thread precision override.

Parameters:

  • precision (Integer, nil)

    scoped precision, or nil to use PRECISION

Yields:

  • block executed with the scoped precision

Yield Returns:

  • (Object)

Returns:

  • (Object)

    block return value

Raises:



150
151
152
153
154
155
156
157
158
# File 'lib/sevgi/function/math.rb', line 150

def with_precision(precision, &block)
  ArgumentError.("Block required") unless block

  previous = Thread.current.thread_variable_get(PRECISION_KEY)
  Function::Math.precision = precision
  block.call
ensure
  Function::Math.precision = previous if block
end

#zero?(value, precision: nil) ⇒ Boolean

Checks whether a value is approximately zero.

Parameters:

  • value (Numeric)

    value to check

  • precision (Integer, nil) (defaults to: nil)

    explicit precision, or nil to use precision

Returns:

  • (Boolean)


164
# File 'lib/sevgi/function/math.rb', line 164

def zero?(value, precision: nil) = eq?(value, 0.0, precision:)