This is a strange one. Strange, and interesting. This class creates an object which returns a logarithmic progression of numbers over a period of time. It allows the target value to change, causing the progression of values to speed up, slow down, or even reverse. Why is this useful? Read on below for more...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
import time from math import log class LogarithmicProgression(object): """ A time determinant logarithmic progression, with a movable target and energy factor. """ def __init__(self, position=1, target=1, energy=1): self.position = float(position) self.target = float(target) self.energy = float(energy) self.distance = abs(self.target - self.position) self._lastCall = time.time() def next(self): if self.target < 0: modTarget = self.target - 1 else: modTarget = self.target + 1 self.distance = d = abs(modTarget - self.position) if d == 0: return 0.0 amount = log(d) increment = amount * ((time.time() - self._lastCall) * self.energy) if self.position < modTarget: self.position += increment else: self.position -= increment self._lastCall = time.time() return increment if __name__ == "__main__": i = LogarithmicProgression(position=0,target=2, energy=1) s = time.time() for c in xrange(1, 100): time.sleep(0.1) i.next() print "0-%.2f in %.2f seconds" % (i.position, time.time() - s)
I use this class to control the acceleration of values from an initial value to a set value, where the set value is or can be constantly changed.
Eg. In a car simulation, this class could be used to simulate the logarithmic acceleration of a vehicle. When a user step's on the gas, the target attribute is set to a higher value than the current position. The position attribute will increase logarithmically until position == target. A user may decrease the throttle, which will decrease the target. This causes the position to decrease, logarithmically, until the is target is again reached (position == target).
As the LogarithmicProgression is 'time determinant', many calls to the .next() method simply results in finer position increments, which will increase the resolution of the progression, rather than create a faster progression. To modify the speed of a progression, the energy attribute can be used. Use this attribute with care, as it is simply a coefficient of the time between .next() calls, and can cause the position to bounce or vibrate around the target.
NB: The car simulation I refer to is a game, not a scientfic, accurate simulation. I use the LogarithmicProgression() simply as an approximation of a vehicle's acceleration.