Advertisement
Guest User

Smooth.py

a guest
Mar 12th, 2012
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.27 KB | None | 0 0
  1. import math
  2.  
  3. METHOD_NEAREST = 0
  4. METHOD_LINEAR = 1
  5. METHOD_CUBIC = 2
  6.  
  7. CLIP_CLAMP = 0
  8. CLIP_ZERO = 1
  9. CLIP_PERIODIC = 2
  10. CLIP_MIRROR = 3
  11.  
  12. CUBIC_TENSION_DEFAULT = 0.5
  13. CUBIC_TENSION_CATMULL_ROM = 0
  14.  
  15. defaultConfig = {
  16.     "method" : METHOD_CUBIC,
  17.     "cubcTension" : CUBIC_TENSION_DEFAULT,
  18.     "clip" : CLIP_CLAMP,
  19. }
  20.  
  21. # Index Clipping Functions
  22. def clipClamp(i, n):
  23.     return max(0, min(i, n-1))
  24.  
  25. def clipPeriodic(i, n):
  26.     i %= n # wrap
  27.     if i < 0:
  28.         i += n # if negative, wrap back around
  29.     return i
  30.  
  31. def clipMirror(i, n):
  32.     period = 2*(n-1) # period of index mirroring function
  33.     i = clipPeriodic(i, period)
  34.     if i > (n-1):
  35.         i = period - i # flip when out of bounds
  36.     return i
  37.  
  38. # Abstract scalar interpolation class which provides common functionality for all interpolators
  39. # Subclasses must override interpolate().
  40.    
  41. class AbstractInterpolator:
  42.     def __init__(self, array, config):
  43.         self.array = array[:] # copy the array
  44.         self.length = len(self.array) # cache length
  45.         if config['clip'] == CLIP_CLAMP:
  46.             self.clipHelper = self.clipHelperClamp
  47.         elif config['clip'] ==  CLIP_ZERO:
  48.             self.clipHelper = self.clipHelperZero
  49.         elif config['clip'] == CLIP_PERIODIC:
  50.             self.clipHelper = self.clipHelperPeriodic
  51.         elif config['clip'] == CLIP_MIRROR:
  52.             self.clipHelper = self.clipHelperMirror
  53.         else:
  54.             raise Exception("The clipping mode {} is invalid".format(config['clip']))
  55.    
  56.     def getClippedInput(self, i):
  57.         """ Get input array value at i, applying the clipping method """
  58.         if 0 <= i < self.length:
  59.             return self.array[i]
  60.         return self.clipHelper(i)
  61.  
  62.     def clipHelperClamp(self, i):
  63.         return self.array[clipClamp(i, self.length)]
  64.     def clipHelperZero(self, i):
  65.         return 0
  66.     def clipHelperPeriodic(self, i):
  67.         return self.array[clipPeriodic(i, self.length)]
  68.     def clipHelperMirror(self, i):
  69.         return self.array[clipMirror(i, self.length)]
  70.     def interpolate(self, t):
  71.         raise Exception("Subclasses of AbstractInterpolator must overrid ethe interpolate() method.")
  72.  
  73. # Nearest neighbor interpolator (round to whole index)
  74. class NearestInterpolator(AbstractInterpolator):
  75.     def interpolate(self, t):
  76.         return self.getClippedInput(round(t))
  77.  
  78. # Linear interpolator (first order Bezier)
  79. class LinearInterpolator(AbstractInterpolator):
  80.     def interpolate(self, t):
  81.         k = math.floor(t)
  82.         a = self.getClippedInput(k)
  83.         b = self.getClippedInput(k+1)
  84.         # Translate t to interpolate between k and k+1
  85.         t -= k
  86.         return (1-t)*a + (t*b)
  87.  
  88. class CubicInterpolator(AbstractInterpolator):
  89.     def __init__(self, array, config):
  90.         self.tangentFactor = 1 - max(0, min(1, config['cubicTension']))
  91.         super(CubicInterpolator, self).__init__()
  92.  
  93.     # Cardinal spline with tension 0.5
  94.     def getTangent(self, k):
  95.         return self.tangentFactor * (self.getClippedInput(k+1) - self.GetClippedInput(k-1))
  96.     def interpolate(t):
  97.         k = math.floor(t)
  98.         m = [self.getTangent(k), self.getTangent(k+1)] # get tangents
  99.         p = [self.getClippedInput(k), self.getClippedInput(k+1)] # get points
  100.         # Translate t to interpolate between k and k+1
  101.         t -= k
  102.         t2 = t*t
  103.         t3 = t*t2
  104.         # Apply cubic hermite spline formula
  105.         return (2*t3 - 3*t2 + 1)*p[0] + (t3 - 2*t2 + t)*m[0] + (-2*t3 + 3*t2)*p[1] + (t3 - t2)*m[1]
  106.  
  107. # Extract a column from a two dimensional array
  108. def getColumn(arr, i):
  109.     return [row[i] for row in arr]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement