class NumScaler
See {file:README.md} for practical examples.
Constants
- EPSILON
Epsilon defines rounding precision
- MODES
Available clamping modes
- VERSION
NumScaler
version string
Public Class Methods
new(from, to, options = {})
click to toggle source
Additional ‘options`:
* `:mode` - specify clamping mode (*default: `:strict`*) * `:precision` - specify Float rounding (*default: `EPSILON`*)
Precision defines number of significant decimal digits for rounding.
Current clamping modes:
* `:strict` - raise ArgumentError for out-of-range number (*default*) * `:clamp` - clamp number to source range * `:cycle` - treat range as a circle of values
@param from [Range] source range @param to [Range] target range @param options [Hash] additional options
# File lib/numscaler.rb, line 28 def initialize(from, to, options = {}) @mode = options[:mode] || MODES.first @prec = options[:precision] || EPSILON raise ArgumentError, 'Unknown mode' unless MODES.member? @mode raise ArgumentError, 'Precision out of range' unless @prec > 0 @src = { :orig => from.min, :range => from.max.to_f - from.min.to_f, :max => from.max.to_f, :min => from.min.to_f } @tgt = { :orig => to.min, :range => to.max.to_f - to.min.to_f, :max => to.max.to_f, :min => to.min.to_f } end
Public Instance Methods
from(num)
click to toggle source
Convert number from source to target
@param num [Numeric] @return [Numeric]
# File lib/numscaler.rb, line 49 def from(num); calc(num, @src, @tgt); end
to(num)
click to toggle source
Convert number from target to source
@param num [Numeric] @return [Numeric]
# File lib/numscaler.rb, line 55 def to(num); calc(num, @tgt, @src); end
Private Instance Methods
calc(num, a, b)
click to toggle source
Perform actual calculation:
1. First check and if necessary apply clamping 1. Then convert between ranges 1. Lastly check how to exactly return the result and do so
@param num [Numeric] number to convert @param a [Hash] source range data @param b [Hash] target range data @return [Numeric]
# File lib/numscaler.rb, line 68 def calc(num, a, b) num = num.to_f unless num.between?(a[:min], a[:max]) num = case @mode when :cycle ((num - a[:min]) % (a[:range])) + a[:min] when :clamp num > a[:max] ? a[:max] : a[:min] when :strict raise ArgumentError, 'Number out of range' end end res = (((num - a[:min]) * b[:range]) / a[:range]) + b[:min] case b[:orig] when Integer res.round else res.round(@prec) end end