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.

Blogging Year in Review

I never thought much about blog statistics over the prior year until receiving a WordPress summary.  The reflection also caused me to think hard about where I want to take this blog in the upcoming year.  So, here’s a brief look back and a brief look ahead.

Over 230,000 visits to this blog were logged in 2011, not very impressive as I suspect there are many top programmers who receive that many visits in one or two months.  For a blog devoted primarily to applied math with the occasional tennis diversion, I felt that was better than expected.

The most visitors came from the US, followed by the UK, India, South America, and Australia.

The top referring sites were my business site, algorithmist.net, followed by degrafa.org, Facebook, Stack Overflow, and Flashbookmarks.

The most traffic came from search engines and the top search terms were black mathematicians, puremvc tutorial, TRON Clock, and Prince EXO 3 Black.  Where’s my sponsorship from Prince?

The top two posts were from the TRON Clock demo and the top blog commenter was friend and fellow developer, PolyGeek.  I’m guessing he’ll be the first person to respond to this post 🙂

In terms of traffic, the top four posts were Flex-related and number 5 was the Babolat RPM Blast review.  OK, where’s my Babloat sponsorship?

In terms of 2012, I’ll be working a lot on the Freehand Drawing Library and app. development, so I expect personal blog posts to decline.  I’m considering guest posts as a means to keep the content fresh and give others a shot at some exposure.  So, if you are interested in writing posts on applied math or general programming/algorithm topics and have either a resume or personal site to display your background, please email me at theAlgorithmist [at] gmail.com with the subject ‘Guest Posting on The Algorithmist.’  All posts will contain a link to your personal site or a brief bio.

I’ve received a few requests to do a series on vector math and computational Geometry in Javascript.  I probably won’t be able to devote time to this until Q2, but it’s at the top of the ‘new topics.’ list.  Please feel free to suggest other topics of interest and thanks for your visits.  Hope you found something interesting or useful.

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.

Function Graphing Update Part II

I’ve been very quiet over the last few months, and for good reason.  Just finished a gig involving two pretty complex learning applications for physical science.  I worked on one as a primary developer, and the function graphing engine I authored was used in another.  This is the first of a couple posts summarizing the work before returning to development of the Freehand Drawing Library.

The prior update on the function graphing engine was summarized in this post. This particular learning application involves chemical reactions and equilibrium.  A simulation is started in one tab, as shown below.

Depending on the simulation length, a substantial number of molecules may interact in a single time step.  Clicking on the Graph tab shows a real-time line plot of the state of various reactions.

The x-axis is time steps and the programmer plots the most recent N steps.

A new addition to the graphing engine is the ability to adjust x- and y-axis bounds and tic marks independently.  This provides highly customizable zoom capability.

The graph may be panned by dragging, and panning is setup in XML to be restricted to the first quadrant.

This was a very interesting project both because I enjoyed working with the other application developer and to see a cool use of the function graphing engine.

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.

TinyTLF 2 Explorer App

Paul created a cool demo to explore some of the new features in TinyTLF V2.0 (still in beta).  The circular region demo (yes, we can do the equivalent of CSS Regions right now in Flash) has been expanded.

Check out the blog post here and enjoy!

Update:  For those who have asked, a new version of the demo with text constrained by spline boundaries is in the works, but scheduled for after the V2 formal release.

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!

TinyTLF 2.0 is in Beta

I’ve given several Freehand drawing demos on my iPad-2 here at MAX, but one of the things I’ve failed to mention is the impending release of TinyTLF V2.0.   You can read about the new features and implementation details here.

Paul and I recently collaborated on another organic text layout demo.  I really like it when Paul does all the hard work and I come in at the tail end and wrangle some equations (a bit of analytic geometry).  Where do I get more gigs like that?

Anyway, here’s a demo of the new layout algorithm for organic text.  Given the even lighter weight of the 2.0 code base, I’m envisioning a lot of interesting mobile applications 🙂