Module: PerfectShape::Math
- Defined in:
- lib/perfect_shape/math.rb
Overview
Perfect Shape Math utility methods
Mostly ported from java.lang.Math: docs.oracle.com/javase/8/docs/api/java/lang/Math.html
Also includes standard Ruby ::Math utility methods
Class Method Summary collapse
- .const_missing(constant) ⇒ Object
-
.degrees_to_radians(degrees) ⇒ Object
converts angle from degrees to radians (normalizing to BigDecimal).
-
.ieee754_remainder(x, y) ⇒ Object
(also: ieee_remainder)
Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard.
- .method_missing(method_name, *args, &block) ⇒ Object
-
.normalize_degrees(angle) ⇒ Object
Normalizes the specified angle into the range -180 to 180.
-
.radians_to_degrees(radians) ⇒ Object
converts angle from radians to degrees (normalizing to BigDecimal).
- .respond_to?(method_name, include_private = false) ⇒ Boolean
Class Method Details
.const_missing(constant) ⇒ Object
108 109 110 |
# File 'lib/perfect_shape/math.rb', line 108 def const_missing(constant) ::Math::const_get(constant) end |
.degrees_to_radians(degrees) ⇒ Object
converts angle from degrees to radians (normalizing to BigDecimal)
36 37 38 |
# File 'lib/perfect_shape/math.rb', line 36 def degrees_to_radians(degrees) (Math::PI/BigDecimal('180'))*BigDecimal(degrees.to_s) end |
.ieee754_remainder(x, y) ⇒ Object Also known as: ieee_remainder
Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard.
Algorithm is exactly: x – (round(x/y)*y)
The ‘round` part rounds to the nearest even number when it is a halfway between n & y (integer + 0.5 number)
The remainder value is mathematically equal to x - y × n, where n is the mathematical integer closest to the exact mathematical value of the quotient x/y, and if two mathematical integers are equally close to x/y, then n is the integer that is even. If the remainder is zero, its sign is the same as the sign of the first argument. Special cases:
If either argument is NaN, or the first argument is infinite, or the second argument is positive zero or negative zero, then the result is NaN.
If the first argument is finite and the second argument is infinite, then the result is the same as the first argument.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/perfect_shape/math.rb', line 78 def ieee754_remainder(x, y) x = BigDecimal(x.to_s) y = BigDecimal(y.to_s) return BigDecimal::NAN if x.nan? || y.nan? || x.infinite? || y.zero? return x if x.finite? && y.infinite? division = x / y rounded_division_low = BigDecimal(division.floor) rounded_division_high = BigDecimal(division.ceil) rounded_division_half = rounded_division_low + 0.5 rounded_division = if division == rounded_division_half rounded_division_low.to_i.even? ? rounded_division_low : rounded_division_high else BigDecimal(division.round) end (x - (rounded_division * y)) end |
.method_missing(method_name, *args, &block) ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/perfect_shape/math.rb', line 100 def method_missing(method_name, *args, &block) if ::Math.respond_to?(method_name, true) ::Math.send(method_name, *args, &block) else super end end |
.normalize_degrees(angle) ⇒ Object
Normalizes the specified angle into the range -180 to 180.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/perfect_shape/math.rb', line 41 def normalize_degrees(angle) angle = BigDecimal(angle.to_s) if angle > 180.0 if angle <= (180.0 + 360.0) angle = angle - BigDecimal('360.0') else angle = Math.ieee_remainder(angle, 360.0) # IEEEremainder can return -180 here for some input values... angle = BigDecimal('180.0') if angle == -180.0 end elsif angle <= -180.0 if angle > (-180.0 - 360.0) angle = angle + BigDecimal('360.0') else angle = Math.ieee_remainder(angle, 360.0) # IEEEremainder can return -180 here for some input values... angle = BigDecimal('180.0') if angle == -180.0 end end angle end |
.radians_to_degrees(radians) ⇒ Object
converts angle from radians to degrees (normalizing to BigDecimal)
31 32 33 |
# File 'lib/perfect_shape/math.rb', line 31 def radians_to_degrees(radians) (BigDecimal('180')/Math::PI)*BigDecimal(radians.to_s) end |
.respond_to?(method_name, include_private = false) ⇒ Boolean
96 97 98 |
# File 'lib/perfect_shape/math.rb', line 96 def respond_to?(method_name, include_private = false) super || ::Math.respond_to?(method_name, include_private) end |