Archive for the 'Code Snippets' Category

Controlling iTunes using Quicksilver… X-Tunes Keystrokes Work!

Thursday, September 20th, 2007

I love X-Tunes, and have been using it on my MacBook Pro, using my old PowerBook's configuration files. Finally, I've gotten tired of the Rosetta-induced weird slowdowns, and other strangenesses associated with it not being Intel-compatible. There is a pretty easy solution using Quicksilver, another app I run in the background. If you are unfamiliar with this software, you should probably take care of that. Anyway, it allows you to assign hotkeys (including my favorite, command-space). The easiest solution is to switch to the iTunes window when you press the combo (X-Tunes switched to it's mini-iTunes window), and then switch back to whatever you were doing on the upstroke (the X-Tunes window would disappear).

Unfortunately, there are no built-in ways to switch to iTunes on the press, and switch back to your app on the release, so I had to roll my own. It is a 27 line interface-less Cocoa script that checks what app is running, if it's iTunes, it switches to the last app in it's memory. If it's not iTunes, then it switches to iTunes, and stores the current app in memory. So, you just set it up to be executed on the press and release of your favorite keystroke. Then, when you press your combo, iTunes pops up (and left/right/up/down control song and volume). Unfortunately, I haven't figured out how to get the return key to trigger the play/pause action only in iTunes. If I come up with something, I'll pass it along.

The Tutorial:

Step 1:

If you don't have it already, download and become familiar with Quicksilver. Then download ITToggle. Decompress them and stick the Release/ITToggle file somewhere where you will remember, say, ~/Library/Application Support/Quicksilver/Scripts/ or ~/Library/Scripts or ~/.bin/ or whatever you're comfortable with. You will have to get to it later, so remember where you stick it.

Step 2:

Enter Quicksilver, and bring up triggers, and select custom triggers.

step2a.jpg

There are a few of my favorite triggers in there, but if you have none, that's OK too. Add a trigger by hitting the "+" icon in the bottom right.
Navigate to ITToggle, using Quicksilver, and as the action select "Run (Shell Script)" (you may have to add the plugin for this), not Open. If you select open, it will open it using Terminal, and that will make the whole thing pointless, because Terminal is totally unnecessary. Make sure it looks like it does here:

step2b.jpg

Step 3:

Now you have the step set up, but there is no trigger associated with it, so we'll have to add one. Double-click the area that is set aside for the "Trigger". This will open up the info drawer, and we can change things from there. Set the keystroke as you wish, and make sure the it it is set up to be on press and release, as seen here:

step3a.jpg

Now it should work (just not from Quicksilver, for some reason), try it from Safari or something. Press should take you there, and release should take you back.

Physically Based Rotation: Take Two

Tuesday, May 15th, 2007


To view this content, you need to install Java from java.com
Keys Source
x axis: w,s rotint
y axis: a,d Matrix
z axis: q,e Quaternion
reset: r Vector
tracing: t Transformation
start/stop: g

Built with Processing

What the hell is going on????

This is a much more telling applet than my previous one, and consequently quite a bit more complicated. It should launch with a random initial condition, but you can customize it as well. First off, read my earlier post about rigid body rotation. At the end of it I noted some issues with the integration algorithm. This new applet addresses this concern. In this applet the same simulation is being performed twice. Once (in red) is the old integration scheme from the earlier applet. It is called Euler integration and very prone to error, as we'll see. The second one, in green, is integrated using Runge-kutta, and the error is much more well managed. The boxes are the actual simulation objects. Projected from the origin are three vectors. The blue one is the angular momentum (specified with the q,w,e,a,s,d keys). The red one is the instantaneous angular velocity as determined by the Euler-integration. The green one is the same, but for the Runge-kutta. The tracings show where these were over time.

What It All Means

If you look at the traced out paths of the two integration methods, you notice two things. The first is that neither of them stay as circles, they both have pretty significant deviations from that, depending on the initial conditions. The second is that the red one spirals away from the green one. This is the bad part of Euler integration, the error is always in one direction, whereas Runge-Kutta has two-way error of much lower order. This means that neither is "perfect" in the sense that they produce 100% exact results, but the green one is much better because it stays confined to a disk. The red one drifts out aimlessly towards the axis of minimum inertia, and stays there afterward. This was probably terribly unclear… leave a comment with questions.

Convincing, Physically-Based Rotation

Thursday, April 12th, 2007


To view this content, you need to install Java from java.com

Keys Source
x axis: w,s inertia
y axis: a,d matrix
z axis: q,e quaternion
reset: r vector

Built with Processing

Tips on using the applet:

If it at first doesn't work, try a shift-reload. To make the block spin, click on the applet, and hit one of the keys that are listed. To see some cool physics at work, press and hold one axis, and then press and hold another axis, so it goes into a real fit. Then you can watch as it stabilizes itself to be rotating around a single, happy, axis.
Note (4/13): My old physics teacher tells me that in the absence of torque this effect shouldn't occur. The axis of rotation should change over time, but it shouldn't tend towards the angular momentum. We are nailing down the reason why this is happening…
Note (4/14): It turns out that the damping effect is coming from my 1-st order Euler integration technique, which is highly inaccurate, especially given the fact that we are only running at about 30fps or so. It is interesting that the errors incurred in this calculation give rise to an almost identical effect as a damping medium such as air.

What's going on:

It can be very difficult to programmatically reproduce realistic free rotation of a rigid body onscreen. Just taking a look at the free rotation of a rectangular prism (a book with a rubber band around it) can really be intimidating. I have searched for a long time for a good way of doing this, and the answer finally came to me: Angular Momentum. Of all the things that are conserved, the least represented in lower-devision physics is angular momentum. Because it is necessarily conserved except in the case of applied torque, you can represent any constant rotational motion simply by having a vector representaton of the angular momentum. This provides a springboard for a host of complex behavior, because no matter what, given a rigid body, angular momentum is conserved. The axis about which an object rotates is not necessarily constant, in fact, it requires extreme symmetry to have an object exhibit this property. The traditional notion that angular momentum = rotational inertia * angular velocity is an extreme simplification, unless you consider the rotational inertia to be a 3×3 matrix. If you do this, given a stored angular momentum, you can invert the matrix, multiply the angular momentum (vector) by it, and you get the angular velocity (vector). This won't be the same at every time step, so you'll have to re-calculate it every time. However, this extra step gives a solid physics foundation for your rotation calculations, gives you an easy way to apply torques and forces to your object, and gives you an easily calculated rotation axis. Storing the inertia tensor (3×3 matrix) in inverted form means that at every frame you just have to perform a single matrix calculation every frame to get the angular velocity of the object.

iPhoto Table Edit

Saturday, December 2nd, 2006

menu.jpgI just finished up work on an iPhoto plugin that allows you to explicitly change various metadata fields in a spreadsheet format. It is a SIMBL-based plugin, and is available for download:

iPhotoTable.tgz

Basic Instructions: Install SIMBL, put iPhotoTable.bundle into /Library/Application Support/SIMBL/Plugins/, launch iPhoto, see the matrix edit function in iPhoto.

You can also change which fields are displayed, as well as which fields are available for batch edit. You can do this with Interface Builder. Simply open up the main "table.nib" file and add tables accordingly. Table Columns should have display titles, and "identifiers" that correspond to the actual metadata field. Elements in the field drop down the title property for metadata field choice, and the Attributed Title as the display name.

Left-Handed DVORAK Keyboards

Wednesday, November 29th, 2006

Keyboards are great, but if you want to use both your keyboard and your mouse effectively, at the same time, you're SOL. You can get expensive, cool, things like the FrogPad, or you can come up with a simpler, cheaper solution. After all, you have all the keys you need on the keyboard that you got with your computer, they are just placed badly for one-handed use! Well, the solution was invented a while ago, by Dvorak. He designed a keyboard layout for folks without a right arm, which is cool, because that arm can then be using a mouse. The actual keyboard layout is documented by the good folks at Wikipedia.

I have made a keyboard layout for MacOSX that transforms your current keyboard into a lefty-dvorak keyboard. Toss it in /Library/Keyboard Layouts/, Log out, log in again, and use a sharpie to write the new letters on your keyboard. You can always take it off with rubbing alcohol later.

Without further ado: Dvorak-Lefty.tgz

Note: Thanks to Tom for pointing out some issues with caps-lock, the new file deals (I hope) with this issue.