Ken Shmidheiser wrote: > > Robert, > > I thought I found a simple solution to your problem at (take a look at > the graphic there): > > > <http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=11488&lngWId=1> > > > I spent a little time converting the Planet Source VB code to FB^3, but > in the end came up short. I think it's because VB has the Pset function > which allows the programmer to set any screen pixel, and the closest > equivalent I could find is the Toolbox SetCPixel which apparently plots > points differently. At any rate, I ended up with plotted lines instead > of the bezier curve. I'm posting my code because someone may see the > error of my way and offer a suggestion to get it working properly in FB^3. > Ken, this one works a little better, but it is not like I understand what the code does. I have merely changed all single variables to double. If I remember correctly double vars are faster than single vars in PPC, maybe someone can confirm. I have also declared the local variables between the LOCAL and LOCAL FN statements (i.e. outside the body of the functions) to benefit from the float registers and at last I corrected the bug you were having because you need to specify the type of the value returned by the function appended to its name (! for single, # for double, $ for string) except if it is a long, a short integer or a boolean. Sometimes one misses the obvious... ;-) /* Here is an absolute minimum Cubic Spline routine based on code by Jason Bullen found at: <http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=11488&lngWId=1> It's a VB rewrite from a Java applet I found by by Anthony Alto 4/25/99 Computes coefficients based on equations mathematically derived from the curve constraints, i.e.: Curves meet at knots (predefined points); these must be sorted by X First derivatives must be equal at knots Second derivatives must be equal at knots */ begin globals _nPoints = 7 dim as double x(_nPoints), y(_nPoints) dim as double p(_nPoints), u(_nPoints) end globals begin enum 1 _plotBtn _drawBtn end enum local fn BuildWindow dim as rect r dim as rgbcolor backRGB backRGB.red = 0 backRGB.green = 0 backRGB.blue = 0 setrect( r, 0, 0, 350, 350 ) appearance Window -1, "", @r, _kDocumentWindowClass, _kWindowStandardFloatingAttributes setrect( r, 20, 310, 165, 330 ) button _plotBtn, 1, "Plot control points", @r,_push setrect( r, 175, 310, 330, 330 ) button _drawBtn, 1, "Draw cubic spline", @r,_push DEF SETWINDOWBACKGROUND( backRGB, _true ) window 1 end fn /* FN SetPandU: Function to compute the parameters of our cubic spline. Based on equations derived from some basic facts... Each segment must be a cubic polynomial. Curve segments must have equal first and second derivatives at knots they share. General algorithm taken from a book which has long since been lost. The math that derived this stuff is pretty messy... expressions are isolated and put into arrays. We're essentially trying to find the values of the second derivative of each polynomial at each knot within the curve. That's why there's only N-2 p's (where N is # points). Later, we use the p's and u's to calculate curve points... */ local dim as integer i dim as double d(_nPoints), w(_nPoints) local fn SetPandU for i = 2 to _nPoints - 1 d(i) = 2 * (x(i + 1) - x(i - 1)) next i for i = 1 to _nPoints - 1 u(i) = x(i + 1) - x(i) next i for i = 2 to _nPoints - 1 w(i) = 6# * ((y(i + 1) - y(i)) / u(i) - (y(i) - y(i - 1)) / u(i - 1)) next i for i = 2 to _nPoints - 2 w(i + 1) = w(i + 1) - w(i) * u(i) / d(i) d(i + 1) = d(i + 1) - u(i) * u(i) / d(i) next i p(1) = 0# for i = _nPoints - 1 to 2 step -1 p(i) = (w(i) - u(i) * p(i + 1)) / d(i) next i p(_nPoints) = 0# end fn '~'9 local dim as double F local fn F#( x as double ) F = x * x * x - x end fn = F local dim as double t, curvePt local fn GetCurvePoint#( i as integer, v as double ) // Derived curve equation (which uses p's and u's for coefficients) t = (v - x(i)) / u(i) curvePt = t * y(i + 1) + (1 - t) * y(i) + u(i)¬ * u(i) * (fn F#(t) * p(i + 1) + fn F#(1 - t) * p(i)) / 6# end fn = curvePt '~'9 local dim as integer piece dim as double xPos, yPos dim as rgbcolor foreRGB local fn DoCurve foreRGB.red = 62535 foreRGB.green = 62535 foreRGB.blue = 0 rgbForeColor( foreRGB ) fn SetPandU for piece = 1 to _nPoints - 1 for xPos = x( piece ) to x( piece + 1 ) yPos = fn GetCurvePoint#( piece, xPos ) //Picture1.PSet (xPos, yPos), &H0 SetCPixel( xPos, yPos, foreRGB ) next xPos next piece end fn '~'9 // Function to plot a few points for testing Local dim as long i dim as rgbcolor foreRGB local fn LoadPoints foreRGB.red = 62535 foreRGB.green = 62535 foreRGB.blue = 62535 rgbForeColor( foreRGB ) x(1) = 20: y(1) = 20 x(2) = 50: y(2) = 100 x(3) = 100: y(3) = 30 x(4) = 150: y(4) = 70 x(5) = 200: y(5) = 170 x(6) = 250: y(6) = 20 for i = 1 to _nPoints-1 circle x(i), y(i), 5 next i end fn '~'9 local dim as long evnt, id local fn DoDialog evnt = dialog(0) id = dialog(evnt) select case( evnt ) case _wndClose select( id ) case 1 : gFBQuit = _zTrue end select case _btnClick select( id ) case _plotBtn : fn LoadPoints case _drawBtn : fn DoCurve end select end select end fn '~'9 on dialog fn DoDialog fn BuildWindow do handleevents until gFBQuit end