I was planning to use bezier curves to create some interactive visuals using pygame. I ran into this instructive example code by Victor Blomquist. While it is instructive, it is not actually working for me. There are a bunch of problems like capitals where they should not be, and using pointers to objects instead of copies of objects etc. Maybe some of that is just due to a time of 5 years that has passed since that code was written, but who knows where, why, and so forth.
Below is a code that is running for me.
""" bezier.py - Calculates a bezier curve from control points. Depends on the 2d vector class found here: http://www.pygame.org/wiki/2DVectorClass 2007 Victor Blomqvist Released to the Public Domain Updates by Lennart Hilbert 2012 """ import pygame from pygame.locals import * import copy from vec2d import * gray = (100,100,100) lightgray = (200,200,200) red = (255,0,0) green = (0,255,0) blue = (0,0,255) X,Y,Z = 0,1,2 def calculate_bezier(in_points, steps = 30): """ Calculate a bezier curve from 4 control points and return a list of the resulting points. The function uses the forward differencing algorithm described here: http://www.niksula.cs.hut.fi/~hkankaan/Homepages/bezierfast.html """ t = 1.0 / steps temp = t*t in_points = [in_points,in_points,in_points,in_points] f = in_points fd = 3 * (in_points - in_points) * t fdd_per_2 = 3 * (in_points - 2 * in_points + in_points) * temp fddd_per_2 = 3 * (3 * (in_points - in_points) + in_points - in_points) * temp * t fddd = 2 * fddd_per_2 fdd = 2 * fdd_per_2 fddd_per_6 = fddd_per_2 / 3.0 points =  for x in range(steps): points.append(copy.copy(f)) f += fd + fdd_per_2 + fddd_per_6 fd += fdd + fddd_per_2 fdd += fddd fdd_per_2 += fddd_per_2 points.append(f) return points def main(): pygame.init() screen = pygame.display.set_mode((600, 600)) ### Control points that are later used to calculate the curve control_points = [Vec2d(100,100), Vec2d(150,500), Vec2d(450,500), Vec2d(500,150)] ### The currently selected point selected_ind = None clock = pygame.time.Clock() running = True while running: for event in pygame.event.get(): if event.type in (QUIT, KEYDOWN): running = False elif event.type == MOUSEBUTTONDOWN and event.button == 1: for nn,p in enumerate(control_points): if abs(p.x - event.pos[X]) < 10 and abs(p.y - event.pos[Y]) < 10 : selected_ind = nn elif event.type == MOUSEBUTTONDOWN and event.button == 3: x,y = pygame.mouse.get_pos() control_points.append(Vec2d(x,y)) elif event.type == MOUSEBUTTONUP and event.button == 1: selected_ind = None ### Draw stuff screen.fill(gray) if selected_ind is not None: selected_point = control_points[selected_ind] selected_point.x, selected_point.y = pygame.mouse.get_pos() pygame.draw.circle(screen, green, selected_point, 10) ### Draw control points for p in control_points: pygame.draw.circle(screen, blue, p, 4) ### Draw control "lines" pygame.draw.lines(screen, lightgray, False, control_points) ### Draw bezier curve for xx in range(0,len(control_points)-3): # Create a copy of the control points before doing calculations with # them. Otherwise, they will be changed during vector operations. If # copy is executed not element by element, only the pointers to the # vectors are copied, but not the vectors themselves input_copy = [copy.copy(pp) for pp in control_points[xx:xx+4]] b_points = calculate_bezier(input_copy) pygame.draw.lines(screen, red, False, b_points) ### Flip screen pygame.display.flip() clock.tick(100) #print clock.get_fps() if __name__ == '__main__': main()