Quick And Simple Bezier Curve Drawing or other
- Posted by begin Jun 16, 2018
- 1586 views
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.