Simple gesture recognition in AS3

A few years ago I coded a simple AS2 gesture recognition package in the hope I could use it in the future. Well. 5 years have passed. No real project have ever made use of it, except a small prototype for a (successful) pitch for Nintendo… well… you know… they’ve got that little DS thing… seemd appropriate, I guess. As often though, that which have been pitched wasn’t built, and the whole gesture/drawable UI component got ditched. And now I need this thing to work again, and I’m scared to even take a look at the old AS2 base code. Well it turns out, that stuff (in this simple form) isn’t really complicated and rewriting the whole thing from scratch didn’t take long at all.

Gesture recognition, the basic kind

Get Adobe Flash player

GestureRecognition.swf, draw the symbols

How it works

This gesture recognition method is done in three steps:

  • Capture user input
  • Homogenize and normalize input
  • Match to a predefined pattern

The first step is trivial and won’t be discussed. The second step is best described with a diagram. I chose to use an approach relying on a line segment/circle intersection algorithm. The goal is to get a path defined by equally distanced points, scaled to fit a 1×1 square. We can obtain this by iterating through the initial path, and finding intersections with a circle of radius r. This radius is very simply determined by dividing the length of the initial path by the number of points desired in the resulting path.

Note that the simplified path is most certainly going to be shorter than the initial path as a result of the process (see the diagram). In some occasions, the final path will effectively “miss” points. In this implementation we stop as soon as there is no intersection left with the next circle. We could think of lots of complicated and/or “expensive” ways to get that done more accurately. But really, as will show the next diagram, this does not affect the recognition itself.

Processing user input, for a simple gesture recognition engine

Processing user input

Once we have a normalized path, we can find a matching pattern in the dictionary. Comparing the data sets is now simply a matter of comparing where the points are relatively to each other within this 1×1 square.

Finding a match, for a simple gesture recognition engine

Finding a match

Since the points are ordered (there is a first point and a last point, and the order matters) we can find the average distance between the paths. We can expect the best matching pattern to have the lower average distance between its points and the normalized user generated path, as pictured on the diagram.

Note that the implementation I propose shows no optimization whatsoever. It will bluntly go through each and every pattern in the dictionary. There is also a total lack of quality control (or threshold value) regarding the “best match”. Whatever you draw, a match will be found. I personally think it is the way it should work, but well, you can disagree and add some extra checks yourself (see in the source, there are a couple hints on where to look).

I can see two very easy ways to optimize the search though. The relative position of the first points is absolutely important. Should you draw one of these symbols backwards, matching exactly the shape, well… it’s very unlikely it’ll be the best match. We can easily extrapolate that too great of a distance between the first points should discard the pattern (let’s say something like >=.5). What is also meaningful is the length of these paths, which should be “close enough”. A very first check combining a comparison in length and relative position of first points could discard a good number of irrelevant patterns. Then… we can look for the best match in whatever remains. Writing this, I suddenly feel like implementing it. Well. I certainly will if this gets used, as I hope, in a real project. Which, yes, is still up in the air.

Useful links

Github repo (includes rough gesture creation tool)
Paul Bourke’s line/sphere intersection algorithm

Posted in ActionScript 3 | 20 Comments

Traer AS3, the mandatory cloth simulation

I believe every single particle engine starts with that as an example: the classic cloth-like simulation. The original Traer.physics package has it. So here it is, adapted from the original source code. But since just lines and dots don’t really make the thing look like anything, I added some GraphicsTrianglePath goodness in there. The mesh is only made of a 8×8 particles grid, or 128 triangles when rendered, which really isn’t much!

Get Adobe Flash player

ClothTriangles.swf, drag handles to move

The source code for this is part of my Traer.physics port to ActionScript3, and is available at Github. There really isn’t much to it, but if you haven’t yet used GraphicsTrianglePath or this little physics package, then it’s probably an okay-ish place to start.

Useful links

Github repo for TraerAS3
Livedocs about GraphicsTrianglePath

Posted in ActionScript 3, Traer AS3 port | 11 Comments

Traer.physics port to AS3

Long-time Processing users probably remember Traer.physics, one of the first physics libraries for Processing, written in Java by Jeffrey Traer Bernstein. It was widely used long before the incredibly useful and much-larger-in-scope ToxicLibs were around. So what is it? A very simple particle system.

As Jeffrey puts it on his project page:

“All this is supposed to do is let you make particles, apply forces and calculate the positions of particles over time in real-time. Anything else you need to handle yourself”.

And well, this is, in my opinion, the beauty of it. Traer physics is really a lot of fun to play with. Granted, there isn’t a lot provided. A ParticleSystem class. A Particle class. Spring and Attraction (which acts also as repulsion by negating a value). That’s pretty much it. But it’s way more than enough to provide a sandbox to come up in no time with new ideas for interaction. Or cool visuals. Or whatever.

What’s in it?

ParticleSystem

This is where everything starts. It provides a dead easy API. The methods listed below are pretty much all you need to know get started:

  • ParticleSystem(gravity:Vector3D, drag:Number); // constructor
  • ParticleSystem.makeParticle(mass:Number, position:Vector3D):Particle;
  • ParticleSystem.makeSpring(a:Particle, b:Particle, springConstant:Number, damping:Number, restLength:Number):Spring;
  • ParticleSystem.makeAttraction(a:Particle, b:Particle, strength:Number, minDistance:Number):Attraction;
  • ParticleSystem.tick(t:Number):void; // advances the simulation by an amount of time
  • ParticleSystem.addCustomForce(f:Force):void; // this is how you add your custom designed forces that implement Force

Of course, a complete API to add/remove/get/set particles, forces, and various settings is provided (i.e. getSpring, getParticle, removeSpringByReference, removeParticleByReference…).

Particle

Can be fixed or free using Particle.makeFixed() and Particle.makeFree(), and have mass and age properties.

Integrator

Your choice of RungeKuttaIntegrator (more stable, more precise, slower) or ModifiedEulerIntegrator (fast, less precise, at times barely stable).
Hmm… What does stability mean? We’re talking about numerical stability here. The wikipedia entry for the Euler method explains very well what it means. In short, there is a correlation in the magnitude of errors occurring and the time increment used when calling ParticleSystem.tick(t). On top of that, some situations will make the integrator simply fail. Oh no worries. You’ll see… particles supposedly fixed flying around and your entire simulation exploding. Fun times! Ways of controlling your system’s stability include choosing a smaller time increment (slowing down the simulation) and add more drag to the system (making it harder for the particles to freely move).

Force

Spring and Attraction are provided. You are more than encouraged to create your own forces by implementing the Force interface.

The port, some nitty gritty details

Some changes to the API were necessary since ActionScript3 doesn’t allow for method overload. Traer.physics being originally written in Java, well, these were all over. I had to limit the options available.

I also chose not to use the original package custom vector class, since AS3 provides a standard Vector3D. This should make it easier to plug into this package other libraries. That change means the position property of Particle is actually a flash.geom.Vector3D.

ParticleSystem uses vector quantities to store particles and forces. Vector.<Particle>, Vector.<Spring>, Vector.<Attraction>, Vector.<Force> have been used where the original code uses Java’s ArrayList.

Examples

I included a bunch of examples in the package. I will post some explanations regarding some of them shortly. These include an orb web like little toy, a tribute to Yugo’s Wonderwall, and yes, the mandatory cloth simulation.

Oh, you may want to see a little something right away don’t you? Here are 700 free floating particles. Incredibly boring, but so little code was written for that!

Get Adobe Flash player

FreeFloating.swf, hover to disturb

What’s missing/What’s next?

Proper ASDocs and unit testing. I’ll try to get that done at some point… Performance tuning/optimization. I’m sure there’s a *lot* of room for improvement. Oh, and more examples!

Remind me again, why porting it?

Quite some time ago I used to play a lot with this package in Processing. I loved it. Some of the little experiments I did at this time… I thought… Damn, I wished Flash could handle that. Now I guess it can. Now, too, Jeffrey released the source code. I had to port over this thing to AS3, mostly for the fond memories I had of it. As a tribute to the good old times where people like Jeffrey, among others, were shaping what Processing is now: the enabler of data visualization for a wide and diverse crowd with only one requirement: a curious mind.

Useful links

Get the source + examples: Github repo
Traer.physics: the original package
Processing
Toxiclibs
http://en.wikipedia.org/wiki/Numerical_stability
http://en.wikipedia.org/wiki/Euler_method
http://en.wikipedia.org/wiki/Runge-Kutta_method

Posted in ActionScript 3, Traer AS3 port | 2 Comments

Stitching planes seamlessly in FP10: 3D grass

There is one thing I really wanted to do as soon as the Flash Player 10 was released, before getting familiar with the power behind GraphicsTrianglePath, and that was to stitch Sprite instances together seamlessly in one direction. I think the simplicity of the technique is interesting and relevant is peculiar cases, so here it is.

Before looking at the extremely simple math behind it, here’s the use I made of it: Randomly generated grass stands, in a billboarding fashion.

Get Adobe Flash player

GrassPatch.swf, click and drag to rotate

Again, way better results would be obtained with GraphicsTrianglePath. Oh, yup, and the code -you will soon realize- is quite messy, this is really only a quick and dirty proof of concept. Alright. Enough disclaimers, how is this little thing done? Since we know the planes will be aligned along X, all we need to do is to find the correct y and z positions, as shown in this diagram:

How to stitch planes together in Flash

How to stitch planes together in Flash

Assuming the registration point of our sprites is at their center, and that we want to align these planes vertically, then we really want to translate C1 to C0. P0 is known to us. P1 is an arbitrary position (we’ll use the sprite’s local coordinates to find C1). The orientation of the planes along one axis is known as well (in that case, along Z). The dimensions before any transformation, is also known for both sprites (segment length).
So really, all we’ve got to do is to find C0 and C1, and translate C1 to C0.

C0.y = P0.y + Math.sin(theta) *(length*.5);
C0.z = P0.z + Math.cos(theta)*(length*.5);
C1.y = P1.y + Math.sin(omega+Math.PI)*(length*.5);
C1.z = P1.z + Math.cos(omega+Math.PI)*(length*.5);

We can now translate P1 to C1. There are many ways to do this. In the provided code, y is first set to -i*length then the difference between C0 and C1 is added to this (effectively translating from an incorrect guessed position to the correct position):

P1.x = P0.x;
P1.y = -i*length + (C0.y - C1.y);
P1.z = C0.z - C1.z;>

Useful links

Get the source: Git repo on github
Wikipedia, about billboarding
Livedocs, about GraphicsTrianglePath

Posted in ActionScript 3 | Leave a comment