Arrowed Lines in Freehand Drawing Library

Drawing lines does not sound very interesting, but in addition to my own app. development, another user expressed a desire for animated arrowed lines.  So, a new two-point stroke has been added to the library.  The TwoPoint class is the base for a family of classes in which a stroke is defined only by a starting point and the current mouse/touch point.

In keeping with the FDL architecture, an engine is assigned to a two-point stroke.  Two engines will be provided in the first release candidate, arrowed lines and arcs.  The start and end arrows are optional, so these engines provide a back-door to drawing lines and arcs.  Not sexy, but the existing line decorators are applicable, so it’s incredibly easy to draw dotted or dashed lines.

Since the point sequence to a stroke may be simulated in an animation, it’s now very easy to draw animated dashed or solid, arrowed lines.  Here is a screen shot from one of the demos.

Injecting a new line decorator is a matter of assigning the fully qualified class name of the decorator,

__data.lineDecorator = “net.algorithmist.freehand.decorators.SolidLine”;

or

__data.lineDecorator = “net.algorithmist.freehand.decorators.DashedLine”;

then, re-assign the stroke’s data provider,

__stroke.data = __data;

There are still a couple beta slots open, so if you are interested in developing a Flex-based application (mobile or otherwise) involving freehand drawing, please contact me at theAlgorithmist [at] gmail [dot] com.  There is a small, three-figure license fee that is a one-time cost.  Beta users get free upgrades for life!

I’ll be posting a roadmap for the anticipated release cycle shortly, so even if you are not interested in Flex/Actionscript development, say tuned.  A subset of the Freehand Drawing Library may be coming for JS or Corona developers.

Image Painting in Freehand Drawing Library

A bonus project is going out to all Freehand Drawing Library beta users this morning.  Currently, the library contains one fixed-width stroke with three drawing engines and three line decorators.  One question arose about how to create different strokes and the role of engines within the architecture.  I also received a comment about an iPad drawing app. that allowed people to ‘stamp’ or ‘paint’ smooth strokes with images.

Having an artist create any variety of cool images in Flash is a no-brainer.  The question is how to stamp that image repeatedly along a smooth stroke.  The answer provides a perfect illustration of stroke creation in the Freehand Drawing Library.  A stroke is designed based on certain desired characteristics, in this case the ability to distribute images along a smooth path.  A stroke engine (that implements IDrawingEngine) is created to match the general characteristics of a stroke.  Not all engines are compatible with all strokes, and that’s fine.

A StampedStroke class (implementing IFreehandDrawable, so it can be used in a Factory) was developed for the desired purpose.  A single engine, Stamp, computes the same smoothed stroke coordinates as the SmoothedStroke engine.  Since nothing is drawn into any graphics context, the concept of line decorators does not apply.  The stroke engine directly instantiates the image symbol and adds it to the display list.

The Stamp engine accepts a single engine parameter, ‘imagestamp’, which is the reference to the symbol created in Flash and exported with a base class that extends MovieClip.  Using the stroke is as simple as instantiation,

private var __stroke:StampedStroke  = new StampedStroke();
private var __data:StrokeDataVO = new StrokeDataVO();

Make sure the stroke engine and symbol are compiled into the SWF,

import net.algorithmist.freehand.StampedStroke;
import net.algorithmist.freehand.symbols.Starburst;

private static const STAMP_ENGINE:Class = Stamp;
private static const STAR_CLASS:Class = Starburst;

Then, inject stroke engine and assign engine parameters,

__data.drawingEngine = “net.algorithmist.freehand.engine.Stamp”;
__data.engineParams = {imagestamp:”net.algorithmist.freehand.symbols.Starburst”};

Assign the data provider for the stroke,

__stroke.data = __data;

Draw, and have fun.  The Stamp engine contains a back door to animating the stroke while it’s being drawn.  I may create an online example since it’s pretty cool 🙂

The library is currently in the final beta phase before RC1.  Because of all the new capability, I’ve opened up several beta slots.   There is a small, three-figure license fee, which is a one-time cost.  All beta testers get free upgrades for life!

Please contact me at theAlgorithmist [at] gmail [dot] com if interested.

New Drawing Engines for Freehand Drawing Library

The upcoming beta for the Freehand Drawing Library now has a single constant-width stroke and three drawing engines.  The basic stroke is architected to work with any drawing engine (IDrawingEngine instance).  The StrokeDataVO contains both the fully qualified class name of the IDrawingEngine instance and an engineParams Object to pass arbitrary parameters to any drawing engine.

The three drawing engines are

1 – SmoothedStroke: Constant-width equivalent of the algorithm used in the variable-width Freehand stroke.  This algorithm allows cusps or sharp angles in the stroke.

2 – ConstantSmoothing:  Same engine as #1 except that smoothing is constant.  Cusps are not possible.

3 – Lagged:  This is an experimental engine that implements lagged smoothing over a small number of prior mouse moves. The entire stroke is redrawn from scratch after every move.  This produces a variety of interesting strokes that move in a serpentine fashion while the stroke is drawn.  I think this one would be fun for a kid’s doodling application.

A screen shot of the lagged drawing engine is shown below.

With the current FDL architecture, all three engines can be interchanged with the same basic, constant-width stroke.  And, each drawing engine can be used with any of the three available line decorators (solid, dashed, dotted).

One stroke, nine different drawings 🙂

I have a few minor details to clean up and then a new beta (0.95) will be released.

Dotted Line Decorator in Freehand Drawing Library

The line decorator architecture in the Freehand Drawing Library is complete, fully documented, and pretty thoroughly tested.  Here is a screenshot from the demo that shows the new dotted line decorator.  The stroke engine is the same for all strokes.

Switching from solid to dashed to dotted lines is simple and the stroke engine is agnostic to how the strokes are drawn.  The code for the radio button handler is provided below (comments and UI-related code are removed)

switch( event.target.id )
{
  case "solid":
    __data.lineDecorator = "net.algorithmist.freehand.decorators.SolidLine";
  break;
  case "dashed":
    __data.lineDecorator = "net.algorithmist.freehand.decorators.DashedLine";
  break;
  case "dotted":
    __data.lineDecorator = "net.algorithmist.freehand.decorators.DottedLine";
  break;
}
__stroke.data = __data;

The decorator classes are either pre-compiled into the app or loaded from a SWF in advance of assigning a decorator. The default solid-line decorator is always available.

The final demo (should be ready this weekend or early next week) will demonstrate a single line decorator with multiple stoke engines.  I’ll release another beta (in advance of the first release candidate) at that time.

Recent Work Measuring Volume

Anyone who has ever played with a chemistry set should enjoy the description of this project 🙂  This learning application teaches students how to measure the volume of regular and irregular objects by their effect on water level in a container.

The application begins in an exploration mode with a layout consisting of a work area and a cabinet containing objects to measure, some containers, and a few tools.

Water may be added to a container from the faucet, which pours at three different rates depending on the slider position.  All water levels and animation were drawn programmatically.  After adding water, the student may drop an object into a container.  Objects may be ‘added’ to empty containers as well.  If any part of the object overlaps a container, it is automatically added to the container.  In addition to collision detection of irregular objects, a general-purpose animation manager was written for this project.  It controlled the animation of objects dropping into containers and setting of a ‘critical’ level, which was used to dispatch an event, from which the rise of the container’s water level was choreographed.  This allows the water level to animate in a reasonable manner and be timed to correspond with the object reaching the water level.

Water level rises in a physically realistic manner in that all objects have a mathematical model; box, cylinder, or spherical.  Depending on the container and object properties, water in a container may not rise by the volume of the object.  For box and cylinder models, computing the water level rise is straightforward. For spherical models, roots of a cubic polynomial must be computed.  I added a cubic root finder to this client’s math library.  Fortunately, the physics of the problem result in only one root, so resolving multiple roots in an interval was not necessary.

Objects are stacked behind containers by default and when the student moves a container with an object ‘inside’ it, the object moves as well.  However, if the student clicks such that the mouse is over the object, the object is moved instead.  This is indicated by a glow filter to inform the student they are about to move the object instead of the container.

Layering, however, is not static.  If an object is released in such a manner that it does not fall into a container, it is immediately layered in front of all containers.  If the same object is later dropped into another container, it is layered behind all containers.

Collision detection includes not only container-object collisions, but detecting when an object is positioned so that it will drop into a container and when a container is in ‘pouring position’ above another container.  Container pouring represented the most intricate part of this application.

Two models are involved in pouring, both of which were supplied by the science curricula manager responsible for this application.  The first involves computing the pouring angle as a function of the horizontal position of each container’s spout.  Given a pouring angle, the second model determines how the ‘side view’ of water in the pouring container is drawn and how much water leaves the container.

This water does not immediately transfer into the destination container.  If water spills from a container in the drag handler, a Timer is initiated whose handler transfers water from a virtual ‘in buffer’ to the destination container according to a pouring constant whose value is container-dependent.  This constant allows certain visual and interactive constraints (such as water not pouring in too fast or too slow into certain containers) to be met.  Adjustment of the water level in the destination container is physically accurate in the presence of contained objects.

In addition to pouring into containers, students may pour water into the sink, which is treated as a faux container for just that purpose.

Overflow from containers is allowed.  Certain containers are allowed to overflow into other containers, as shown below.

Three tools are provided, a Ruler (for measuring object dimensions), an eyedropper (for extraction and addition of tiny amounts of water), and a magnifying glass for measuring the meniscus of water in a graduated cylinder.  The latter is dynamically drawn using a quadratic Bezier, according to properties assigned by the science curricula manager.

The meniscus is shown whenever a specified interior section of the lens is over the actual meniscus in a graduated cylinder.  This test is performed inside the magnifying glass handler using a highly optimized circle-rectangle collision test.  The magnifying glass and containers may establish a two-way connection (think of it as two-way binding) so that if water is added to a graduated cylinder, the magnified meniscus view is dynamically redrawn until the meniscus is ‘out of view’ of the lens.

In addition to the exploration view, the application also contains a test or practice view.

Each problem presents students with a selected number of objects, tools, and containers, sufficient to answer the question.  Answers are deemed correct if they lie within a specified tolerance.  To create a virtually limitless number of questions from a small base, initial volumes and object parameters may be randomized in the question XML.  One example problem is

<question type="answer" number="9" category="all" target="Prism" textBox="true" >    <questionText>
  <![CDATA[To the nearest 0.1 cm <span class='sup'><font size = '+4'>3</font></span>, what is the volume of this rectangular prism?]]>
  </questionText>
  <textBox>
   <![CDATA[cm <span class='sup'><font size = '+4'>3</font></span>]]>
  </textBox>
  <answer tolerance="0.1" />
  <containers />
  <objects>
    <object id="Prism" x="330" y="330">
  <length>
    <generate>3.9 + 0.3*rnd()</generate>
  </length>
<width>
<generate>2.4+ 0.3*rnd()</generate>
   </width>
   <height>
     <generate>7.3 + 0.3*rnd()</generate>
   </height>
  </object>
 </objects>
 <tools>
  <tool id="ruler" x="460" y="300" />
 </tools>
</question>

Whenever a <generate> node is encountered, the parser sends the node’s contents to a specialized method that randomizes a value and generates the numerical value of the node.  That value is either in-lined into question text or used to calculate object volume.

So, each time the student practices in this view, they receive a the same set of questions with differing values.  The code is very efficient in the sense that the same base class for container-object interaction is used to create the two Views.  The hierarchy for lab items is DraggableItem -> LabItem -> Lab Object -> LabContainer.

I suppose you can see why I’ve been so busy for the last couple months 🙂  Going to take a few days off now before returning to work on the Freehand Drawing Library.

Merry Christmas and best wishes for 2012 to all readers.

Dashed Line Decorator in Freehand Drawing Library

I’ve been insanely busy over the last couple months, for which I should be grateful, but at the same time a little bummed over the lack of posts.  Here’s a quick update on the new Decorator architecture in the Freehand Drawing Library.

In the prior post, I mentioned that the drawing algorithm is now abstracted into its own API.  A concrete implementation of any algorithm is injected into the BasicStroke class upon assigning a data provider.  Now, the drawing API itself is abstracted.  Using a Decorator pattern, it is now possible to dynamically change the line drawing style applied inside a specified drawing engine.  This completely separates the algorithm for computing the constituent points of a stroke from the line style used to draw the stroke.

Just like SkinnableComponents in Flex, the stroke algorithm and visual representation are now completely decoupled.  Here is a screenshot for a dashed-line Decorator.  The same smoothed-stroke algorithm for solid strokes is used in this example, except it is now agnostic to how the small line segments are drawn.

I’ll have some additional exciting announcements in the near future.  In the mean time, back to my gig!

Sneak Peek of Constant-Width Strokes in Freehand Drawing Library

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.

Arrowed Bezier

Interestingly, I’ve received three inquiries on this problem in the last month; how do you draw a quadratic Beizer with arrows at each endpoint (pointing in the direction of the Bezier curve)?  Drawing an arrow is pretty simple and everyone interested in this problem posed it as an issue with computing rotation angles.

The problem could be solved with trig, but trigonometry often overcomplicates a problem involving simple vector math.  Suppose you wanted to draw an arrow (equilateral triangle) pointing in the direction of the x axis.  That’s a pretty easy problem.  Suppose you wanted to draw a similar arrow pointing in the direction of the y axis or the negative y axis?  Those are also easy problems.

You are actually drawing an arrow in the direction of a unit vector, using a normal to that unit vector to draw the base.  The base is drawn half the length of a side in the direction of both the positive and negative normal directions.  The tip is drawn at full length in the direction of the primary unit vector.   In the first case, the vector (1,0) serves as a unit vector in the direction of the x axis and (0,1) is the normal vector.

This method could be extended to draw arrows in any arbitrary direction provided you have a unit and normal vector as a frame of reference.  A unit vector is created by normalizing a direction vector and the direction vectors of a quadratic Bezier are easily obtained from its control points.  If the vectors P0, P1, and P2 are the control points of a quadratic Bezier, then one end of the Bezier ‘points’ in the direction of P0-P1 and the other end ‘points’ in the direction of P2-P1.  The normal of a unit vector is trivial given the unit vector x- and y-components since the rotation angle is Π/2.

These concepts are embodied in a very simple demo that was hacked together from some old Degrafa code.  The original person asking this question was using Flex 3, so the primary components in this demo extend Canvas.  It’s a pretty crummy demo as demos go, but I don’t have any more time to put into it.  The demo does, however, illustrate this concept of creating unit and normal vectors that can be very useful in a wide variety of applications.

Here are some screen shots.

The red box is not a true bounding box for the quad. Bezier.  It’s used to create a middle control point and have some control over the shape of the Bezier without having an interactive ‘handle’ at the endpoints (which would obscure the arrows).

Like I said, it’s a pretty sucky demo, but I hope you find the concept of creating arbitrary frames of reference via direction vectors and normals useful in some future context.

Download a .zip of the FXP file here and have fun!

Freehand Drawing Library on iPad

This is my last post before MAX.  Thought I would end the Freehand Drawing Library set of posts with some screenshots of it running on my iPad-2.  I’m running the debug version of the MobileFreehand test and I’m rather satisfied with the performance from Air 2.7.

Sorry for the poor picture quality from my phone camera.  The browser version is running in a window at the upper, left-hand side of the picture.  You can see the iPad-2 leaning against the MBP screen.

I find that I draw better using a stylus on the iPad-2 vs. a mouse with the browser version.  And, yes, it does work just fine with the screen rotated.

The best aspect of this entire project is one central code library (Flex library project) from which a number of targeted (browser, desktop, mobile) applications may be developed.

See you at MAX in a couple days!

Freehand Drawing Library New Features

The top two requests from prior beta users of this library were stroke transforms and the ability to serialize strokes to SVG or FXG format.  The intent is to use the library to create a handrawn stroke as part of a logo, for example, then use a stroke editor for fine tuning.  The stroke is then converted to a String representation (FXG or SVG format), then sent to a server or written to a file in an AIR application.

Here are some screen shots of the serialization demo.  A single stroke is drawn into the Freehand drawing area, as shown below.

After conversion to FXG or SVG, the resulting String is displayed below the Freehand drawing area.  If FXG format is selected, a crude (and I do mean crude) FXG viewer uses the serialized stroke to echo it as a filled Path.

I tested the SVG output by copying and pasting it into an online SVG viewer.

There is one beta slot left, so if you are interested in a license, please contact me at theAlgorithmist [at] gmail [dot] com (serious inquiries only).  Beta users get free upgrades for life.