tie

Programmatic Technical Drawing in Scala


The Problem

Drawing a good picture is never easy, but drawing a good one programmatically seems somehow exponentially harder. Harnessing a computer to effect the layout and to immediately regenerate the drawing are powerful productivity boosts. Yet, the need to specify every compositional detail of what is truly intuitive, automatic knowledge can make writing that program a difficult task of its own.

A pair of beautiful 'little languages' are exceptional attempts to solve this 'death by a thousand calculations'. They are: PIC by Brian Kernighan, and (Graphviz) DOT by Emden Gansner and Stephen North. Both know largely how to Do The Right Thing. Even so, since neither is a full-featured programming language, each projects unfortunate limitations on one's ability to both tweak The Right Thing to be correct in a slightly different way, or to package solutions for later reuse. In the end, I've addressed the latter by resorting to generating the little language (as text) from modules written in a high-level language. It's about as fun as it sounds, though fortunately the resulting drawings look a lot prettier than that code.

Tie's Solution

Tie is a Scala graphics package for generating technical drawings programmatically. It consciously embodies the spirit of PIC and DOT, rather than, say, the Java AWT. Its functional approach of building larger drawings by composing and transforming smaller ones is also loosely inspired by Paul Hudak's inimitable tutorial, "The Haskell School of Expression".

Like PIC and DOT, Tie is also a programming language, one which is hosted within Scala. This means that it is not another 'little language', but a strongly-typed modern object-oriented language with first-class functions, anonymous classes, type inference, extensible pattern matching, and a collections library which encourages one to program in aggregates. So, whether you have data to visualize, a network to monitor, or a system architecture to model; any time you need to parametrize a part of your drawing, you could accept a function or perhaps a user-defined class instance as a value; just as any functionality you want to leverage later, could be defined as a mixin or a derived class--even a curry-able function. Naturally, laying out a nice drawing still requires a little geometry, but, thanks to these facilities for abstraction and modularization, most of the basics have been swept out of sight into the library, which, like the Scala Standard Library, has been written in user-space, and so may be reimplemented if the need arises. With the right abstraction then, the intent behind the visual layout actually becomes a separable concern from the mathematics to effect that layout.

While illustrations in Tie are format-agnostic, renderers exist for both SVG documents and PNG images. At present, roughly 90% of the non-animation portions of the SVG 1.1, 2nd Ed. specification (of June 2010) is supported. One may draw common geometric shapes, render images, write text, or formulate arbitrary paths by composing lines, arcs, and bezier curves. Then, transforming shapes by scaling, rotation, reflection, and more is made deceptively simple, for its power. Finally, beyond basic coloring, Tie has support for linear and radial gradients, repetitive tiling of patterns, and clipping and/or masking of one shape by another, all with precise opacity control. Essentially, with the notable exception of filter effects--which are on the way--if you can show it in SVG, you can write a program to render it for you with Tie.

The best thing, however--what makes it even cooler than SVG, which already expresses these kinds of drawings--is Tie's rich offering of state-of-the-art modularity constructs. From deep support for blending the best of functional and object-oriented programming, to the ability to build one language on top of another, Tie rocks because of its Scalatude!


© 2011 by Corbin "Kip" Kohn. All rights reserved.