Я расширяю Numerics методом, который я называю "Boundarize" из-за отсутствия лучшего имени; Я уверен, что для этого есть настоящие имена. Но его основная цель - сбросить заданную точку, чтобы она находилась в пределах границы.
То есть, «оборачивая» точку вокруг границы; если область между 0 и 100, если точка переходит в -1:
-1.boundarize(0,100) # => 99
(переход слишком далеко к отрицательному «оборачивает» точку вокруг точки от максимума).
102.boundarize(0,100) # => 2
Это очень простая для реализации функция; когда число ниже минимума, просто добавьте (max-min), пока оно не окажется на границе. Если число превышает максимум, просто вычтите (max-min), пока оно не окажется на границе.
Одна вещь, которую я также должен учитывать, это то, что есть случаи, когда я не хочу включать минимум в диапазон, и случаи, когда я не хочу включать максимум в диапазон. Это указывается в качестве аргумента.
Однако я боюсь, что моя текущая реализация ужасно, ужасно, крайне неэффективна. И поскольку каждый раз, когда что-то движется на экране, оно должно перезапускать это, это одно из узких мест моего приложения. У кого-нибудь есть идеи?
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)