Exercise 7: Bézier Curve

Given the vertices of a Bézier polygon (see fig below):

$P 0 = (1; 1)$

$P 1 = (2; 3)$

$P 2 = (4; 3)$

$P 4 = (3; 1)$

Determine 7 points on the Bezier curve defined by these points.


In [82]:
%matplotlib inline
import numpy
import numpy as np
import pylab
import matplotlib.pyplot as plt

class BezierCurve:
    
    def __init__(self):
        self.points = []
        self.plt = plt
        self.setup_plot()
        self.coeff_matrix = None
        self.coefficients = []
        self.matrix = numpy.matrix(
            (
                (-1,  3, -3,  1),
                ( 3, -6,  3,  0),
                (-3,  3,  0,  0),
                ( 1,  0,  0,  0)
            )
        )
        
    def setup_plot(self):
        self.plt.margins(0.1)
        self.plt.grid()
        
    def calculate_coefficient_matrix(self):
        points = numpy.matrix(
            (
                (self.points[0]),
                (self.points[1]),
                (self.points[2]),
                (self.points[3])
            )
        )
        
        self.coeff_matrix = np.dot(self.matrix, points)
        
    def evaluate(self, time):
        time_ = np.matrix([
            [time**3, time**2, time, 1]
        ])
        
        return np.dot(time, self.coeff_matrix)
    
    def calculate_curve_point(self, time):
        return (
            self.points[0] * (1 - time)**3 + 
            self.points[1] * 3 * time * (1 - time)**2 + 
            self.points[2] * 3 * time**2 * (1 - time) +
            self.points[3] * time**3
        )
        
    def plot(self):
        # Plot points
        x = []
        y = []
        for point in self.points:
            x.append(
                point[0]
            )
            y.append(
                point[1]
            )
        plt.plot(x, y, 'ro')
        
        # Prepare data
        self.calculate_coefficient_matrix()
         # Gather data
        plot_data = []
        for t in numpy.linspace(0, 1, 100):
            plot_data.append(
                numpy.dot(
                    numpy.matrix(
                        (
                            (numpy.power(t, 3)),
                            (numpy.power(t, 2)),
                            (t),
                            (1)
                        )
                    ),
                    self.coeff_matrix
                )
            )
        
        x = []
        y = []
        for data in plot_data:
            x.append(data.A[0][0])
            y.append(data.A[0][1])
            
        # Plot
        plt.plot(x, y)

In [83]:
import random

p0 = numpy.array([1, 1])
p1 = numpy.array([2, 3])
p2 = numpy.array([4, 3])
p3 = numpy.array([3, 1])

curve = BezierCurve()
curve.points.append(p0)
curve.points.append(p1)
curve.points.append(p2)
curve.points.append(p3)
curve.plot()

# Determine 7 points on the curve
for i in range(0, 7):
    r = random.random()
    v = curve.calculate_curve_point(r)
    print "Point at {0} is: \n{1}".format(r, v)


Point at 0.213183415858 is: 
[ 1.73713742  2.00641748]
Point at 0.759007068901 is: 
[ 3.25626562  2.09749203]
Point at 0.00562536709187 is: 
[ 1.01697032  1.03356233]
Point at 0.268869213941 is: 
[ 1.94573268  2.17947136]
Point at 0.0892272090839 is: 
[ 1.28872458  1.48759429]
Point at 0.760753565248 is: 
[ 3.25736636  2.09204547]
Point at 0.239112174734 is: 
[ 1.83417582  2.09162526]

In [ ]: