Search code examples
graphicsbezierantialiasingspiral

rendering an antialiased spiral


I have looked at this example using php and GD to piecewise-render a spiral with small arcs. What I would like to do is render an approximation to a spiral that is as mathematically accurate as possible.

Inkscape has a spiral tool that looks pretty good, but I would like to do the spiral generation programmatically (preferably in Python).

I haven't found any drawing libraries (e.g. Cairo) that natively support spiral shapes. If one wanted to render a perfect antialiased spiral, would the best way be to just iterate pixel-by pixel over a canvas, determining whether each pixel lies within a mathematically-defined spiral arm region (of finite thickness)? In that case, one would also have to implement anti-aliasing logic from scratch. Would you integrate the portion of the curve that lies within each pixel box, then convert the ratio of filled to empty area to an alpha value?

In this instance the quality of the rendering is more important than the rendering time. However, evaluating an integral at each pixel strikes me as pretty inefficient.

Update: I believe the question I should be asking is this one (for which Yahoo Answers has failed).


Solution

  • Wouldn't it be easier to draw a curve (spline?) and just generate plenty of control points? Like that you'd pick up an existing antialiasing engine.

    [EDIT]: A first approximation to this (done with Tcl/Tk, but the code should be easy to convert) gives me this:

    # Make the list of spiral coordinates
    set coords {}          
    set theta 0; set r 10
    set centerX 200; set centerY 150
    # Go out 50 pixels per revolution
    set pitch [expr {100.0 / 720.0}]
    for {set i 0} {$i<720} {incr i} {
        lappend coords [expr { $centerX + $r*sin($theta) }] \
                       [expr { $centerY + $r*cos($theta) }]
        set r     [expr { $r + $pitch }]
        # Increment angle by one degree
        set theta [expr { $theta + 3.1415927/180 }]
    }
    
    # Display as a spline
    pack [canvas .c -width 400 -height 300]
    .c create line $coords -tag spiral -smooth 1
    

    I've not made any effort to be efficient in my use of control points.