import matplotlib.pyplot as plt import numpy as np import sys class Plot: def __init__(self, n): self.fig, self.ax = plt.subplots() self.cid_click = self.fig.canvas.mpl_connect('button_press_event', self.onclick) self.cid_motion = self.fig.canvas.mpl_connect('motion_notify_event', self.on_mouse_move) self.cid_release = self.fig.canvas.mpl_connect('button_release_event', self.on_release) plt.xlim(0, 800) plt.ylim(0, 600) plt.grid() self.line = [] self.controlPoints = [] self.curvePoints = [] self.isDrawing = False self.inputMode = 0 self.n = n def onclick(self, event): if self.inputMode == 0: self.isDrawing = True if self.inputMode == 1 and len(self.controlPoints) < self.n: self.controlPoints.append((event.xdata, event.ydata)) self.drawPlot() def on_mouse_move(self, event): if self.isDrawing: self.line.append((event.xdata, event.ydata)) self.drawPlot() def on_release(self, event): if self.inputMode == 0: self.isDrawing = False self.inputMode = 1 def drawPlot(self): self.ax.clear() self.ax.plot(*zip(*self.line), color='red', label='linia') if len(self.controlPoints) > 0: self.ax.scatter(*zip(*self.controlPoints), color='black', label='Punkty kontrolne') if len(self.controlPoints) >= self.n: t_values = np.linspace(0, 1, num=100) bezier_points = np.array([self.de_casteljau(t) for t in t_values]) self.ax.plot(bezier_points[:, 0], bezier_points[:, 1], color='blue', label='Krzywa Béziera') self.ax.legend() self.ax.set_xlim(0, 800) self.ax.set_ylim(0, 600) self.ax.grid() plt.draw() def de_casteljau(self, t): points = np.array(self.controlPoints) n = len(points) for r in range(1, n): for i in range(n - r): points[i] = (1 - t) * points[i] + t * points[i + 1] return points[0] def run(self): plt.show() n = 10 if len(sys.argv) > 1: n = int(sys.argv[1]) if __name__ == "__main__": plot = Plot(n + 1) plot.run()