https en wikipedia orgwikibc3a9ziercurve https www tutorialspoint comcomputergraphicscomputergraphicscurves htm bezier curve is a weighted sum of a set of control points generate bezier curves from a given set of control points this implementation works only for 2d coordinates in the xy plane listofpoints control points in the xy plane on which to interpolate these points control the behavior shape of the bezier curve degree determines the flexibility of the curve degree 1 will produce a straight line the basis function determines the weight of each control point at time t t time value between 0 and 1 inclusive at which to evaluate the basis of the curve returns the x y values of basis function at time t curve beziercurve1 1 1 2 curve basisfunction0 1 0 0 0 curve basisfunction1 0 0 1 0 basis function for each i the basis must sum up to 1 for it to produce a valid bezier curve the function to produce the values of the bezier curve at time t t the value of time t at which to evaluate the bezier function returns the x y coordinates of the bezier curve at time t the first point in the curve is when t 0 the last point in the curve is when t 1 curve beziercurve1 1 1 2 curve beziercurvefunction0 1 0 1 0 curve beziercurvefunction1 1 0 2 0 for all points sum up the product of ith basis function and ith point plots the bezier curve using matplotlib plotting capabilities stepsize defines the steps at which to evaluate the bezier curve the smaller the step size the finer the curve produced https en wikipedia org wiki b c3 a9zier_curve https www tutorialspoint com computer_graphics computer_graphics_curves htm type ignore bezier curve is a weighted sum of a set of control points generate bezier curves from a given set of control points this implementation works only for 2d coordinates in the xy plane list_of_points control points in the xy plane on which to interpolate these points control the behavior shape of the bezier curve degree determines the flexibility of the curve degree 1 will produce a straight line the basis function determines the weight of each control point at time t t time value between 0 and 1 inclusive at which to evaluate the basis of the curve returns the x y values of basis function at time t curve beziercurve 1 1 1 2 curve basis_function 0 1 0 0 0 curve basis_function 1 0 0 1 0 basis function for each i the basis must sum up to 1 for it to produce a valid bezier curve the function to produce the values of the bezier curve at time t t the value of time t at which to evaluate the bezier function returns the x y coordinates of the bezier curve at time t the first point in the curve is when t 0 the last point in the curve is when t 1 curve beziercurve 1 1 1 2 curve bezier_curve_function 0 1 0 1 0 curve bezier_curve_function 1 1 0 2 0 for all points sum up the product of i th basis function and i th point plots the bezier curve using matplotlib plotting capabilities step_size defines the step s at which to evaluate the bezier curve the smaller the step size the finer the curve produced type ignore x coordinates of points to plot y coordinates of points to plot degree 1 degree 2 degree 3
from __future__ import annotations

from scipy.special import comb  


class BezierCurve:
    

    def __init__(self, list_of_points: list[tuple[float, float]]):
        
        self.list_of_points = list_of_points
        
        
        self.degree = len(list_of_points) - 1

    def basis_function(self, t: float) -> list[float]:
        
        assert 0 <= t <= 1, "Time t must be between 0 and 1."
        output_values: list[float] = []
        for i in range(len(self.list_of_points)):
            
            output_values.append(
                comb(self.degree, i) * ((1 - t) ** (self.degree - i)) * (t**i)
            )
        
        assert round(sum(output_values), 5) == 1
        return output_values

    def bezier_curve_function(self, t: float) -> tuple[float, float]:
        

        assert 0 <= t <= 1, "Time t must be between 0 and 1."

        basis_function = self.basis_function(t)
        x = 0.0
        y = 0.0
        for i in range(len(self.list_of_points)):
            
            x += basis_function[i] * self.list_of_points[i][0]
            y += basis_function[i] * self.list_of_points[i][1]
        return (x, y)

    def plot_curve(self, step_size: float = 0.01):
        
        from matplotlib import pyplot as plt  

        to_plot_x: list[float] = []  
        to_plot_y: list[float] = []  

        t = 0.0
        while t <= 1:
            value = self.bezier_curve_function(t)
            to_plot_x.append(value[0])
            to_plot_y.append(value[1])
            t += step_size

        x = [i[0] for i in self.list_of_points]
        y = [i[1] for i in self.list_of_points]

        plt.plot(
            to_plot_x,
            to_plot_y,
            color="blue",
            label="Curve of Degree " + str(self.degree),
        )
        plt.scatter(x, y, color="red", label="Control Points")
        plt.legend()
        plt.show()


if __name__ == "__main__":
    import doctest

    doctest.testmod()

    BezierCurve([(1, 2), (3, 5)]).plot_curve()  
    BezierCurve([(0, 0), (5, 5), (5, 0)]).plot_curve()  
    BezierCurve([(0, 0), (5, 5), (5, 0), (2.5, -2.5)]).plot_curve()