Howdy all! And here's a present - my Unistroke Gesture Recognition patchin

cradle's picture

Long time lurker, time to give something back.

So I'm Glenn. And you're all awesome. Especially all of you who put your hard work and ideas out there for others (eg. me!) to learn from.

So, here's something I actually made 1) as a challenge, 2) I wanted it for UI work and 3) to give something back and hope it's useful.

It's a (very) simple gesture recogniser for QC.


Quartz Composer Dollar Gesture Recognizer Plugin

Download from GitHub (grab the newest, SnowLeopard only [maybe Leopard?]) (or find a version attached [GitHub will have newest version most likely])

File contents -

Jestieur.plugin # The plugin! Put in ~/Library/Graphics/Quartz\ Composer\ Plugins/

$1 ObjectiveC.qtz # The demo patch for my plugin (hopefully it works :)

$1 Javascript.qtz # A fun 'trick' where instead of using ObjC, I "eval"'d the JS version

$N Javascript.qtz # same as $1, but for multistroke gestures

Go for it! Play around! If anything goes wrong, read the following essay by me :P

It's massively incomplete, as a problem (?) I have is 'feature creep', so I've tried my hardest to just document my future plans in a file (the README I think atm) and have something working rather than nothing but awesome ideas.

It's a patchin (plugin/patch? confused :S) that implements the $1 Gesture Recogniser (if you haven't heard of it, check it out So props out to those sweet researchers for making their code so available, and encouraging so openly many implementations (even providing pseudo code implementations, with line by line explanation).

It's what is called a unistroke (one line) gesture recogniser, which is scale and orientation independent (i.e. unless you train it with 2 different arrows, it will count arrows of any size and direction as just an 'arrow' with equal success as an identical one)

Suprisingly (or not :P it was a resource frequented when I made it) the Kineme thread mentioning it'd be cool to have as a plugin is Google hit #2 for the implementation. (here's the feature request

I can't take all the credit for this patch, what I did was convert Daniele malcom' Margutti's ObjectiveC implementation of the $1 recogniser (MCGestureRecognizer) into a QC patch (learning ObjC and patch development along the way!), so many thanks to him (go to his site!

This may well be superceded by the/a (requested?) official patch, or it could be further developed from where it is. Depending on the skill level of whoever is taking over the project... if you understand patch design and ObjectiveC better than me (an ObjC virgin) it may be worth starting from scratch. Otherwise, feel free to poke around my code and make any changes you want.

I've put the code up on github (, so feel free to hack away. Note that I've attached a custom GPLesque license to the file. I did this in order to try and respect the rights of the people whom my work is based. Basically if you make money from it you need to release the code back to the community. It's nice to share.

Caveats & Limitations... it's provided AS IS, it may crash ur composition (maybe your whole mac! :( ) and although the only bug I experienced is the one I mention below, I can't and dont't guarantee anything.

Limitations, the gestures are harcoded in a file called "gestures_data.txt". To change the gestures you'll need to modify this semi-cryptic file. An obvious "Next Step" for the patch is to have a learning mode (in fact the GUI.qtz file[s] were initial attempts at a 'top down' interface for such a learning mode)

Also, it's only been tested on Snow Leopard, and only on 32 bit Intel... it should work on 64 bit (it's cross compiled as such) but no promises? ok? good.

It also probably has memory leaks... I'm new to ObjC

--- "patch library empty bug" --- *** If your patch library is empty, restart quartz composer and load the patch library before the composition, this should work... it did for me + As this was my first ObjectiveC patch, the code smells, most notable what I dubbed the "start up" jerk. I think I've put the startup code in the wrong function (initialised at the wrong time :) but I haven't got around to finding where it should go, so it loads the gestures into memory upon loading the patch (i.e. when the patch library loads) rather than when the composition is started. If someone wants to fix this, or to help point me quickly where to make a change, I'm happy to implement any 10 minute fixes going around :P


If I'd had longer, I'd have written a shorter email.

TLDR; install Jestieur.plugin, run $1 ObjectiveC.qtz, make gestures!

QCDollarGestureRecogniser-93425e.zip375.05 KB

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

gtoledo3's picture
Re: Howdy all! And here's a present - my Unistroke Gesture ...

Really cool... the plugin works well for me so far, the javascript, not so much. Thanks.

cybero's picture
Re: Howdy all! And here's a present - my Unistroke Gesture ...

Interesting plugin, the ObjectiveC version works really well.

franz's picture
Re: Howdy all! And here's a present - my Unistroke Gesture ...

that's a valuable first post ! thxxxxx

gtoledo3's picture
Re: Howdy all! And here's a present - my Unistroke Gesture ...

BTW, I don't get any kind of startup hesitation.

When you load plugins into Quartz Composer, you have to stop it and re-open, with a stock install, so you can rest at ease that this particular scenario that you encountered is to be expected. You won't see the plugin in the patch list until the re-start.

Using the kinemecore patch will allow you to load new standard sdk plugins on the fly without closing and re-opening QC (but not the "patch"/skanky sdk plugins that go in the Patches folder).

I'll have to really work on my curly braces! I can't seem to draw that well with a trackpad. There's a few that I just can't seem to get to work (like X), but the ones that I can get to work are pretty reliable. This will be especially cool with OpenCV stuff.