ANN: Equidistant Bezier points

Jim Hurley jhurley at infostations.com
Thu May 26 00:27:40 EDT 2005


The conventional bezier points are very good for drawing the curve. 
They are very dense when the curvature is great and less dense where 
the curvature is small--lots of points where they are needed and 
fewer where they are not needed.

But it is difficult at times to move objects from point to point 
along the bezier curve when then points are spread so unevenly. It 
would *also* be nice to have a set of points spread uniformly along 
the bezier curve.  (Malte Brill and I fussed over this problem some 
time ago.)

I have added the handler below to the bezier curve so that there are 
now an additional set of points available as a custom set 
(equidistantPoints) for use when needed.

To see the stack run this in the message bar:

     go url "http://home.infostations.net/jhurley/EquidistantBezierPts.rev"

The relevant new handler follows.

--Algorithm: Move along the parametric
--curve, x = x(t), y = y(t), from t = 0 to t = 1 and
--set a point when the
--distance from the preceding
--point is just greater than ds.

setEquidistantPoints line 1 of the points of grc "bezierLine"

on setEquidistantPoints tLastLoc
-- where tLastLoc is the first point on the bezier curve.

   put 20 into ds --This can be adjusted to suit your needs.
   put 0 into t

   repeat
     repeat

       put f(t) into tNextLoc
       if dist(tNextLoc, tLastLoc) > ds then exit repeat
       add .01 to t
     end repeat
    -- And, for good measure, a little more accuracy
     subtract .01 from t
    
     repeat
       put f(t) into tNextLoc
       if dist(tNextLoc,tLastLoc) > ds then exit repeat
       add .001 to t
     end repeat
    --Now add the point to the custom set of equidistant poitns.
     put tNextLoc & cr after tListOfEquidistantPts
      --And to begin the loop anew, the next point becomes the last point.
     put tNextLoc into tLastLoc

     if t>1 then exit repeat
   end repeat

--Create the custom variable to hold the points
   set the equidistantPoints of grc "bezierLine" to tListOfEquidistantPts

end setEquidistantPoints


-- These are the parametric equations for the bezier curve.
--  j = 1 gives the x-coor and j = 2 given the y-coor.

function f t
   put 1-t into s
   repeat with j = 1 to 2
     put (s*s*s*item j of pt1 + 3*s*s*t*item j of pt2 + \
         3*s*t*t*item j of pt3 + t*t*t*item j of pt4) into item j of thePt
   end repeat
   return thePt
end f

The non-uniform bezier points are generated from f(t) above with t 
running *uniformly* from 0 to 1
The uniformly space points are generated from f(t) with t chosen to 
produce uniform spacing.



More information about the use-livecode mailing list