This commit is contained in:
Frank DeMarco 2014-01-18 21:57:58 +09:00
parent a60c234c5f
commit c2f80332b2
1 changed files with 59 additions and 20 deletions

View File

@ -29,10 +29,14 @@ class Nodeset(list):
LINEAR, CUBIC = range(2)
def __init__(self, name, raw):
def __init__(self, name, nodes, method=None):
list.__init__(self, [])
self.name = name
self.parse_raw(raw)
if isinstance(nodes, str):
self.parse_raw(nodes)
else:
self.parse_list(nodes)
self.interpolation_method = method
self.set_splines()
def parse_raw(self, raw):
@ -42,7 +46,26 @@ class Nodeset(list):
else:
self.interpolation_method = self.CUBIC
for node in raw[1:].strip().split(","):
self.append(Node(node))
self.add_node(map(float, node.strip().split()), False)
def add_node(self, coordinates, refresh=True):
x = coordinates[0]
inserted = False
for ii, node in enumerate(self):
if x < node.x:
self.insert(ii, Node(coordinates))
inserted = True
break
elif x == node.x:
return
if not inserted:
self.append(Node(coordinates))
if refresh:
self.set_splines()
def parse_list(self, nodes):
for node in nodes:
self.add_node(node)
def set_splines(self):
if self.interpolation_method == self.LINEAR:
@ -111,8 +134,8 @@ class Nodeset(list):
class Node(list):
def __init__(self, raw):
list.__init__(self, (float(value) for value in raw.strip().split()))
def __init__(self, coordinates):
list.__init__(self, coordinates)
def __getattr__(self, name):
if name == "x":
@ -172,7 +195,6 @@ class GUI(GameChild):
self.set_nodeset_index()
self.subscribe(self.respond_to_command)
self.subscribe(self.respond_to_mouse_down, MOUSEBUTTONDOWN)
self.subscribe(self.respond_to_mouse_up, MOUSEBUTTONUP)
def load_configuration(self):
config = self.get_configuration("interpolator-gui")
@ -287,23 +309,42 @@ class GUI(GameChild):
nodeset_rect = self.nodeset_label_rect
plot_rect = self.plot_rect
if event.button == 1:
if nodeset_rect.collidepoint(event.pos):
pos = event.pos
if nodeset_rect.collidepoint(pos):
self.set_nodeset_index(1)
redraw = True
elif plot_rect.collidepoint(pos) and \
not self.collide_markers(pos):
xp, yp = pos[0] - plot_rect.left, pos[1] - plot_rect.top
self.get_nodeset().add_node(
self.get_function_coordinates(xp, yp))
self.set_markers()
redraw = True
elif event.button == 3:
if nodeset_rect.collidepoint(event.pos):
pos = event.pos
if nodeset_rect.collidepoint(pos):
self.set_nodeset_index(-1)
redraw = True
elif plot_rect.collidepoint(event.pos):
for marker in self.markers:
if marker.location.collidepoint(event.pos):
self.get_nodeset().remove(marker.node)
self.set_markers()
redraw = True
elif plot_rect.collidepoint(pos):
marker = self.collide_markers(pos)
if marker:
self.get_nodeset().remove(marker.node)
self.set_markers()
redraw = True
redraw and self.draw()
def respond_to_mouse_up(self, event):
pass
def collide_markers(self, pos):
for marker in self.markers:
if marker.location.collidepoint(pos):
return marker
def get_function_coordinates(self, xp=0, yp=0):
nodeset = self.get_nodeset()
(x_min, y_min), (x_max, y_max) = nodeset[0], nodeset[-1]
rect = self.plot_rect
x = float(xp) / (rect.right - rect.left) * (x_max - x_min) + x_min
y = float(yp) / (rect.bottom - rect.top) * (y_min - y_max) + y_max
return x, y
def set_markers(self):
self.markers = markers = []
@ -342,10 +383,8 @@ class GUI(GameChild):
step = 5
for x in xrange(rect.left, rect.right + step, step):
ii = x - rect.left
fx = nodeset.get_y(float(ii) / (rect.right - rect.left) * \
(nodeset[-1].x - nodeset[0].x) + nodeset[0].x)
y = rect.bottom - (rect.bottom - rect.top) * fx / \
(nodeset[-1].y - nodeset[0].y)
fx = nodeset.get_y(self.get_function_coordinates(ii)[0])
y = self.get_plot_coordinates(y=fx)[1]
if ii > 0:
aaline(surface, self.curve_color, (x - step, last_y), (x, y))
last_y = y