0

我根据 Foley、van Dam、Feiner、Hughes(第 2 版)的第 6 章计算机图形学原理和实践 (CGP&P) 实现了透视投影算法。我有

N'per = M * Sper * Spar * T (-prp) * R * T (-vrp). 

据我了解,最终图像的规范形式大小应为 (-1,-1) 到 (1,1) 和 z in (0,-1)。但是,最终图像的 XY 尺寸(参见图 1)似乎不正确。我主要是想了解最终图像大小是如何确定的。我在下面包含了matlab代码。我的平截头体 (f) 由已转换为 ECEF 的指定纬度/经度处的视点 (EP) 定义;距离:近平面(nDist)= 300;视平面 (vDist) = 900; 远平面 (fDist) = 25000。在 EP 创建的视线 (LOS) 矢量是投影中心。截锥体正确地找到并返回其内沿 LOS 的建筑物。视野为(10 度 x 10 度)。现在我只是想把这些建筑物投影到一个定义好的窗口上,这样我就可以“量化” (绘制?)网格并指示哪个建筑物位于视图平面中的哪个 x,y 对。不幸的是,由于窗口没有按指示的大小返回,这使我的绘画更加困难。此外,我只想知道我做错了什么,没有得到正确的尺寸。


Matlab代码(没有尝试优化或任何东西。只是蛮力实现!

function iPersProj = getPersProj(bldg, bi, f, plotpersp, fPersPlot)
    color        = [rand rand rand];
    face         = eFaces.bottom;  
    iPersProjBtm = persproj(f, bldg, face);
    face         = eFaces.top;
    iPersProjTop = persproj(f, bldg, face); 
    iPersProj    = [iPersProjTop;iPersProjBtm];
    hold on;
    scatter3(iPersProjTop(:,1), ...
             iPersProjTop(:,2), ...
             iPersProjTop(:,3),'+','CData',color);
    scatter3(iPersProjBtm(:,1), ...
             iPersProjBtm(:,2), ...
             iPersProjBtm(:,3),'o','CData',color);
    pPersProj=[iPersProjTop; 
               iPersProjTop(1,:); ... 
               iPersProjBtm;      ... 
               iPersProjBtm(1,:); ... 
               iPersProjBtm(2,:); ...
               iPersProjTop(4,:); ...
               iPersProjTop(3,:); ...
               iPersProjBtm(3,:); ...
               iPersProjBtm(4,:); ...
               iPersProjTop(2,:); ...
               iPersProjTop(1,:)];

    line (pPersProj(:,1), pPersProj(:,2),'Color',color);
    text (pPersProj(1,1), pPersProj(1,2), int2str(bi));
end

function proj = persproj(f, bldg, face)
    vrp  = f.vC; %center view plane
    vpn  = f.Z;  % LOS for frustum
    cop  = -f.EP;

    F    = f.vDist - f.nDist;
    B    = f.vDist - f.fDist;
    umin = -5;
    vmin = -5;
    umax = 5;
    vmax = 5;

    R    = getrotation (f);
    Tvrp = gettranslation(-vrp);
    ed   = R * Tvrp * [f.EP 1]'; %translate eyepoint to camera?
    prp  = [0 0 ed(3)];

    sh   = getsh(prp, umax, umin, vmax, vmin);
    Tprp = gettranslation(-prp);


    vrpp = -prp(3); %(sh * Tprp * [0;0;0;1]); %vrp-prime per CGP&P 
    zmin = -(vrpp + F)/(vrpp+B);
    zmax = -(vrpp + B)/(vrpp+B);
    zprj = -vrpp/(vrpp+B);

    sper = getsper(vrpp, B, umax, umin, vmax, vmin);

    M=[ 1 0 0 0; ...
        0 1 0 0; ...
        0 0 1/(1+zmin) -zmin/(1+zmin); ...
        0 0 -1 0];

    proj = zeros(4,4);

    for i=1:4

        Q=bldg.coords(i,:,face);
        uvdw = M * sper * sh * Tprp  * R * Tvrp * [Q';1];
        proj (i,1) = uvdw(1);
        proj (i,2) = uvdw(2);
        proj (i,3) = uvdw(3);
    end
end

function sper = getsper (vrpz, B, umax, umin, vmax, vmin)

    dx=umax-umin;
    dy=vmax-vmin;

    sper=zeros(4,4);
    sper(1,1) = 2*vrpz/(dx*(vrpz+B));
    sper(2,2) = 2*vrpz/(dy*(vrpz+B));
    sper(3,3) = -1/(vrpz+B);
    sper(4,4) = 1;

 end

function sh = getsh (prp, umax, umin, vmax, vmin)

    sx=umax+umin;
    sy=vmax+vmin;

    cw = [sx/2 sy/2 0 1]';
    dop = cw - [prp 1]';

    shx = - dop(1)/dop(3);
    shy = - dop(2)/dop(3);

    sh=zeros(4,4);
    sh(1,1) = 1;
    sh(2,2) = 1;
    sh(3,3) = 1;
    sh(4,4) = 1;
    sh(1,3) = shx;
    sh(2,3) = shy;

end

function R = getrotation (f)

    rz = f.Z;

    rx=cross(f.Y, rz);        
    rx=rx/norm(rx);

    ry=cross(rz,rx);

    R=zeros(4,4);
    R(1,1:3) = rx;
    R(2,1:3) = ry;
    R(3,1:3) = rz;
    R(4,4) = 1;
end

function T = gettranslation(p)
    T        = zeros(4,4);
    T(1:3,4) = p';
    T(1,1)   = 1;
    T(2,2)   = 1;
    T(3,3)   = 1;
    T(4,4)   = 1;
end

图 1:预期投影,但尺寸不是 (-1,-1) 到 (1,1) 1

4

0 回答 0