gbezier0.py

Created by steveg1cmz

Created on August 09, 2023

2.47 KB

Initial Bezier curves (quadratic, cubic, line) implementation, implemented using matplotlib. Tested on Numworks 19 4.0 Tested on Numworks 20.3.2

Only simple parameters are handled (no polybeziers, no full SVG syntax).


# Type your text here
"""Bezier curves implemented using matplotlib.
"""
__version__ = "0.00"

crid="""Bezier V""" +__version__ +"""
© 2023 SteveG1CMZ"""

import matplotlib.pyplot as plt
from time import *

#customise
showme=True #execute main
showaxis=True #default False
#the bezier is normally plotted from 0 to 1
#but changing t0 and t1 allows curve to be
#extrapolated (or partial)
t0=0 
t1=1
tscale=100 #workaround integer steps in python
tstep = 10 #resolution of curve (memory!)
#end custom

P0,P1,P2 = [ (0,0), (2,4), (5,3) ]
PT0,PT1,PT2,PT3= [ (0,0), (2,4), (1,1), (5,3) ]

def bzq1(p0,p1,p2,t):
  if type(p0)==type((0,0)):
    x0,x1,x2 = p0[0], p1[0], p2[0]
    y0,y1,y2 = p0[1], p1[1], p2[1]
    X = bzq1(x0,x1,x2,t)
    Y = bzq1(y0,y1,y2,t)
    return ((X),(Y)) #
  else:
    p = (1-t)**2*p0 + 2*t*(1-t)*p1 + t**2*p2
  return p

 
def bzq(p0,p1,p2):
  global t0,t1,tscale,tstep
  points=[]
  for tt1 in range(t0*tscale,t1*tscale,tstep):
    t = tt1/tscale
    points.append(bzq1(p0,p1,p2,t))
  points.append(p2) #ensure final point reached
  return points

def bzcubic(p0,p1,p2,p3):
  global t0,t1,tscale,tstep
  points=[]
  for tt1 in range(t0*tscale,t1*tscale,tstep):
    t = tt1/tscale
    points.append(bzcubic1(p0,p1,p2,p3,t))
  points.append(p3) #ensure final point reached
  return points

def bzcubic1(p0,p1,p2,p3,t):
  if type(p0)==type((0,0)):
    x0,x1,x2,x3 = p0[0], p1[0], p2[0],p3[0]
    y0,y1,y2,y3 = p0[1], p1[1], p2[1],p3[1]
    X = bzcubic1(x0,x1,x2,x3,t)
    Y = bzcubic1(y0,y1,y2,y3,t)
    return ((X),(Y)) #
  else:
    p = (1-t)**3*p0 + (1-t)**2*3*t*p1 + (1-t)*3*t**2*p2 + t**3*p3
  return p

def gline(pt1,pt2):
  """A cubic can approximate a line.
  """
  return bzcubic(pt1,pt1,pt2,pt2)

def pp(points,color):
  X=[]; Y=[]
  for PT in points:
    X.append(PT[0])
    Y.append(PT[1])
 
  print("X:",X)
  print("Y:",Y)
  plt.axis(showaxis)
  plt.plot(X,Y,color) #,colour
  #plt.plot(*P0)
  #plt.plot(*P1)
  #plt.plot(*P2)
  plt.show()

def example():
  plt.plot([P0[0],P1[0],P2[0]], [P0[1],P1[1],P2[1]],"gray")

  plt.plot([PT0[0],PT1[0],PT2[0],PT3[0] ], [PT0[1],PT1[1],PT2[1],PT3[1] ],"gray")
  L=gline(PT3,[0,0])
  pp(L,"red")
  plt.show()
  start=monotonic()
  points=bzq(P0,P1,P2)
  points3=bzcubic(PT0,PT1,PT2,PT3)
  #print(points)
  mids=monotonic()
  pp(points,"blue")
  pp(points3,"green")
  print(round(1000*(mids-start)),"ms")

  dur=(monotonic()-start)
  print(round(1000*dur),"ms")

if showme or __name__ == "__main__":
  print(crid); sleep(1)
  example()