In [32]:
%matplotlib inline
import numpy
import pylab
import matplotlib.pyplot as plt
class Key:
def __init__(self):
self.time = 0
self.in_tangent = numpy.array([0, 0, 0])
self.out_tangent = numpy.array([0, 0, 0])
self.value = numpy.array([0, 0, 0])
class CurveSplineBezier:
def __init__(self):
self.keys = []
self.plt = plt
self.setup_plot()
def matrix(self):
return numpy.matrix(
(
(-1, 3, -3, 1),
( 3, -6, 3, 0),
(-3, 3, 0, 0),
( 1, 0, 0, 0)
)
)
def start_time(self):
return self.keys[0].time
def end_time(self):
return self.keys[-1].time
def number_of_keys(self):
return len(self.keys)
def get_key_time(self, index):
return self.keys[index].time
def set_key_time(self, index, time):
if self.keys[index - 1].time > time:
return False
self.keys[index].time = time
def get_key_value(self, index):
return self.keys[index].value
def set_key_value(self, index, value):
self.keys[index].value = value
def evaluate(self, time):
if len(self.keys) < 1:
return False
elif len(self.keys) < 2:
return self.keys[-1].value
elif (
time < self.keys[0].time
or
time > self.keys[-1].time
):
return False
if time == self.keys[0].time:
return self.keys[0].value
if time == self.keys[-1].time:
return self.keys[-1].value
for index, key in self.keys:
if time >= key.time and time < self.keys[index + 1].time:
current_time = (time - key.time) / (self.keys[index + 1].time - key.time)
return self.interpolate(index, index + 1, current_time)
def setup_plot(self):
self.plt.margins(0.1)
self.plt.grid()
def interpolate(self, start_key, end_key, time):
matrix = self.matrix()
t3 = time**3
x = t3 * matrix[0].A[0][0] + t3 * matrix[1].A[0][0] + t3 * matrix[2].A[0][0] + t3 * matrix[3].A[0][0]
y = t3 * matrix[0].A[0][1] + t3 * matrix[1].A[0][1] + t3 * matrix[2].A[0][1] + t3 * matrix[3].A[0][1]
z = t3 * matrix[0].A[0][2] + t3 * matrix[1].A[0][2] + t3 * matrix[2].A[0][2] + t3 * matrix[3].A[0][2]
w = t3 * matrix[0].A[0][3] + t3 * matrix[1].A[0][3] + t3 * matrix[2].A[0][3] + t3 * matrix[3].A[0][3]
start = self.keys[start_key].value
end = self.keys[end_key].value
out_tangent = self.keys[start_key].out_tangent
in_tangent = self.keys[end_key].in_tangent
return np.array([
x * start[0] + y * end[0] + z * out_tangent[0] + w * in_tangent[0],
x * start[1] + y * end[1] + z * out_tangent[1] + w * in_tangent[1],
x * start[2] + y * end[2] + z * out_tangent[2] + w * in_tangent[2]
])
def add_key(self, key):
new_key = Key()
new_key.time = key.time
new_key.in_tangent = (key.value - key.in_tangent) * 3
new_key.out_tangent = (key.out_tangent - key.value) * 3
if len(self.keys) > 0:
if self.keys[-1].time < key.time:
self.keys.append(new_key)
return
elif self.keys[0].time > key.time:
self.keys.insert(0, new_key)
return
for index, key_ in self.keys:
if key_.time > key.time:
self.keys.insert(index, new_key)
return
else:
self.keys.append(new_key)
In [39]:
key0 = Key()
key0.value = numpy.array([1, 1, 0])
key1 = Key()
key1.value = numpy.array([2, 3, 0])
curve = CurveSplineBezier()
curve.add_key(key0)
#curve.add_key(key1)
Out[39]:
In [ ]: