views:

30

answers:

2

I'm extending Numerics with a method I call "Boundarize" for lack of better name; I'm sure there are actually real names for this. But its basic purpose is to reset a given point to be within a boundary.

That is, "wrapping" a point around the boundary; if the area is betweeon 0 and 100, if the point goes to -1:

-1.boundarize(0,100)        # => 99 

(going one too far to the negative "wraps" the point around to one from the max).

102.boundarize(0,100)       # => 2

It's a very simple function to implement; when the number is below the minimum, simply add (max-min) until it's in the boundary. If the number is above the maximum, simply subtract (max-min) until it's in the boundary.

One thing I also need to account for is that, there are cases where I don't want to include the minimum in the range, and cases where I don't want to include the maximum in the range. This is specified as an argument.

However, I fear that my current implementation is horribly, terribly, grossly inefficient. And because every time something moves on the screen, it has to re-run this, this is one of the bottlenecks of my application. Anyone have any ideas?

module Boundarizer

  def boundarize min=0,max=1,allow_min=true,allow_max=false 

    raise "Improper boundaries #{min}/#{max}" if min >= max
    raise "Cannot have two closed endpoints" if not (allow_min or allow_max)

    new_num = self

    if allow_min
      while new_num < min
        new_num += (max-min)
      end
    else
      while new_num <= min
        new_num += (max-min)
      end
    end

    if allow_max
      while new_num > max
        new_num -= (max-min)
      end
    else
      while new_num >= max
        new_num -= (max-min)
      end
    end

    return new_num

  end

end

class Numeric
  include Boundarizer
end

0.boundarize(10,50)             # => 40
10.boundarize(0,10)             # => 0     (the maximum is by default not allowed)
0.boundarize(0,20,false)        # => 20    (the minimum is not allowed)
A: 

your operation is pretty much the modulo operation see here.

Ruby provides the operator % for that.

tliff
+2  A: 

It looks to me like all you need is modulo (% operator) with a couple of extra checks to handle allow_min and allow_max:

irb(main):002:0> -1 % 100
=> 99
irb(main):003:0> -101 % 100
=> 99
irb(main):004:0> 102 % 100
=> 2
Alex - Aotea Studios
holy crap, modulo. I'm stupid.
Justin L.