Quick And Simple Bezier Curve Drawing or other

new topic     » topic index » view thread      » older message » newer message

for my CEEMD statistics i needed a Bezier function. i hope somebody else can use it.

-- Graphics Gems 5, Edited by Alan W. Paeth 
-- http://www.amazon.com/Graphics-Version-Morgan-Kaufmann-Computer/dp/0125434553/ 
-- Chapter IV.8  -  Quick And Simple Bezier Curve Drawing 
-- By Robert D. Miller 
 
-- Setup Bezier coefficient array once for each control polygon 
function BezierForm2D(integer NumCtlPoints, object px, object py) 
  atom  choose 
  integer k, n = NumCtlPoints-1 
  object cx = repeat(0.0, NumCtlPoints) 
  object cy = repeat(0.0, NumCtlPoints) 
  for k = 0 to n do 
    if k = 0 then  
      choose = 1.0 
    elsif k = 1 then  
      choose = n 
    else   
      choose *= (n-k+1.0)/ (k*1.0) 
    end if     
    cx[k+1] = px[k+1] * choose 
    cy[k+1] = py[k+1] * choose 
  end for 
  return {cx, cy} 
end function 
 
-- Return ptx,pty, t <= 0 <= 1, t specifies the point on the curve you want to get. t has to be between 0.0 and 1.0. 
-- given the number of Points in control polygon, 
-- BezierForm2D must be called once for any given control polygon 
function BezierCurve2D(integer NumCtlPoints, object cx, object cy, atom t) 
  integer k, n 
  atom t1, tt, u, ptx, pty 
  object bbx = repeat(0, NumCtlPoints) 
  object bby = repeat(0, NumCtlPoints) 
  n = NumCtlPoints-1 
  u = t 
  bbx[1] = cx[1] 
  bby[1] = cy[1] 
  for k = 2 to NumCtlPoints do 
    bbx[k] = cx[k] * u 
    bby[k] = cy[k] * u 
    u *= t 
  end for 
  ptx = bbx[NumCtlPoints] 
  pty = bby[NumCtlPoints] 
  t1    = 1-t 
  tt    = t1 
  k     = n 
  while k >= 0 do 
    ptx += (bbx[k+1] * tt) 
    pty += (bby[k+1] * tt) 
    tt *= t1 
    k -= 1 
  end while 
  return {ptx, pty} 
end function 
 
function CalcBezierCurve(atom x1, atom y1, atom x2, atom y2, atom x3, atom y3, atom x4, atom y4, atom stepSize) 
  atom ptx, pty, oldPtx, oldPty 
  integer k 
  object pnx = repeat(0, 4), pny = repeat(0.0, 4) 
  pnx[1] = x1   pny[1] = y1              --SCREEN COORDINATES 
  pnx[2] = x2   pny[2] = y2 
  pnx[3] = x3   pny[3] = y3 
  pnx[4] = x4   pny[4] = y4 
   
  object bcx = repeat(0, 4), bcy = repeat(0, 4) 
  {bcx, bcy} = BezierForm2D(4, pnx, pny) 
  for k = 0 to stepSize do 
    {ptx, pty} = BezierCurve2D(4, bcx, bcy, k/(stepSize*1.0)) 
  ?"--------------" 
      ?ptx 
      ?pty 
  ?"--------------" 
    if k = 0 then 
      oldPtx = ptx 
      oldPty = pty 
    else 
      -- do something with oldPtx, oldPty, ptx, pty maybe - such as draw a line 
      oldPtx = ptx 
      oldPty = pty 
    end if 
  end for 
  return 1 
end function 
 
?CalcBezierCurve(100,300, 300,100, 500,600, 700,300, 50) 
 
maybe_any_key() 

should you be able to streamline it or make it more phix like please share.

richard

EDIT

You control the interpolation with the stepSize. If you use a small stepSize like 5, you get only 6 points (including start and end point of your screen coordinates) and if you draw lines between the points, it is most likely not a very nice curve. If you use a higher stepSize like 50, you get 51 interpolated points... and your curve looks smoother. the functions allows you to have points that go backward or close the Bezier.

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu