I wrote a few days ago about how I had this killer (simple but useful) Mac application idea bouncing around in my head for a year now. I have to confess I’ve spent a fair amount of time over the last three days in refreshing my Cocoa programming skills, and I’ve written my first decent test-app: a Mandelbrot generator.
Back when I was a teenager I was fascinated with the Mandelbrot set. It was kind of the “hallmark image” of the then-newly-emerging field of fractal geometry. This was the same field of Mathematics that was allowing computer-generated landscapes like moon in the Genesis Planet Demonstration video from Star Trek: Wrath of Kahn. I remember staring at the strangely beguiling image in a Scientific American article, fascinated with its strange features. Also incredible was the fact that no matter how closely you “zoomed-in” to a point of the Mandelbrot set, you got a uniquely different-yet-similar picture.
I remember being about 16 years old and reading and re-reading the article, trying to understand the relatively simple mathematics behind it. It was just the equation z=z2+c but in the complex number plane. I understood complex numbers and had a year or two of algebra under my belt, but couldn’t get it. Then one day I had that “eureka” moment and it all made sense. I jotted down the simple quadratic, translated it into a computer algorithm and set to writing a program to test it.
This was in the days of DOS. I wrote my program in Turbo Pascal, where it wasn’t all that difficult to set color values to individual pixels on a computer screen. In fact, in those days that was almost the only way you could do graphics! Granted, there were libraries to do the incredible feat of drawing lines and adding simple text labels, but in the end you were working with setting the grid of 320×200 pixels one of four colors. (I’m talking CGA graphics mode. Actually, my NCR PC 6 had a “special enhanced” graphics mode of 640×400 pixels and four colors.)
The numerical calculations were not complex, but there were a lot of them. I remember that generating a 640×400 image took a little over 2.5 hours on my 8 Megahertz 8088 computer, and the 32-bit floating point operations meant I couldn’t zoom in for too much details, but it was still amazingly cool.
For a few years my hallmark of breaking in a new computer involved rewriting my Mandelbrot generator. It looked far better on my Dell 286-20Mhz PC with 287 math-coprocessor. That had an actual VGA (640×480 at 256 colors) monitor and rendered the image in about 45 minutes. My first time on an 80386 computer it was even faster.
I want to reiterate how much the art of “writing cool looking things on the computer” was to me back then. As a kid I spent endless hours with my friend Tom; we both started with the Texas Instruments TI-99/4A and then both moved on to PCs and Turbo Pascal. We would write graphics programs that would do primitive CAD. Actually, Tom did most of the heavy lifting with really involved programs like that. I diid the simple model of the U.S.S. Enerprise that could be rotated around in 3D, scaled, etc. It was Tom’s experiment with optics and visual perspective. We wrote some (very lame) video games on the TI-99/4A in BASIC. My friend Bryan had an Atari for which he knew every byte and how to do crazy and magical graphical stuff. Those were also the days when kids were writing amazing programs on the original Apple, just by “poking and peeking” special byte values in special locations. It was the ultimate era of tweaking.
Then came the days of Windows. All of a sudden I didn’t have control over the pixels on the screen. I didn’t know how to draw simple lines. Programming became weird and difficult, and as powerful as it seemed with this new Windowing and multi-application paradigm, I felt like things got too complex. 1990 marked the end of my era of writing “neat desktop applications”. I became more of a “systems engineer” of the application development was more in data-management or statistical computation applications. Yeah, they were important, and I’ve carved out a decent career over the years, but I missed the days of “writing a cool program that made something pretty on the screen”. (An analogy that might appeal to my brother: the Golden Age of Tweaking I mention above was like the old days when cars were simper, and a high school boy could take apart an engine and fuss with the carburetor, etc. without some magical plug-in computer interface. I blame the end of that Golden Age of Tinkering with the downfall of the American Automobile.)
So a couple days ago, really just a few minute after writing that article about my Task Manager program I wanted to write, I picked back up my copy of Cocoa Programming for Mac OS X by Aaron Hillegass, and started on page 1. I got to page 232 when I decided I would have to try actually fiddling with all these new concepts before they just started mushing together in my brain. And I decided the best “real app” that would test whether I could move beyond the simple cookie-cutter demos was to rewrite the Mandelbrot Generator.
As powerful as modern computers are today, it’s amazing that something as simple as directly controlling a grid of pixels and assigning colors to them is so hard. It seems the writers of books and documentation can’t imagine such a desire. What do I mean by not writing some application with buttons and tables and text fields!? Oh my! For a while I started getting really frustrated. There was the NSImage class, which could make it effortless for me to load a JPEG from a file, scale it, rotate it, zoom it, add layers of transparency to it… but I didn’t want to load a file image, and I didn’t want to scale it. I wanted a one-to-one correlation with pixels in front of my face.
Finally I got it figured out. I just had to understand how to create an NSImage based on an NSBitmapImageRep (which I would actually draw on) and have it managed by an NSImageView. In truth it ended up being pretty simple once I figured it outâ€”don’t most things end up that wayâ€”and it was remarkable how easy it was to add controls to let me type in coordinates, later adding the ability to click on a point in the image to zoom in. There’s a lot I could add to this programâ€”resizing, unzooming, custom coloration schemes, multi-threading so the app doesn’t lock up for a second during computation. I also really wanted to handle the mouse-click using a delegate instead of subclassing the NSImageView, but I need to start the next chapter in the book.
It is a wonderful feeling, however, being able to get back into “sitting and writing neat and fun programs on a computer”. And everything I’ve said about OS X Cocoa being a revolutionary programming environment is still true. For anyone with a Mac who cares, here’s my (unfinished 0.9 version) app: MandleTry Cocoa Mandelbrot generator.
A few people recently asked in the Comments section for source code. I’m not going to release the entire package, but I’ll release part of the Objective-C source code that calculates the pixel values and, more importantly, uses the NSBitmapImageRep class to do the pixel-manipulating magic most elegantly.