为什么我的透视投影中的最终图像尺寸不在(-1,-1)到(1,1)中?

时间:2013-05-22 15:14:35

标签: matlab projection perspective

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

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

据我了解,最终图像的规范形式大小应为(-1,-1)到(1,1),z为(0,-1)。但是,最终图像X-Y尺寸(见图1)似乎不正确。我主要试图了解最终图像大小是如何确定的。我在下面提供了matlab代码。我的视锥体(f)是由指定纬度/经度的眼点(EP)定义的,已转换为ECEF;距离:近平面(nDist)= 300; view plane(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

0 个答案:

没有答案