The Unofficial Newsletter of Delphi Users - by Robert Vivrette




Beziers and Paths

by Clinton R. Johnson - xepol@poboxes.com

I felt it was about time that there were some examples on how to use some of the undocumented features of the graphics API.  Its a shame that Borland declined implementing these features within the TCanvas, as most of them are fairly straight forward.

In the BezierTools unit, I provide 2 procedures for drawing Bezier curves.  Each procedure takes a Canvas and an array of TPoints as parameters.  The Points can either be dynamically declared, or a static array created in a VAR declaration.

A Beziers curve is defined by a start point, and an end point and 2 tension points.  It is possible to draw more than one curve at a time, providing the curves are attached.  The PolyBezier function considers the end point of the previous curve as the start point for the next point.  You would pass the normal 4 points for the first curve, and only 3 points for each curve after that (2 tension points, and a end point).  The rule is : for N Bezier curves, you need 3N+1 points.

The graphics API does not draw filled Bezier curves.  It seemed to me that this would be a neat feature to have, so combined Bezier curves with Paths.  Paths are a type of recording device.  Not a sophisticated as metafiles, but decidedly useful.  Each canvas can only have one path at a time, and you must create the path before you use it.  Paths (generally) can not be saved and replaying into the canvas like metafiles, nor can you move paths easily between canvases like metafiles, bitmaps etc (which is not to say it's impossible, but it requires more coding to accomplish).

You record a path by issuing a BEGINPATH command, with the Canvas handle as a parameter.  You then draw, as normal, onto the canvas.  Once you have completed your figure, call ENDPATH.  If you are going to draw the path as a filled area, you should call CLOSEFIGURE before ENDPATH.  You should use exception handling around a BEGINPATH/ENDPATH pair.  Any drawing to the canvas while a path is being recorded is sent to the path, and not to the canvas it self.

Once you have created a path, you need to draw the path onto the screen.  The two most useful calls are STROKEPATH, and STROKEANDFILLPATH.  STROKEPATH draws path with the current pen(and is not filled), while STROKEANDFILLPATH uses both the pen and brush to provide a filled polygon effect.  I use STROKEANDFILLPATH with the FilledBezier procedure to provide a filled bezier.

I used the TSMPanel to represent the start/end and tension points of the curves.  I turn off any sizing abilities, and ensure that the caption section is high enough to cover the entire control for dragging.  They made idea controls, because I did not need any extra code to move them.  If you have the Plus package for Windows, or IE4.0, turn on Show Window Contents While Dragging for best effect.  You will see the curves redraw AS you drag the control points, not just the results of moving them.

The example I have provided is written in Delphi 3. Click here to download this demo code.