
# animInterp.py
# Andrew Davison, Sept. 2025, ad@coe.psu.ac.th

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


def animate(frame):
  # Update the plot in each animation frame
  t = frame / 100.0    # Time parameter from 0 to 1

  if t == 0:
   curveXs[:] = []  # reset the curve data
   curveYs[:] = []

  # Linear interpolation between P0 and P1 to find point A
  Ax = (1-t)*P0[0] + t*P1[0]
  Ay = (1-t)*P0[1] + t*P1[1]
  
  # Linear interpolation between P1 and P2 to find point B
  Bx = (1-t)*P1[0] + t*P2[0]
  By = (1-t)*P1[1] + t*P2[1]
  
  # Linear interpolation between A and B to find final point P
  Px = (1-t)*Ax + t*Bx
  Py = (1-t)*Ay + t*By
  
  # Update interpolation line AB
  lineAB.set_data([Ax, Bx], [Ay, By])
  
  # Update point P
  ptP.set_data([Px], [Py])
  
  # Add point P to curve
  curveXs.append(Px)
  curveYs.append(Py)
  bezCurve.set_data(curveXs, curveYs)
  
  return lineAB, ptP, bezCurve


# ----------------------------
# three control points
P0 = [0, 0]
P1 = [0.5, 1]
P2 = [1, 0]

curveXs = []
curveYs = []

fig, ax = plt.subplots(figsize=(6, 6))
ax.set_aspect('equal')
ax.set_xlim(-0.1, 1.1)
ax.set_ylim(-0.1, 1.1)

# Plot the control points
ax.plot([P0[0], P1[0], P2[0]], [P0[1], P1[1], P2[1]], 'o--', 
       color='gray', label='Control Points')
ax.text(P0[0], P0[1], ' P0', fontsize=12)
ax.text(P1[0], P1[1], ' P1', fontsize=12)
ax.text(P2[0], P2[1], ' P2', fontsize=12)

# the lines and points being animated
lineAB, = ax.plot([], [], 'o--', 
      color='lightcoral', label='Interpolation Line')

ptP, = ax.plot([], [], 'o', 
      color='purple', markersize=8, label='Point P')

bezCurve, = ax.plot(curveXs, curveYs, '-', 
      color='darkviolet', lw=2, label='Bezier Curve')

ani = FuncAnimation(fig, animate, frames=101, 
                    interval=25, blit=True)

ax.set_title('Quadratic Bezier Curve Animation')
ax.grid(True)
ax.legend()
plt.show()