AS3 Developer Position in Houston

One of my best clients, an agency in Houston, has an opening for an AS3 developer.  If you are available and in the Houston area (locals strongly preferred), then send me an email at theAlgorithmist[at]gmail[dot]com.  You should have the following background.

A firm foundation in OOP and event-driven programming with demonstrable expertise developing highly interactive applications in AS3.  You should know something about basic design patterns.  Flash 10 experience is a bonus.  Mobile is an even bigger bonus, but not a requirement.  You need to have experience in creating reusable components and helping designers with modest scripting skills create visual elements to be integrated into a larger application.  You also need to know how and when to hack something quick to make a deliverable on a short time frame.

Flex/FlashBuilder IDE experience is valuable, but not required (i.e. creating Actionscript projects and integrating visual content created by designers using Flash CS4/CS5).  Flex framework experience is a bonus but not required.

Any experience you have using third-party AS3 libraries and extending them to create new functionality is highly desirable.  You will be required to work with such libraries developed by me 🙂

Don’t send me a resume.  Resumes are B.S. documents created for HR people and managers that want buzzwords and other B.S.  Show me an online blog/portfolio or something that demonstrates your skills.  Then, we’ll talk.  I will forward promising candidates onto my client.

I’ve worked with this company for over six years and can vouch that although an agency environment can be challenging, these people are absolutely great to work with.  Looking forward to hearing from you.

Efficient Programming Practices

Shane McCartney has created a high-level presentation (about 136 slides total) on efficient programming practices.  Experienced Flash developers may already know most or all of these, but you never know when a good tip might pop up in one of these slides, so check it out and see what you think.

View presentation here.  Actual performance tests are available here, although I have not had time to independently review them all in detail.

New Degrafa Math Utilities

If you update your code base from SVN, there should now be a com.degrafa.utilities.math folder with some new goodies.  These are low-level math utilities that will be used in upcoming advanced versions of the quad/cubic Bezier classes and Bezier utilities such as closest point to a quad/cubic Bezier.

Current methods include

Bisect – classic bisection algorithm for locating a root within an interval

Gauss – Numerical integeration using Gauss-Legendre

Newton – Simple implementation of Newton’s method

Halley – Simple implementation of Halley’s method

SimpleRoot – AS3 port of Jack Crenshaw’s TWBRF

Solve2x2 – Solve 2×2 systems of equations using Cramer’s method, with support for caching determinant.

A simple test program (MXML file) illustrating the usage of these methods can be downloaded here.  These are very low-level utilities that will be used in future Degrafa development and may be of value to advanced users.

Text Along Spline Code Part IV

Continuing the code deconstruction from this post, the second pass of the algorithm is split into two parts.  The first distributes text up to the final knot in the spline.  The second part handles the case where the text extends beyond the natural spline boundaries.  This is done by using the curve’s orientation toward the end of the spline to extend the text in a straight line in that direction, as shown in this post.

The code segment for the first part of phase 2 is,

// second pass - place text along spline
var s:Number              = 0;
var endX:Number           = __spline.getX(1);
var endY:Number           = __spline.getY(1);
var cacheRotation:Boolean = true;
var rotation:Number       = 0;

for( i=0; i<__myText.length; ++i )
{
  tf = __letters[i];

  if( s <= 1 )
  {
    var myX:Number = __spline.getX(s);
    var myY:Number = __spline.getY(s);
    if( s < 0.95 )
    {
      var dX:Number  = __spline.getX(s+0.05) - myX;
      var dY:Number  = __spline.getY(s+0.05) - myY;
    }
    else
    {
      dX = endX - __spline.getX(0.94);
      dY = endY - __spline.getY(0.94);
    }

    // normalize
    var d:Number  = Math.sqrt(dX*dX + dY*dY);
    var uX:Number = dX/d;
    var uY:Number = dY/d;

    tf.rotation         = Math.atan2(dY, dX)*Consts.RAD_TO_DEG;
    var myWidth:Number  = tf.textWidth;
    var myHeight:Number = tf.textHeight;

    tf.x = myX + myHeight*uY;
    tf.y = myY - myHeight*uX;
  }

The variable, s, denotes arc length along the spline.  The variables, endX and endY record the coordinates of the spline at s=1 (or the endpoints).  The Boolean variable, cacheRotation istrue if we are using a constant (precomputed) rotation value, which is the case when the text extends beyond the end of the spline.  The rotation variable denotes the rotation of the TextField for each letter distributed along  the spline.

This block of code,

if( s <= 1 )
  {
    var myX:Number = __spline.getX(s);
    var myY:Number = __spline.getY(s);
    if( s < 0.95 )
    {
      var dX:Number  = __spline.getX(s+0.05) - myX;
      var dY:Number  = __spline.getY(s+0.05) - myY;
    }

estimates the tangent to the curve at the current s parameter.  The cumulative text width is multiplied by the inverse of arc-length to estimate the s-parameter corresponding to the beginning of each letter, as previously described.  We could use the Singularity method that returns the derivative of the spline at the parameter value (which is the slope of the tangent), however, I wanted this code block to be usable with other packages that draw Bezier curves.  Most of those packages do not return derivative information, so it is estimated by dy/dx ~ Δy/Δx for small Δx.

The tangent of the spline at s is used to orient the TextField to align with the tangent at that point.  This is just a starting-point for aligning the text and works reasonably well except in places where the spline has extremely high curvature.  Understanding this first approximation is helpful before delving into more complex algorithms.

A unit vector in the direction of the tangent approximation is computed next and the TextField’s rotation property is set,

var d:Number  = Math.sqrt(dX*dX + dY*dY);
var uX:Number = dX/d;
var uY:Number = dY/d;

tf.rotation   = Math.atan2(dY, dX)*Consts.RAD_TO_DEG;

Note the use of the atan2() function.  The x- and y-components of the unit vector are used to compute the normal vector, which is needed to position the TextField.  This will be discussed in the next part of the deconstruction.

Text Along a Spline IV

In many practical circumstances, the amount of text to be distributed along a curved path exceeds the length of the path. It is possible to extrapolate parametric curves beyond the normal [0,1] domain, however, arc-length parameterization applies only to the restricted domain. Arc-length parameterization is necessary to uniformly distribute text along the curve.

One reasonable compromise is to use the tangent approximation at the end of the curve to extrapolate along a straight line. This approach is also computationally efficient as a single unit vector and normal can be reused for each letter distributed along the line.

This approach is illustrated below.

I still have one small glitch to work out with this approach and then I will put the text-along-spline code on the back burner.  The next big priority is to help the Degrafa team start to move Singularity code into the Degrafa code base.  The first step in this process will be to rewrite the cubic Bezier spline to be independent of the current Composite class.  Although I can’t predict every possible porting issue, at a high level it should be largely a matter of replacing the FastBezier class with the Degrafa cubic Bezier class.

At least that’s the way it looks on paper 🙂  More to come later!

Spline Tangents Part III

Once again, there were a few questions regarding this post; namely, how to draw the normal vector to the spline.  One person suggested using the fact that slopes of perpendicular lines are negative reciprocals.  Since we already know the slope of the tangent line, we know the slope of the normal line (although there are numerical issues with near or exactly vertical tangents).

That’s a good suggestion for a starting point.  An alternative is to use the fact that we have unit vectors in the tangent direction both ‘away’ and ‘toward’ the direction the curve moves with increasing parameter value.  The 2D rotation matrix corresponding to rotations of +/- PI/2 is particularly simple. We can rotate the already computed unit vectors and then determine a point along the normal the same distance as along the tangent line.  This is illustrated below,

Normal to a spline
Normal to a spline

The issue here is that the normal will flip when passing through a parameter value corresponding to a vertical tangent.  The reason is a subject for another post at another time. You are welcome to download the updated code from the Downloads section and experiment with both approaches. In the mean time, I’m hoping that the demo that created this series in the first place will be completed by the weekend or early next week.

Spline Tangents Part II

I received a couple questions regarding this post relative to computing the angle of the tangent line relative to the horizontal. It’s a matter of a little trig once you recall the geometric interpretation of a curve’s derivative at a point.  Our old friend, Math.atan2() is just what the doctor ordered.  To illustrate, I modified the demo code to use the Singularity Wedge class to show the angle relative to the horizontal as shown below.

Angle tangent segment makes with the horizontal axis
Angle tangent segment makes with the horizontal axis

The wedge is redrawn dynamically as the slider moves.  Once you know the tangent orientation, you also know the normal orientation.  Along with arc-length parameterization, this means that sprites can be precisely distributed along and aligned to the spline.  Stay tuned for more …