0

Foley、van Dam、Feiner、Hughes (第 2 版) による第 6 章 Computer Graphics Principles and Practices (CGP&P) に従って透視投影アルゴリズムを実装しました。私は持っている

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

私が理解しているように、最終的な画像は (-1,-1) から (1,1) までの標準的な形式のサイズで、z は (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