corkscrew_surface.lua


NAME
    corkscrew_surface

FUNCTION
    corkscrew_surface(n, a, b)

NOTES
    Generate corkscrew surface based on parametric equations of
    
        x = a cos(u) cos(v)
        y = a sin(u) cos(v)
        z = a sinv + b u

    Example:
        require("plot_simple")
        plot = plot_simple.new()
        plot:add_static(zeGrf.new("light"))
        require("corkscrew_surface")
        xyz, nor = corkscrew_surface(32, 1, .5)
        xyz:scale(50, 50, 50)
        shape = zeGrf.new("polygon")
        shape:set{type = "quads", vertex = xyz,
                  vertex_normal = nor, color = {0, .7, .7, 1}}
        plot:add(shape)
        plot:animate()
NPUTS
    n    - slices between 0 and 2pi
    a, b - surface parameters

OUTPUTS
    Two zeVertex objects containing coordinates and normals of quads.

SOURCE

require("surface_generator")

function corkscrew_surface(n, a, b)
    assert(n >= 8)
    assert(a > 0)
    assert(b > 0)

    local function sfunc(u, v)
        local cosv = a*math.cos(v)
        return math.cos(u)*cosv,
               math.sin(u)*cosv,
               a*math.sin(v) + b*u
    end

    local function nfunc(u, v)
        local cosu, sinu, cosv, sinv =
              math.cos(u), math.sin(u),
              math.cos(v), math.sin(v)
        return zeMake.normal2(0, 0, 0,
                             -a*sinu*cosv,
                              a*cosu*cosv,
                              b,
                             -a*cosu*sinv,
                             -a*sinu*sinv,
                              a*cosv)
    end

    local U, V = zeUtl.new("double", "double")
    U:range(0, math.pi/n, 2*n+1)
    -- V should be from 0 to 2pi
    -- but I think this is more interesting
    V:range(0, math.pi/n, n+1)
    
    return surface_generator(U, V, sfunc),
           surface_generator(U, V, nfunc)
end