home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / share / k3d / scripts / animation / keyframes.py
Encoding:
Python Source  |  2008-01-23  |  2.4 KB  |  109 lines

  1. import k3d
  2.  
  3. class control_point:
  4.     def __init__(self, position, weight):
  5.         self.position = position
  6.         self.weight = weight
  7.  
  8. class nucurve:
  9.     def __init__(self, order):
  10.         self.order = order
  11.         self.control_points=[]
  12.         self.knots = []
  13.  
  14. class arc_length:
  15.     def __init__(self, T, Point, Length):
  16.         self.t = T
  17.         self.point = Point
  18.         self.length = Length
  19.  
  20. def basis(i, k, t, knots):
  21.     ret = 0
  22.     if k > 0:
  23.         n1 = (t - knots[i]) * basis(i, k - 1, t, knots)
  24.         d1 = knots[i + k] - knots[i]
  25.         n2 = (knots[i + k + 1] - t) * basis(i + 1, k - 1, t, knots)
  26.         d2 = knots[i + k + 1] - knots[i + 1]
  27.         if d1 > 0.0001 or d1 < -0.0001:
  28.             a = n1 / d1
  29.         else:
  30.             a = 0
  31.         
  32.         if d2 > 0.0001 or d2 < -0.0001:
  33.             b = n2 / d2
  34.         else:
  35.             b = 0
  36.  
  37.         ret = a + b
  38.     else:
  39.         if knots[i] <= t and t <= knots[i + 1]:
  40.             ret = 1
  41.         else:
  42.             ret = 0
  43.     return ret
  44.  
  45.  
  46. def evaluate(Curve, T):
  47.     c = k3d.vector3(0, 0, 0)
  48.     for i in range(len(Curve.control_points)):
  49.         control_point = Curve.control_points[i]
  50.         w = control_point.weight * basis(i, Curve.order-1, T, Curve.knots)
  51.         b = control_point.position * w
  52.         c = c + b
  53.  
  54.     return c
  55.  
  56. def mix(x, y, alpha):
  57.     return x * (1 - alpha) + y * (alpha)
  58.  
  59. def start_t(Curve):
  60.     return Curve.knots[0]
  61.  
  62. def end_t(Curve):
  63.     return Curve.knots[len(Curve.knots)-1]
  64.  
  65. def get_arc_length_detail(Curve, SegmentCount):
  66.     min_t = start_t(Curve)
  67.     max_t = end_t(Curve)
  68.  
  69.     arc_lengths = []
  70.     arc_lengths.append(arc_length(min_t, evaluate(Curve, min_t), 0))
  71.  
  72.     for i in range(1, SegmentCount + 1):
  73.         t = mix(min_t, max_t, float(i) / float(SegmentCount))
  74.         point = evaluate(Curve, t)
  75.         last_arc = arc_lengths[len(arc_lengths)-1]
  76.         arc_lengths.append(arc_length(t, point, last_arc.length + k3d.length(point - last_arc.point)))
  77.         
  78.     return arc_lengths
  79.         
  80. def get_arc_lengths(Curve, MaxError):
  81.     segment_count = 4
  82.  
  83.     last_arcs = get_arc_length_detail(Curve, segment_count)
  84.     last_length = last_arcs[len(last_arcs)-1].length
  85.     last_error = last_length
  86.  
  87.     while last_error / last_length > MaxError:
  88.         segment_count *= 2
  89.         
  90.         arcs = get_arc_length_detail(Curve, segment_count)
  91.         length = arcs[len(arcs)-1].length
  92.         error = length - last_length
  93.  
  94.         last_arcs = arcs
  95.         last_length = length
  96.         last_error = error
  97.  
  98.     return last_arcs
  99.  
  100. def get_uniform_arc_length_position(Arcs, Length):
  101.     for i in range(1, len(Arcs)):
  102.         if Length <= Arcs[i].length:
  103.             u = (Length - Arcs[i-1].length) / (Arcs[i].length - Arcs[i-1].length)
  104.             return mix(Arcs[i-1].point, Arcs[i].point, u)
  105.  
  106.     return Arcs[len(Arcs)-1].point
  107.  
  108.  
  109.