Thursday
Jul082010

Thank You.

My new favorite tweets.

I released RetroSketch to the App Store last week. I am very proud of it's minimal interface. But I have found a major problem with its lack of chrome– I have no place to thank all the people who have helped me along the way.

First and foremost I need to thank God for the opportunities I have received and the talents I was given. I also need to thank my wife and kids. They have supported me all along and have endured many challenges along the way. None of this would be possible without them.

Next on the list are all my friends and colleagues that have helped me out. In particular I want to thank Rob Rhyne, Mike Ash, Mark Boszko, Sandy Wang, Guy English and everyone at NSCoder Night DC. If it wasn't for all these fine folks, RetroSketch would be a slow, pokey, ugly, barely usable pile of code plastered on a hard to read website. (Trust me on this one.)

Finally, I want to thank all of my good friends scattered over the internet. I can not begin to explain how deeply moving it has been to see the outpouring of support. The picture next to this article is something I never expected to see. What can I say?

THANK YOU.

Tuesday
Jun292010

A Tale of Two Knobs

The story of RetroSketch is really the story of its knobs. I always thought that figuring out CoreGraphics would take the majority of my time. Turns out that was the easy part.

I could write about how I wrote all this code to doctor the results of atan() depending on the quadrant of the angle, how I computed the distance of a touch from the center of knob, and how I threw away all of that as soon as Mike Ash told me about atan2() and hypot().

I could also write about how having two instances of the same knob class is a bad idea, how their events arrive independently and result in staircases when you try to draw diagonals.

But no, instead I will tell about my first experience with UI design. It's kind of funny, I figured I really didn't have much design work ahead of me with an interface that consists of a grey backdrop and just two knobs. I was wrong. (BTW coming up with a couple of marketing screenshots for a UI that consists of two knobs on a grey expanse is really fun)

The Early Placeholders

As soon as I started hacking the code, I knew I had to draw something on the screen to make sense of touch information. I just needed something to show me the boundaries the software was expecting. So I simply drew a red circle at the outer edges of the knobs.

I also drew a solid blue circle in the center of the knob which represents the dead area. I needed that to avoid the scenario where a user goes straight across the center. If the knobs were sensitive in the center, they would register that move as a sudden 180 degrees twist of the knob, triggering an ugly jump on screen.

20100628EarlyDevKnobs.png

In this early test you can see I was also trying out various ideas. The rects in the center were a comparison between 1 pixel wide lines and 2 pixels (2 pixels won). The label at the top was there to display realtime test data (angle, relative movement, etc.) reported by the knobs.

The Ellipse around the edge allowed me to see into the background (an very early rev of the texture). More importantly, notice that both the aluminum layers and the screen edge were casting shadows at this stage of development. Eventually I had to turn off these shadows for performance reasons. That was the hardest tradeoff I made in the project; those shadows are the real reason that lines in the mechanical device look black in the first place. Without these shadows, I had to artificially darken the texture to make up for it (a poor solution). In the future (if this ever turns a profit), I would like to re-write the whole thing in OpenGL to implement the shadows as shaders.

Finally, notice the placement of the knobs. Placing them in the bottom corners seemed natural at the time, but of course that changed as soon as I had an actual device in my hands.

The RoboSketch Era

I knew all along the placeholder was temporary, but after seeing it for so long I had trouble imagining anything else. I had a series of issues in my head that were complicating matters.

  1. I decided early that drawing a border to house the knobs would look silly and take away screen real estate. The lack of border meant I could not use pictures or renditions of real world knobs. Real world knobs floating over a "glass" that supposedly houses moving parts seemed to work against the illusion I was trying to create.

  2. I wanted large knobs. A large radius gives the user more control, so I wanted the largest knobs I could fit. Which conflicts with...

  3. Knobs floating on the screen cover up the user's drawing area. The problem might be mitigated by making them transparent.

  4. The knobs need to be as self explanatory as possible.

So this is what I came up with:

20100628CDKnobsFrame.png

As you can see, I was seriously confused at this point. I actually thought of going with this design for a moment. I thought that by making them futuristic I could somehow justify having them float above the screen defying all logic. I still had to make them transparent, which really didn't make sense either.

Worst of all, having futuristic knobs clashed with the RetroSketch name. This is when I started to consider the possibility of renaming the whole thing to RoboSketch. To pull that off, I figured I should add some other futuristic features. I would have to implement a document model to save and load works in progress. I had justified not doing this, because the original retro device didn't, but a robo device certainly should. I also thought of adding some automation features to really earn the robo designation.

This RoboNightmare quickly got out of hand. Thankfully, my trusty friends at NSCoder Night DC talked me out it. It made no sense. I was turning my back on my main audience: the nostalgia market. So it was back to the drawing board.

On a side note, the discs in the picture above were Acorn'ed on top of a really old screenshot. If you look carefully, you can see two really large, but thin red arcs in both bottom corners. They are very transparent so it's really hard to see them. This was an early experiment. Placing the center of the knobs right in the corner afforded a huge radius, which in turn gave users detailed control (if you knew how it worked.) The tradeoff was that you could no longer turn the knobs in continuous circles. Problem was, people who tried it didn't get it. This confirmed two important design parameters:

  1. The knobs need to be visible and obvious.

  2. When in doubt, people tended to move their thumbs in circles. It is also interesting to note that this circular motion does not really come natural on the real devices with physical knobs. It is possible to go in infinite circles, but most people move using a series of short twists. Still, people seemed to assume that continuous circles were always the norm.

The Final Design

Disappointed, I went back to the placeholder design in my head. I was now convinced that making it transparent, but very red, would make it visible yet unobtrusive. Somehow being the only thing with color would set it apart visually. Instead of the thin red circles I started with, I would make them thick and represent the area of sensitivity. This meant, the blue area was no longer necessary, it would simply be empty space.

In addition, I wanted to add arrows pointing up and down on one knob and left and right on the other. I also wanted to add the text "UP" & "DOWN" along with the arrows, curved inside the knob. Finally I wanted the text and the arrows to spin around as the knob was turned.

I ran into trouble with this design. My trusty Opacity failed me for the first time. It could not curve the text the way I wanted it (Please don't take this out of context, I love me some Opacity somethin' fierce.) So at the next NSCoder Night DC meeting, I asked my friend Mark Boszko (a.k.a @bobtiki) to help me out drawing my odd shapes.

Instead of simply doing what I asked for, Mark questioned my design (Thank God!). First to go were the directions written into the knobs. Having copy as part of the knob design complicated matters (i.e. required localizations) and made things look cluttered. He also convinced me to get rid of the color. So we wound up with two grey doughnut-shaped knobs with straight double tipped arrows going either side to side or up and down.

That particular day, we happened to be graced by the visit of Sandy Wang (Mike Ash's lovely wife.) She suggested the arrows would look better curved. Both Mark and Sandy whipped out their laptops and started drawing knobs for me. (Have I mentioned how much NSCoder Nights in general rock? I recommend you find one near you)

20100627Contributions.png

Sandy's version is shown on the left and Mark's on the right.

Once I saw these, I knew this was it. The only thing left was to implement the design within the app. While both mockups were really good, they needed some retouching. I mostly tweaked the proportions to my liking. Problem was, I still had trouble drawing the curved angles in Opacity. So I decided to take matters into my own hands and draw the knobs from scratch using CoreGraphics.

20100628CGKnobs.png

These pictures show intermediate drawings generated live by the app using CoreGraphics calls. I used different colors on the graphical components to differentiate them. I could now change the angle and proportions of these knobs programmatically.

Turns out, this approach not only was fun for me, but it also gave me a smooth looking knob on the Retina display of the new iPhone 4. It also has the advantage that I could easily tweak parameters to make the knobs scale for both the iPad and iPhone versions of the app.

Final Touches

The last touch I added to the knobs, was the ability to fade out completely when not in use. When the app first launches, they are visible and remain so, until they are used. After they are used, they gently fade away. Touching anywhere on the screen makes them reappear momentarily. It is not necessary to wait for them to appear to start using them, just move the knobs as if they were there and it works as you would expect. By doing all of this, the knobs interfere as little as possible with the drawing. It also allows the user to take a snapshot using the built in capabilities. (just press the power button and the home button at the same time, snapshots are stored in the Photos app.)

20100629Logo.png

It was a long journey for me, but it was well worth it. When it was all said and done, I was so happy with the result, it became the basis of both the product's logo and icon.

So that is the story of my rather simple knobs. I hope this post provides some useful insight. I also hope you have as much fun as I do twisting these knobs!

Thursday
Jun242010

RetroSketch Postmortem

RetroSketch was born as an experiment— a distraction really. I had been working on my dream app for months, dealing mostly with audio. I was also juggling some consulting work, and I was becoming a bit unmotivated due to my lack of progress. Then the iPad was introduced. I knew I wanted to play with it as soon as I could. The thought of moving my dream app to the iPad didn't really make sense. So what to do?

The size and shape of the iPad reminded me of those sketching toys and an idea got stuck in my head. I wanted a quick project that wouldn't take me from my main work, but I didn't want something so trivial it wasn't interesting. Just drawing a line controlled with two knobs didn't seem like an interesting challenge at first. So I spent some time playing with a real toy, and thats when I got inspired. To make it more interesting, I decided to recreate the way the physical object works; I wanted to simulate all the moving parts.

Spending a lot of time dealing with CoreGraphics is what made the project really compelling to me. The plan was to draw the inside of the box as a background, the vertical & horizontal bars moving the stylus casting shadows inside, and of course a layer of aluminum dust getting etched out by the stylus as it moves around. I figured most people would never notice all of these things, But I still thought is was worth doing it just for the fun of it.

So I did. And I'm done. Somewhere along the process the project went from being an exercise to becoming my first commercial app. I have no clue how it will sell, but it has been worth it already. Turning it into an app has forced me to do all the things related to launching an app that you always put off until the end (at least the stuff that I procrastinate, I'm sure everyone does something different). I had do to a website, create a corporate identity, create Ad Hoc distributions, and think of marketing in more concrete terms, etc.

Now that I'm reaching the conclusion of this phase, and while I still have the experience fresh in my mind, I set out to write a couple of blog posts about it. I want to share some of my observations and lessons learned. Here is a jumping point for those posts:

  • A Tale of Two Knobs
  • A Comparison of Diverging Philosophies (Coming Soon)
  • Sensors: The Source of Wonderful Noise (Coming Soon)
  • Sounds Easy (Coming Soon)

When all is said and done, I have to admit, I'm very excited about the whole thing.

Tuesday
May052009

Truth Table for C4[2] shirt

Here is my preliminary work for the optimization of the T-shirt. 

I layed out out the table a little funny. You can think of it as 4 columns instead of a single long column. I did this mostly due to the constraints of my little engineering notebook.

To make things more interesting I noticed that the second, third and fourth columns were really all identical. This is because for all of them, the output of the sun OR artificial light gate is always 1, so they would just be copies, so I just did one for clarity.

Next, notice that the first 8 entries of the table are all driven by the fact that the seed input to the final AND gate is 0. Therefore, all the interesting stuff only happens when you have and light source of some sort and a seed, of course.

The final eight entries in the table can be thought of as two sets of four that are interwoven (if I were to do this table again, I would move the Aeroponics column to be the second one next to the seed, thereby avoid the interwoven messiness).

One group of four entries is dependent on Aereponics only. If you have Aeroponics set to 1, Water AND Dirt are inconsequential.

The second group of four interwoven entries happens when Aeroponics is 0. In this case basically it reduce to the truth table for the Water AND Dirt gate.

Next up, I need to do a 6 input Karnaugh Map. This is something I have not done in about 15 years. Not to worry! Doing Karnaugh Maps is just like riding a bike, your crotch hurts after a while of doing it.

Truth Table for C4[2] T-shirt. Truth Table for C4[2
Thursday
Oct232008

Speeding up a Cocoa Project Repository Setup with Git

I just finished working my way through a chapter of a new iPhone dev book. I had a working copy of the example of the book and felt like mucking around with it to learn more on my own. I still want to keep the original state of the code, but I am too lazy to setup a repository for such "disposable" code.


Years of using Subversion have made me lazy like that. I am really lazy. I always forget what the steps are to create a repo, mostly because it is usually such an infrequent task for me. But now that Git makes it so easy to create a repo right there in the project directory I'm working on without littering the whole thing with junk... hmmm... Maybe I should be using it even for "disposable" code.


So to facilitate this new behavior I wrote a little script. It expects the root of the project to be the current working directory, so make sure you "cd" into the right place before invoking it. Here is what it does:



  1. Creates a new new git repository at the CWD

  2. Creates a new .gitignore file to ignore:
    • the build directory

    • user.pbxuser file inside the project

    • user.perspectivev3 file inside the project

  3. Adds all the files in the CWD to the index, staging them for inclusion in the next commit

  4. finally commit everything with the default message "- initial commit to Repository"


I think this will be useful to me, and so I post it here in case it is useful to others. It is really very simple. Please let me know if you have any suggestions to improve it.



#!/bin/bash

git init

cat > .gitignore <<EOF
build
.xcodeproj/.pbxuser
.xcodeproj/.perspectivev3
EOF

git add .

git commit -a -m "- initial commit to Repository"