Archive

Archive for May, 2012

Geometric Shapes in Freehand Drawing Library

May 11, 2012 Comments off

Well, here’s another example that I would not have though appropriate for the Freehand Drawing Library.  Regular  geometric shapes might be drawable as strokes (i.e. press-move-release) with some sort of external control to force straight or constant-angle line segments.  That concept, however, does not seem to fit in a freehand or freeform drawing library.

After some thought, many geometric shapes can be defined (even if somewhat arbitrarily) by a bounding rectangle. The current TwoPoint stroke class could easily be extended to define such a bounding rectangle.  By injecting different drawing engines, it is possible to draw a nearly unlimited number of shapes inside that bounding rectangle.

To illustrate the idea, a GeometricShape class was created that extends TwoPoint.  I developed three sample drawing engines for this stroke, Ellipse, Triangle, and BasicArrow.  Each engine draws the bounding rectangle while the mouse is down and clears it on release.  Pre-draw parameters may be assigned to each engine to further control the shape (i.e. select an isosceles or equilateral triangle or alter arrow shape).

While these engines may seem trivial, they open the door to creating a wide variety of such drawings in the FDL, and, all line decorators are available for each shape.  So, if you want a dashed ellipse or dotted arrow, it’s simply a matter of injecting the desired line decorator.

An astute reader (aka existing beta users) may ask, “what about editing?”  It’s easy to modify or extend these shape drawing engines to return the vertex information for the shape.  This information can be edited and then stored in a value object.  That VO may be sent as auxData in the stroke dataProvider.  If present, the stroke could simply redraw the shape directly from the edited vertex information instead of a bounding rectangle.  It’s all supported in the FDL architecture.

An update is going out to all beta users this morning.

Categories: Flex, Math, Portfolio

Editing A Cubic Bezier Spline

May 7, 2012 Comments off

A couple months ago, this was something I believed I would never say about the Freehand Drawing Library.  Now, the library is and always will be a drawing library. Editing is not part of the core library architecture, however, it is something that requires a level of support inside the library.  In the past, this was accomplished by caching the sequence of mouse motions used to define a stroke.  The points could be edited and manually assigned to a stroke, either all at once or in an ENTER_FRAME event to animate the stroke.

This works cleanly with a simple interface for typical strokes, i.e. touch-move-release motions.  Now that the FDL supports splines and possibly other constructs that stretch the definition of a stroke, what about editing more complex drawings?  I want to maintain a light interface and not make editing operations an integral part of the library.  That inevitably leads to interface and code bloat in an attempt to satisfy every possible combination of customer-created editor.

I think it was the movie ‘War Games’ that popularized the phrase, ‘always leave yourself a back door.’  The back door to stroke manipulation outside normal FDL methods is to use arbitrary name-value parameters.  Every stroke has the ability to access or mutate arbitrary data objects.  It’s only two methods in the API, but they provide a wide variety of capability to custom strokes.

I added a simple spline editor to the PolyLine demo as an illustration.  After creating a spline (by clicking the end button), the knot/tangent display is overlaid on top of the stroke as shown below.

The spline knots are already available since they were manually assigned to the stroke.  The tangent information is entirely encapsulated inside the drawing engine, inside the stroke.  That information is obtained by the demo via a parameter request,

__stroke.getParam( “tangent” + i.toString() );

It is the responsibility of each stroke class to document all custom parameter queries and settings.  The above query returns in- and out-tangent values in an Object and that information is passed to the editor.  Knots may be dragged, which cause a parallel shift in the tangent.  The new knot and tangent information is conveyed back to the stroke with a sequence of parameter settings,

__stroke.params = { “changeKnot”:{vertex:index, x:editor.knotX, y:editor.knotY} };

or

__stroke.params = { “changeInTangent”:{vertex:index, x:editor.inTangentX, y:editor.inTangentY} };

__stroke.params = { “changeOutTangent”:{vertex:index, x:editor.outTangentX, y:editor.outTangentY} };

If a spline drawing engine is assigned to the PolyLine, it passes this information onto the internal FDLIntepolatingSpline instance.  A non-spline engine (line segments) ignores the parameters.

The screenshot below shows the result of a knot drag.

After dragging the middle vertex, the following screenshot shows the result of editing the first-vertex out-tangent.

This is all supported by the existing architecture, but there is one wrinkle.  If the edited spline is to be saved and then redrawn at a future time, we must have the facility to record the tangent edits *and* bypass the tangent Command when the spline is reconstructed.

I added an auxData parameter to the StrokeDataVO, which allows arbitrary auxiliary data to be recorded for a stroke.  It’s easy to deep-copy an Object with a ByteArray, so preserving immutability was no problem.  Now, by adding support for a ‘redraw’ parameter in the PolyLine stroke, the spline can be redrawn with arbitrary tangents supplied by external data instead of the tangents computed by the injected tangent Command.