
# ratBez.py
# Andrew Davison, Sept. 2025, ad@coe.psu.ac.th

import math
import matplotlib.pyplot as plt
import bezUtils


def plotRational(ctrlPts, weights, numSamples):
  curveX, curveY = bezUtils.ratBezier(ctrlPts, weights, numSamples)

  plt.figure(figsize=(6, 4))
  
  plt.plot(curveX, curveY, 
          label=f"Rational Bézier Curve (deg {len(ctrlPts)-1})")
  bezUtils.drawControlPts(plt, ctrlPts, weights)
  
  plt.axis("equal")
  plt.title("Rational Bézier Curve")
  plt.grid(True)
  plt.legend()
  plt.show()


'''
# Example 1: cubic rational Bézier
ctrlPts = [(0,0), (1,2), (3,2), (4,0)]
# weights = [1, 0.5, 2, 1]
weights = [1, 1, 1, 1]
plotRational(ctrlPts, weights, 300)

# Example 2: degree 5 rational Bézier
ctrlPts = [ (0,0), (0.5,1.5), (1.5,2.5),
            (2.5,1), (3.5,2), (4,0) ]
weights = [1, 2, 0.3, 1.5, 1, 1]
plotRational(ctrlPts, weights, 400)
'''

# Example 3: circle using four rational Béziers

weights = [1, math.sqrt(2)/2, 1]
cpArcs = [  # control points for each arc
  [(1,0), (1,1), (0,1)],
  [(0,1), (-1,1), (-1,0)],
  [(-1,0), (-1,-1), (0,-1)],
  [(0,-1), (1,-1), (1,0)],
]

# Reference circle
nSamps = 200
thetas = [2*math.pi*i/nSamps 
                     for i in range(nSamps+1)]
xs = [math.cos(t) for t in thetas]
ys = [math.sin(t) for t in thetas]


fig, ax = plt.subplots(figsize=(7, 7))

for ctrlPts in cpArcs:
  curveX, curveY = bezUtils.ratBezier(ctrlPts, weights, nSamps)
  ax.plot(curveX, curveY, 'b')
  bezUtils.drawControlPts(plt, ctrlPts, weights)

# plot the circle
plt.plot(xs, ys, color="orange", lw=5, alpha=0.5)

plt.axis("equal")
plt.title("Circle using four rational Bézier curves")
plt.grid(True)
plt.show()
