Archive

Archive for March, 2012

Quadratic Arc Decorators for Freehand Drawing Library

March 28, 2012 Comments off

I just finished the first cut at the quadratic arc decorators for the Freehand Drawing Library.  Previously, only solid arcs could be drawn.  The example below shows dashed- and dotted-line decoration applied to arrowed arcs.

The decorators all share a fast, on-the-fly arc-length parameterization utility.  I still have a few tweaks to make to one of the decorators before full production release, but the new library is going out to all beta users this morning.

Based on feedback, I’m going to add one more stroke (Polygonal) and two spline-based drawing engines to the full release.  Because of this new addition, I’m seeking a couple more beta users.  If your drawing requirements could benefit from a variety of splines, including splines that auto-convert to shapes (i.e. lines and quads) for creating dynamic outlines/fills, please e-mail me for more information on entering the beta program.

The beta includes full source code and there is a small, 3-figure license fee.  All beta users get FREE upgrades for life.  Email is theAlgorithmist [at] gmail [dot] com.  Thanks!

Advertisements

Graphing Non-Functions

March 22, 2012 Comments off

My current gig is winding down, so this will probably be the last update on the function graphing engine for a while.  Although the function graphing engine is architected to graph cartesian or parameteric functions, only cartesian functions were supported in the initial release.  All functions defined in XML must implement an IPlottable interface, which means that evaluation and derivative methods are interpreted with y as a strict function of x.  All functions must be marked as cartesian, since a parametric function will not plot in the initial implementation.

What about non-functions, that is cases where y is not strictly a function of x?  As the saying goes, there is always a back door.  Functions may identify themselves as self-plotting.  In this case, the engine does not sample the function.  Instead, it provides the function with all the relevant information regarding the current graph window and calls the function’s plot() method.  A self-plotting function is welcome to draw anything it pleases, including Bezier curves, conic sections, spirals, or even smiley faces 🙂

Problems may arise with derived functions, however, i.e. other functions that derive their visual display from the definition of another function.  A graphical Marker function is a perfect example.  The Marker is an artist-generated, interactive graphic asset that is constrained to the path of another function.  If domain values exist for which there is not a unique range value, then Marker movement is unpredictable.

This example shows how to work around the non-function issue to a degree.  It plots parabolas that open upward, downward, and to the left or right.  More specifically, the parabola directrix is either parallel to the x or y axis.  Parallel to the x-axis is good.  Parallel to the y-axis causes problems.

Suppose we want a Marker constrained to the parabola along with a display of the tangent and normal, as well as the directrix.  The fixed distance from the point on the parabola to the directrix and axis of symmetry is also drawn.

Of the four use cases, the Marker follows y as a function of x in two and x as a function of y in the other two.  We can’t use the function graphing engine to manage the Marker display as it always calls the base function (parabola) eval() method with an input x-coordinate.  The derivative and normal displays won’t work in two cases because dy/dx is not uniquely defined.

In general, the equation of a parabola with vertex (h,k), focus (h,k+p), and directrix y=k-p is given by

(x-h)2 = 4p(y-k)

which allows y to be defined as a function of x, or x as a function of y.  There are really only two use cases requiring consideration, directrix parallel to the y-axis and directrix parallel to the x-axis.  In one case, horizontal mouse movement is used to position the Marker.  Vertical mouse movements control the Marker in the other case.

The custom Marker is composed directly into the custom Parabola function, which is marked as self-plotting.  This function is responsible for creating the Marker and controlling its placement as well as drawing all supporting graphics.

The Parabola function is defined in XML as

<function id=”Parabola” class=”graph.tests.Parabola” params=”h:0,k:0,p:-1,parallelTo:y”>
<lineMetrics thickness=”2″ color=”0xff0000″ />
<data markerParams=”marker:graph.symbols.CustomMarkerSymbol,rolloverColor:0x9ACD32,digits:2″
markerCoord=”1″ >
<directrix thickness=”3″ color=”0x9933CC” alpha=”1″ lineStyle=”line_dashed” dashWidth=”6″ dashSpacing=”4″ />
<lineSet1 thickness=”2″ color=”0x0000ff” />
<lineSet2 thickness=”1″ color=”0x00ff00″ alpha=”0.5″/>
</data>
</function>

and the display is shown below.

The aspect ratio of this graph is not ideal for the example, but it’s adequate for illustrating the example.  Note that the custom Parabola function is welcome to plot not only the parabola, but as many supporting graphics as it likes.  The custom Marker may be dragged along the boundaries of the parabola and rollover displays the current y-coordinate by default.

A simple parameter change,  h:0,k:0,p:1,parallelTo:y, causes the parabola to open to the right.

Parametric function graphing should be supported in the future, providing for a more clean and general-purpose means to plot any general parabola and supporting visuals.  I thought this was an interesting example of how a decent architecture and simple concepts like Composition open up possibilities that do not seem possible based on the defined constraints of an engine.

Next post will be an update on new capability in the Freehand Drawing Library.

Graphing Freeform Functions And Derivative

March 14, 2012 Comments off

I’m currently working on an interactive set of unit tests for the function graphing engine I wrote over three years ago.  We’ve made some hasty modifications to the engine over the last six months and only tested the mods within the actual learning applications.  The engine is now sufficiently complex that I’m worried about making changes in one area that have undesired consequences in another area.

This unit test engine allows any number of specific graph tests to be coded to an IGraphTest interface and added in XML.  The ComboBoxes for selecting graph tests and functions inside those tests are auto-populated based on XML data.

One of my favorite features of the graph engine (and the least tested) is freeform function input.  In the past, freeform functions and parameter values were defined completely in XML, i.e.

<function id=”freeForm1″ class=”graphing.functions.library.FreeFormparams=”1,-1,2,1″>
<data vars=”a,b,c,d,x” function=”a*x + b*x^2 – 3*sin(c*x) + d*x^3″ />
<lineMetrics thickness=”2″ color=”0xff0000″ />
</function>

The data node defines parameters a, b, c, and d that may take on any real value. The independent variable is x.  The params attribute in the function node defines the actual parameter values.  Function parsing is handled by an independent class that may be used in any other application, independent of the graphing engine.

That’s all well and good, but I wanted to test the ability to define functions and parameters programmatically, specifically typing a function into an input text field.  In this test, the XML looks like

<learningObject id=”testGraph” class=”graphing.functions.FunctionPlot”
x=”25″ y=”60″ width=”350″ height=”280″ display=”freeForm” pannable=”true” >

.
.
.

<function id=”freeForm” class=”graphing.functions.library.FreeForm” >
<lineMetrics thickness=”2″ color=”0xff0000″ />
</function>
<function id=”deriv” class=”graphing.functions.library.Derivative”
derivedFrom=”freeForm”>
<lineMetrics thickness=”2″ color=”0x0000ff”/>
</function>

The graph engine displays an initially undefined function (I had to correct a couple of typos to get that to work). A function is defined in XML (the Derivative) that is derived from that undefined freeform function (yes, two more corrections there).

The function is typed into an input box in the test application.  Spinners are used to set parameter values.  The code automatically determines the presence of a, b, c, and d  parameters and disables spinners for which there are no parameters in the function.  That was a little tricky, because of situations where ‘c’ may be used as a parameter or in the function, i.e. sin(c*x) vs. cos(x).

Here is a screenshot of a simple example with the first derivative automatically computed from the freeform function definition.  Each function is coded to a specific interface and must be able to evaluate itself and its first derivative.  Although I’d like to get into symbolic differentiation one day, the current approach is numerical and it uses an adaptive differencing algorithm based on graph scale.

It is, without question, the ugliest demo you will ever see, but its sole purpose is to facilitate rapid unit testing of both new functionality and prior capability that is to be used in new ways.

I’m really liking the freeform graphing now that it can be done purely programmatically and I’ve almost decided to add symbolic differentiation to my bucket list 🙂