[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Circular number system?



Hmm... I'd try something like this:

print 13 % 12
. . . yields 1.

print -1 % 12
. . . yields 11.

print 11 % 12 > 1 % 12
. . . asks if 11 is left of 1 and returns True.

print ( 315 + 360 ) % 360
. . . yields 315

print 666 % 12
. . . yields 6...  :o

2009/2/22 Daniel Jo <ostsol@xxxxxxxxx>:
> What I mean by "circular" is sort of like a clock, where passing the
> upper limit takes one back to the start again.  Two hours passed 11 on
> a 12-hour clock is 1 o'clock.  Similarily three hours before 2 is 11
> o'clock.  Another example is a compass.  Forty-five degrees left of
> north, 0 degrees, is 315 degrees, rather than -45.
>
> My need for it is for the latter example.  In such an example,
> comparisons such as "less-than" and "greater-than" aren't so important
> as "left-of" and "right-of", respectively.  Anything in the range
> [180,360) is left of 0 and anything in the range (0, 180] is right of
> 0.  Similarily, anything in the range [270,360) and [0,90) is left of
> 0.
>
> My implementation is more of a utility class than a data-type:
>
> import math
>
> class RingBase (object):
>    def __init__ (self, lower, upper):
>        self.lower = lower
>        self.upper = upper
>        self.span = upper - lower
>
>    def __call__ (self, value):
>        if value > self.upper:
>            loops = int (value / self.span)
>            return value - self.span * loops
>        if value < self.lower:
>            loops = int (abs (value) / self.span) + 1
>            return value + self.span * loops
>        return value
>
>    def _lo (self, v1, v2):
>        v1 = self (v1)
>        v2 = self (v2)
>        half = self.span * 0.5
>
>        left = v2 - half
>
>        if left < self.lower:
>            if v1 >= self.upper - (v2 - self.lower):
>                return True
>            elif v1 < v2:
>                return True
>        elif v1 < v2 and v1 > left:
>            return True
>
>        return False
>
>    def _ro (self, v1, v2):
>        v1 = self (v1)
>        v2 = self (v2)
>        half = self.span * 0.5
>
>        right = v2 + half
>
>        if right >= self.upper:
>            if v1 <= self.lower + (self.upper - v2):
>                return True
>            elif v1 > v2:
>                return True
>        elif v1 > v2 and v1 < right:
>            return True
>
>        return False
>
> class Ring (RingBase):
>    def __init__ (self, lower, upper):
>        super (Ring, self).__init__ (lower, upper)
>
>    lo = RingBase._lo
>    ro = RingBase._ro
>
> class Radian (RingBase):
>    def __init__ (self):
>        super (Radian, self).__init__ (0.0, 2.0 * math.pi)
>
>    lo = RingBase._ro
>    ro = RingBase._lo
>
> An instance of Ring is callable and is used to clamp a value within
> the Ring's limits.  For example. . .
>
> ring = Ring (0, 12)
> print ring (13)
>
> . . . yields 1.
>
> print ring (-1)
>
> . . . yields 11.
>
> ring.lo (11, 1)
>
> . . . asks if 11 is left of 1 and returns True.
>
> So is there anything else like this out there?
>
> -Daniel
>



-- 
____________________
Jussi Toivola