The full 1.0 release of the Freehand Drawing Library will contain classes for both fixed- and variable-wdith strokes. The latter was the most challenging in terms of implementation, so it was the first entry into the library. Now, my attention is turning towards constant-stroke classes.
Unlike its fixed-width counterpart, I anticipate a wide variety of both algorithms and stroke styles to be employed with fixed-width strokes. In order to avoid bloating the library with one class for every conceivable type of fixed-width stroke, a different architecture is used inside the library.
A BasicStroke class that implements IFreehandDrawable was created that serves as the constant-width counterpart to the Freehand class. Both fixed- and variable-width stroke classes accept the same data providers. To accommodate a wide variety of fixed-width strokes, the StrokeDataVO now contains a reference to a drawing engine of type IDrawingEngine. The fully qualified class name of the IDrawingEngine implementation is assigned before setting the data provider for a BasicStroke. This engine performs the actual drawing while the application interfaces with an IFreehandDrawable instance. The application is thus agnostic to both fixed- and variable-width strokes. A Factory may be employed to return the desired type of stroke based on input properties.
The basic drawing engine is based on simple line segments, i.e. point-to-point. Although occasionally useful, this engine (net.algorithmist.freehand.engine.LineSegments) is intended to serve as a base class for other engines. A smoothed-stroke engine is currently under development, net.algorithmist.freehand.engine.SmoothedStroke . It uses the same smoothing algorithm as the variable-width Freehand stroke, but without the overhead for computing the two splines used to vary stroke width. A screen shot is shown below.
Lang Simplification, discussed in the previous post, should be useful for strokes containing a significant number of straight or nearly-straight sections, such as the rough ‘4’ in the above example.
The drawing engine may be changed during runtime simply by altering the engine reference and re-assigning the stroke data provider. The new engine is applied to all subsequently drawn strokes.