cross_cap2.lua


NAME
    cross_cap2

FUNCTION
    cross_cap2(n)

NOTES
    Generate cross cap surface based on Gray (1997) parametric equations
    
        x = sin(u) sin(2v)/2
        y = sin(2u) sin(v)^2
        z = cos(2v) sin(v)^2
        
    Refer to MathWorld at http://mathworld.wolfram.com/Cross-Cap.html
    
    Example:
        require("plot_simple")
        plot = plot_simple.new()
        plot:add_static(zeGrf.new("light"))
        require("cross_cap2")
        xyz, nor = cross_cap2(36)
        xyz:scale(100, 100, 100)
        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 - number of segments in a ring

OUTPUTS
    Two zeVertex objects containing coordinates and normals.

SOURCE

require("surface_generator")

function cross_cap2(n)
    assert(n > 16)
    
    local function sfunc(u, v)
        local sinv = math.sin(v)
        return math.sin(u)*math.sin(2*v)/2,
               math.sin(2*u)*sinv*sinv,
               math.cos(2*v)*sinv*sinv
    end

    local function nfunc(u, v)
        local cosu, sinu, cos2u, sin2u,
              cosv, sinv, cos2v, sin2v =
              math.cos(u), math.sin(u), math.cos(2*u), math.sin(2*u),
              math.cos(v), math.sin(v), math.cos(2*v), math.sin(2*v)
        return zeMake.normal2(0, 0, 0,
                              cosu*sin2v / 2,
                              2*cos2u*sinv*sinv,
                              0,
                              sinu*cos2v,
                              2*sin2u*sinv*cosv,
                             -2*sin2v*sinv*sinv + 2*cos2v*sinv*cosv)
    end

    local U, V = zeUtl.new("double", "double")
    U:range(1.e-9, math.pi/n - 1.e-12, n+1)
    V:range(1.e-9, math.pi/n - 1.e-12, n+1)
    
    return surface_generator(U, V, sfunc),
           surface_generator(U, V, nfunc)
end