Class: Interpolate::Points
- Inherits:
-
Object
- Object
- Interpolate::Points
- Defined in:
- lib/interpolate/base.rb
Constant Summary collapse
- DEFAULT_BLEND =
default blending function, which delegates to the :interpolate method on each given value object
lambda { |value, other, balance| unless value.respond_to? :interpolate raise "found an object (#{value.inspect}) that doesn't respond to :interpolate" end value.interpolate(other, balance) }
Instance Attribute Summary collapse
-
#points ⇒ Object
readonly
Returns the value of attribute points.
Instance Method Summary collapse
-
#at(point, &block) ⇒ Object
(also: #[])
returns the interpolated value at the Numeric point specified, optionally using a given block as the blending function.
-
#blend_with(&block) ⇒ Object
define the blending function to use with this Interpolate::Points object.
-
#initialize(points = {}, &block) ⇒ Points
constructor
creates an Interpolate::Points object with an optional Hash object that specifies key points (Numeric) and associated value objects.
-
#merge(points = {}) ⇒ Object
returns a new Interpolate::Points object with the given key points merged with the original points.
-
#merge!(points = {}) ⇒ Object
merges the given key points with the original points.
Constructor Details
#initialize(points = {}, &block) ⇒ Points
creates an Interpolate::Points object with an optional Hash object that specifies key points (Numeric) and associated value objects
the blend_with Proc can also be given when creating a new Interpolate::Points object
59 60 61 62 63 |
# File 'lib/interpolate/base.rb', line 59 def initialize(points = {}, &block) @points = {} @blend_with = block merge!(points) end |
Instance Attribute Details
#points ⇒ Object (readonly)
Returns the value of attribute points.
43 44 45 |
# File 'lib/interpolate/base.rb', line 43 def points @points end |
Instance Method Details
#at(point, &block) ⇒ Object Also known as: []
returns the interpolated value at the Numeric point specified, optionally using a given block as the blending function
if no key points have been specified, the return value is nil
if one key point has been specified, the return value is the value of that key point
if the given point falls outside the interpolation key range (lower than the lowest key point or higher than the highest key point), the nearest point value is used; in other words, no extrapolation is performed
otherwise, the interpolated value is calculated in accordance with the first of:
* the given block
* the stored blending function, :blend_with
* a call to :interpolate on a key value object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/interpolate/base.rb', line 112 def at(point, &block) # obvious cases first if @sorted.empty? # no key points return nil elsif @sorted.size == 1 # one key point return @sorted.first.last end # out-of-bounds cases next if point <= @min_point # lower than lowest key point return @sorted.first.last elsif point >= @max_point # higher than highest key point return @sorted.last.last end # binary search to find the right interpolation key point/value interval left = 0 right = @sorted.length - 2 # highest point will be included low_point = nil low_value = nil high_point = nil high_value = nil while left <= right middle = (right - left) / 2 + left (low_point, low_value) = @sorted[middle] (high_point, high_value) = @sorted[middle + 1] break if low_point <= point and point <= high_point if point < low_point right = middle - 1 else left = middle + 1 end end # determine the balance ratio span = high_point - low_point balance = (point.to_f - low_point) / span # choose and call the blending function blend = block || @blend_with || DEFAULT_BLEND blend.call(low_value, high_value, balance) end |
#blend_with(&block) ⇒ Object
define the blending function to use with this Interpolate::Points object
setting this to nil
will reset the blending behavior back to calling the default blending function
69 70 71 |
# File 'lib/interpolate/base.rb', line 69 def blend_with(&block) @blend_with = block end |
#merge(points = {}) ⇒ Object
returns a new Interpolate::Points object with the given key points merged with the original points
75 76 77 |
# File 'lib/interpolate/base.rb', line 75 def merge(points = {}) Points.new(points.merge(@points)) end |
#merge!(points = {}) ⇒ Object
merges the given key points with the original points
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/interpolate/base.rb', line 80 def merge!(points = {}) # points must be a Hash raise ArgumentError, "key points must be a Hash object" unless points.is_a? Hash # ensure the points are all keyed Numeric-ally points.each do |key, value| raise ArgumentError, "found a point key that is not a Numeric object: #{key.inspect}" unless key.is_a? Numeric end @points.merge!(points) normalize_data self end |