Saturday, December 02, 2006

Someone is ready for Christmas

Ian asks us every day whether it is Christmas yet. Every. Day. Kristin and I just pray he has the same tenacity when it comes to doing his homework ten years from now. Otherwise, a slow day today. Did a little trim work around the windows in the attic, and grabbed a couple gallons of primer to start painting.
Not much progress on the rendering front. The AA vector drawing I have in place right now is just way to basic. This is getting a little repetitive, but once again, Xach has come to the rescue with a good link. Hopefully more to show tomorrow.


bezier progress

Xach's comment referring me to a paper at the Anti-Grain Geometry site on estimating bezier curves using line segments was spot on. I had to replace the AA line-drawing algorithm to use fractional pixel locations. As you can see from the above, the line segments do a pretty good approximation. There are still some issues with how the individual line-segments meet up that can be seen in the image. I think this is because when two lines meet at a pixel location, the last line to be drawn overwrites the pixel color instead of adding its contribution. This code will also give me an excuse to finally dig into CL optimizations like type declarations and inlining. From some debugging output, I know that some of the code is actually using rationals. I'm almost sure that can't be good for speed


Wednesday, November 29, 2006

Brute Force Bezier Curves

I think in order to render TrueType fonts you first have to be able to render Bezier curves. Above is the brute-force method I hacked together for my in-progress rendering engine in lisp. I still don't know how to anti-alias them. Once I get the curves looking good, then I can integrate Xach's zfb-ttf library to get the curves for different True-Type fonts. From the little I've read there is more to decent font rendering than just following the control points. I've seen references to hinting, which I think are instructions for tweaking the font rendering especially at very small sizes.


Monday, November 27, 2006


In C, I'm used to swapping values with a temporary:

int x = 1;
int y = 2;

int tmp = x;
x = y;
y = tmp;

In Lisp, you can do the same thing using psetf:

(let ((x 1) (y 2))
  (psetf x y y x))


I'm doing more math-wise in Lisp as I am playing around with a little bit of rendering. psetf is an example of one of those small corner-case functions that greatly simplify coding in Lisp. Going through the kind of "and here are all the NUMBER functions..." reference doesn't penetrate my thick skull. Necessity is the mother of memorization (or something like that). I am moving forward on the working assumption that no matter what it is I am coding, there is probably a simpler way to do it. This isn't necessarily always the case. There are a few areas where Lisp seems overly verbose (multiple return values in a let comes to mind); however, it is a pretty good chance that if it looks ugly, Lisp has a better way of doing it. The picture above is my anti-aliased line rendering courtesy of Xach's Salza package and example png.lisp code. I'm rolling my own as a hobby/exercise more than anything else. I've got some particular image rendering goals, so this is probably not going to be that generic. I don't care about rotating bitmaps, color correction, or any of that image manipulation stuff. What I do want to do is render nice anti-aliased curves, text and gradients.

And even when I've found a simpler way, I am probably still missing something. Thas on #lisp pointed out that the simple swap above could be done with (rotatef x y) much more concisely. In my case, I am actually performing several swaps at once based on the slope of the line:

(when (minusp dy)
    x1 x2 x2 x1
    y1 y2 y2 y1
    dx (- x1 x2)
    dy (- y1 y2)))

But, for the simple swap, rotatef is your man.


Lisp at Microsoft

It turns out the garbage collector for Microsoft's CLR was originally written in Common Lisp.