Re: Polygon coordinates transformation

new topic     » goto parent     » topic index » view thread      » older message » newer message

Tommy,

back in 1998 I proposed *fast* texture mapping routines that transform a
given polygon to another polygon. The target polygon has only two
restrictions: (1) it has to have the same number of vertices as the source
polygon, and (2) it has to be 'horizontally' convex (but, of course, both
these conditions can be circumvented with a tiny bit of effort...).

I realize my transform (essentially mapping every point on a horizontal line
in the target to a point in the source) is not exactly what you were asking
for, but it can be perhaps adapted for your purposes.

jiri


--  map.e : texture mapping

function space(integer n,integer y,integer y2)
    sequence s
    integer d,dy,e,f,m

    if n=1 then return {y} end if
    if y=y2 then return repeat(y,n) end if
    s = repeat(y,n)
    s[n] = y2

    dy = 1
    d = 2*(y2-y)
    m = n-1
    f = 2*m
    e = -m
    if y>y2 then
        dy = -1
        d = -d
    end if
    for i = 2 to m do
        e += d
        while e>=0 do
            e -= f
            y += dy
        end while
        s[i] = y
    end for
    return s
end function

global procedure map_image(
    sequence tex,   -- texture bitmap, 2-d sequence
    sequence p,     -- vertices in texture: {{u1,v1},..{un,vn}}
    sequence s      -- polygon to be shown: {{x1,y1},..{xn,yn}}
    )
    -- texture mapping, pixel mode:
    -- map polygon p in image (texture) tex into polygon s
    -- polygon s must be convex : any *horizontal* line has no
    -- more than *two* intersections with sides of such polygon

    sequence u,uu,v,vv,x,xx
    integer i1,i2,k,len,n,rows,u1,u2,v1,v2,x1,x2,y,y1,y2,yi,ymax,ymin

    s=floor(s)          -- integers only
    n=length(s)         -- number of sides

    -- get y extremes
    ymin=s[1][2]
    ymax=ymin
    for i=2 to n do
       if s[i][2]<ymin then ymin=s[i][2] end if
       if s[i][2]>ymax then ymax=s[i][2] end if
    end for

    -- set up edge arrays
    rows=ymax-ymin+1
    xx=repeat({},rows)  -- hold x-values
    uu=xx               -- texture horizontal index
    vv=xx               -- texture vertical index

    -- init & loop
    x2=s[n][1]
    y2=s[n][2]-ymin+1
    u2=p[n][1]
    v2=p[n][2]
    for i=1 to n do
        x1=x2
        x2=s[i][1]
        y1=y2
        y2=s[i][2]-ymin+1
        u1=u2
        u2=p[i][1]
        v1=v2
        v2=p[i][2]
        if y1=y2 then   -- horizontal side
            xx[y1] &= x1
            uu[y1] &= u1
            vv[y1] &= v1
        else            -- non-horizontal side
            if y1>y2 then
                len=y1-y2+1
                yi=-1
            else
                len=y2-y1+1
                yi=1
            end if
            x=space(len,x1,x2)
            u=space(len,u1,u2)
            v=space(len,v1,v2)
            k=1
            for j=y1 to y2-yi by yi do
                xx[j] &= x[k]
                uu[j] &= u[k]
                vv[j] &= v[k]
                k+=1
            end for
        end if
    end for

    -- display
    y=ymin
    if length(xx[1])=1 then
        pixel(tex[vv[1][1]][uu[1][1]],{xx[1][1],y})
        y+=1
        i1=2
    else
        i1=1
    end if
    if length(xx[rows])=1 then
        i2=rows-1
        pixel(tex[vv[rows][1]][uu[rows][1]],{xx[rows][1],ymax})
    else
        i2=rows
    end if
    for i=i1 to i2 do
        x=xx[i]
        x1=x[1]
        x2=x[2]
        if x1<x2 then
            len=x2-x1+1
            u=space(len,uu[i][1],uu[i][2])
            v=space(len,vv[i][1],vv[i][2])
        else
            len=x1-x2+1
            u=space(len,uu[i][2],uu[i][1])
            v=space(len,vv[i][2],vv[i][1])
            x1=x2
        end if
        x=repeat(0,len)
        for j=1 to len do
            x[j]=tex[v[j]][u[j]]
        end for
            pixel(x,{x1,y})
        y+=1
    end for
end procedure -- map_image

global procedure vmap_image(
    atom a,         -- screen address
    integer w,      -- screen width
    sequence tex,   -- texture bitmap, 2-d sequence
    sequence p,     -- vertices in texture: {{u1,v1},..{un,vn}}
    sequence s      -- polygon to be shown: {{x1,y1},..{xn,yn}}
    )
    -- texture mapping for virtual screens:
    -- map polygon p in image (texture) tex into polygon s
    -- polygon s must be convex : any *horizontal* line has no
    -- more than *two* intersections with sides of such polygon

    sequence u,uu,v,vv,x,xx
    integer i1,i2,k,len,n,rows,u1,u2,v1,v2,x1,x2,y1,y2,yi,ymax,ymin

    s=floor(s)          -- integers only
    n=length(s)         -- number of sides

    -- get y extremes
    ymin=s[1][2]
    ymax=ymin
    for i=2 to n do
       if s[i][2]<ymin then ymin=s[i][2] end if
       if s[i][2]>ymax then ymax=s[i][2] end if
    end for

    -- set up edge arrays
    rows=ymax-ymin+1
    xx=repeat({},rows)  -- hold x-values
    uu=xx               -- texture horizontal index
    vv=xx               -- texture vertical index

    -- init & loop
    x2=s[n][1]
    y2=s[n][2]-ymin+1
    u2=p[n][1]
    v2=p[n][2]
    for i=1 to n do
        x1=x2
        x2=s[i][1]
        y1=y2
        y2=s[i][2]-ymin+1
        u1=u2
        u2=p[i][1]
        v1=v2
        v2=p[i][2]
        if y1=y2 then   -- horizontal side
            xx[y1] &= x1
            uu[y1] &= u1
            vv[y1] &= v1
        else            -- non-horizontal side
            if y1>y2 then
                len=y1-y2+1
                yi=-1
            else
                len=y2-y1+1
                yi=1
            end if
            x=space(len,x1,x2)
            u=space(len,u1,u2)
            v=space(len,v1,v2)
            k=1
            for j=y1 to y2-yi by yi do
                xx[j] &= x[k]
                uu[j] &= u[k]
                vv[j] &= v[k]
                k+=1
            end for
        end if
    end for

    -- display
    a+=w*ymin
    if length(xx[1])=1 then
        poke(a+xx[1][1],tex[vv[1][1]][uu[1][1]])
        a+=w
        i1=2
    else
        i1=1
    end if
    if length(xx[rows])=1 then
        i2=rows-1
    else
        i2=rows
    end if
    for i=i1 to i2 do
        x=xx[i]
        x1=x[1]
        x2=x[2]
        if x1<x2 then
            len=x2-x1+1
            u=space(len,uu[i][1],uu[i][2])
            v=space(len,vv[i][1],vv[i][2])
        else
            len=x1-x2+1
            u=space(len,uu[i][2],uu[i][1])
            v=space(len,vv[i][2],vv[i][1])
            x1=x2
        end if
        x=repeat(0,len)
        for j=1 to len do
            x[j]=tex[v[j]][u[j]]
        end for
        poke(a+x1,x)
        a+=w
    end for
    if i2<rows then
        poke(a+xx[rows][1],tex[vv[rows][1]][uu[rows][1]])
    end if
end procedure -- vmap_image

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu