Promítání prostoru na rovinu

 

Rovnoběžné promítání

 

Promítací paprsky svírají při tomto promítání s půmětnou úhel  obecně různý od . Jedná se o zobrazení .

 

 

 

Poznámka: v následujícím budeme písmenem  označovat axonometrickou průmětnu tak, jak je to obvyklé v konstruktivní geometrii.

 

V tomto zobrazení se („prostorové“) osy  souřadné soustavy  zobrazí na trojici přímek  v rovině , jednotkové vektory  na vektory . Ztotožníme-li tedy průmětnu  s nákresnou (obrazovkou počítače), dostaneme situaci na dalším obrázku. Aby trojice přímek v rovině mohla být považována za průmět souřadné soustavy v kosoúhlé‚ axonometrii, je třeba kromě společného průsečíku požadovat jen to, aby žádné dvě nesplývaly. Průmětnu  opatříme souřadnou soustavou  dle připojeného obrázku. Jedná se o stejnou uživatelskou souřadnou soustavu, kterou jsme používali v unitě GRAPH2D. Vektory  nechť mají v této souřadné soustavě souřadnice , ,  Zobrazení, které zobrazuje libovolný bod  na bod  je dáno rovnicemi

 

 

Tyto dvě rovnice jsou základem unity GRAPH3D: Procedure Projection (X:T3DPoint;var Xp:T2DPoint), která umožňuje 3D modelování. Tato procedura promítá „prostorový“ bod typu T3DPoint jeho průmět v rovině typu T2DPoint. Všechny procedury sestrojující prostorové objekty pak jednotlivé body „prohánějí“ touto procedurou. Například procedura pro konstrukci úsečky v prostoru vypadá takto:

 

procedure TDraw3D.Line(A,B:T3DPoint;Red,Green,Blue:Byte);

var Xp,Yp:T2DPoint;

begin

Projection(A,Xp);Projection(B,Yp);

  With Image1.Canvas do{pro kreslení do objektu Canvas}

  begin

    Pen.Color:= Red+256*Green+256*256*Blue;

    MoveTo(XCoor(Xp[1]),YCoor(Xp[2]));

    LineTo(XCoor(Yp[1]),YCoor(Yp[2]));

  end;

//X[1]:=XCoor(pX[1]);X[2]:=YCoor(pX[2]); {přímým přístupem do ScanLine}

//Y[1]:=XCoor(pY[1]);Y[2]:=YCoor(pY[2]); Line2D(X,Y,Red,Green,Blue);

end;

 

 

Poznámky:

 

1. Všimněte si, že v GRAPH3D jsou body deklarovány jako čtyřsložkové pole. Důvod je analogický jako v GRAPH2D (třísložkové‚ pole). Je to kvůli transformacím v prostoru, kterými se budeme zabývat později.

 

2. Jednotka GRAPH3D připojená k tomuto příkladu obsahuje jen několik procedur nutných speciálně k této kunstrukci. Podstatně bohatší stejnojmenná jednotka se nachází v podadresáři UNITS. Její jednotlivé procedury budeme postupně probírat, a to v této a několika následujících kapitolách.

 

3. Konstrukce jsou prozatím prováděny do objektu Canvas obrazu Image1. Poněkud pomalejší vykreslování prozatím nevadí. V závorce uvedený přístup do ScanLine předpokládá navíc deklaraci proměnných X, Y jako TPixel (stačí lokální). Uvedená procedura Line2D je totožná s „dvojrozměrnou úsečkou“ v GRAPH2D.

 

Příklad 1: Zobrazení krychle v libovolném rovnoběžném promítání. Protože krychle je jedno z nejjednodušších těles a budeme ho často používat, napíšeme si v GRAPH3D proceduru Box_LineModel, což je procedura, která spojí příslušné‚ vrcholy hranami. Protože nám zadání poskytuje volnost v poloze krychle i volbě parametrů axonometrie, je krychle umístěna tak, že tři její hrany leží v souřadných osách a parametry axonometrie jsou voleny libovolně. Je zřejmé, že volbou j2'=0, k1'=0 dostaneme tzv. volné rovnoběžné promítání .

 

 

Zde najdete                 kompletní zdrojový kód                       a zde                spustitelný kód

 

Hranové konstrukce ploch

 

Nejdříve si všimněme konstrukcí ploch zadaných ve tvaru  Tyto plochy sestrojujeme pomocí procedury PolyLine, která tentokrát pracuje ve . Jejími parametry je pole  bodů, kterými má křivka procházet,  počet bodů a barevné složky Red, Green, Blue. Plochu sestrojíme pomocí řezů rovinami kolmými na osu , resp . Řez kolmý např. na osu  sestrojíme tak, že první souřadnice bodů každé křivky naplníme hodnotami , druhá je konstantní. Výsledkem cyklického volání procedury přes interval  je osnova zelených řezů na přiloženém obrázku. V programové realizaci to znamená, že cyklus pro  bude vnější, pro  vnitřní

 

 

 

Příklad 1: Hranová konstrukce plochy :

 

hx:=(x2-x1)/40;hy:=(y2-y1)/40;

y:=y1;

Repeat

  x:=x1;i:=0;

  Repeat

   i:=succ(i); A[i,1]:=x;A[i,2]:=y;A[i,3]:=f(x,y);x:=x+hx;

  until x>x2;

  Draw3D.PolyLine(A,i,Red,Green,Blue);

y:=y+hy;

until y>y2;

 

Přehozením cyklů získáme osnovu řezů kolmých na osu x (vykresleno červeně).

 

 

Z těchto dvou osnov křivek sestrojíme model grafu funkce nad obdélníkem . (Podélné a příčné řezy jsou zde barevně rozlišeny z demonstračních důvodů. Obvykle se sestrojují stejnou barvou). Na připojených obrázcích je graf funkce  nad obdélníkem  ve volném rovnoběžném promítání.

 

 

Zde najdete                 kompletní zdrojový kód                       a zde                           spustitelný kód

 

Příklad 2: Umožňuje uživateli zadat rovnici funkce za běhu programu.

 

Zde najdete                 kompletní zdrojový kód                       a zde                           spustitelný kód

 


 

Je-li plocha zadána parametrickými rovnicemi, je postup analogický. Cyklováním přes parametr  dostaneme první osnovu křivek, cyklováním přes , pak druhou.

 

Příklad 3: Vykreslete anuloid, kulovou a válcovou plochu ve volném rovnoběžném promítání a ověřte známé vlastnosti těchto průmětů (elipsovitý průmět kulové plochy, sklon hlavní poloosy průmětu kružnice...).

 

 

Program, jehož zdrojový kód najdete zde a spustitelný kód zde, vykresluje anuloid v kosoúhlé axonometrii.

 

Program, jehož zdrojový kód najdete zde a spustitelný kód zde, je upraven tak, že uživatel má opět možnost zadávat rovnici plochy za běhu programu.

 

Nejméně příjemným zadáním je pro programátora plocha určená rovnicí . Tuto konstrukci nelze provést pomocí kolmých řezů, které jsme použili výše. Plochu je třeba vhodně segmentovat. Postup je trojrozměrným zobecněním konstrukce křivek zadaných rovnicí  , která byla uvedena v kpt. 3.4. Konstrukce ploch určených rovnicí  bude uvedena v kpt. 8.2.

 

 

Pravoúhlé promítání

 

Kosoúhlé promítání není příliš vhodná pro konstrukce obektů, které mají simulovat pohled na reálný předmět. Srovnání kosoúhlého kolmého promítání vidíme na připojeném obrázku. Známým modelem kosoúhlého promítání je vrhání stínů slunečními paprsky na rovinnou podložku. Pohled na drátěný model tělesa představuje axonometrii kolmou, pohled na jeho stín pak axonometrii kosoúhlou. Čím je Slunce níž nad obzorem, tím jsou stíny-kosoúhlé průměty protaženější. Reálný zrakový vjem vzniká tak, že světelné paprsky odražené vnímaným objektem procházejí zorničkou oka a dopadají kolmo na jeho sítnici. Je-li zorný úhel, pod kterým předmět pozorujeme, dostatečně malý, lze paprsky považovat za rovnoběžku a sítnici oka za rovinu. Má-li tedy sestrojovaný průmět nahrazovat pohled na reálný předmět, je třeba použít pravoúhlé promítání.

 

Lineární transformace, která zobrazuje libovolný bod  na bod  je dána rovnicemi

 

 

 

Nyní je třeba určit koeficienty  tak, aby tato transformace byla pravoúhlým promítáním. Uživatel grafického systému obvykle volí „směr pohledu“, tj. směr promítání, a to pomocí horizontálního úhlu a a vertikálního úhlu b. Označíme-li pořadě  průsečíky průmětny se souřadnými osami, resp. s promítacím paprskem, který prochází počátkem, pak platí:

 

kde g, d úhly mezi průměty souřadných os (viz obrázek) a dále je

 

 

Tyto vzorce jsou součástí procedury SetOrthoAxonProjection, která pro hodnoty úhlů a, b definujících směr pohledu do souřadné soustavy nastavuje průměty .

 

Úlohy, které jsme výše řešili v rovnoběžném promítání jsou nyní řešeny v promítání kolmém:

 

 

 

 

Zobrazení krychle                                                       zdrojový kód               spustitelný kód

Graf funkce dvou proměnných                                     zdrojový kód               spustitelný kód

(totéž s interaktivní změnou rovnice plochy)                  zdrojový kód               spustitelný kód

Plocha zadaná parametrickými rovnicemi                     zdrojový kód               spustitelný kód

(totéž s interaktivní změnou rovnic plochy)                   zdrojový kód               spustitelný kód

 

Středové promítání

 

Pozorujeme-li reálné objekty pod větším zorným úhlem, je třeba při jejich zobrazování použít středové promítání na rovinu. Kolmici spuštěnou se středu promítání na průmětnu nazýváme hlavní paprsek.

 

 

Při programovém zpracování středového promítání vyzžijeme algoritmů z předchozí kapitoly. Konstrukci průmětů budeme řešit procedurou SetCenterProjection. Do ní můžeme převzít všechny procedury SetOrthoAxonProjection, které pouze doplníme. Především opět určíme směr pohledu do souřadné soustavy . Zvolený horizontální a vertikální úhel bude nyní určovat směr tzv. hlavního paprsku, tj. promítacího paprsku kolmého na průmětnu. Tento směr budeme opět reprezentovat jednotkovým směrovým vektorem , který je tedy určen souřadnicemi

 

Průmětnu určíme podobně jako v předchozí kapitole - je kolmá na hlavní paprsek a zvolíme ji v jednotkové vzdálenosti od počátku. Střed  promítání (ObserverPoint) určíme zadáním vzdálenosti  pozorovatele od počátku. Jeho souřadnice pak zjistíme snadno jako -násobek (ObserverDistance) souřadnic směrového vektoru (předpokládáme zadávání úhlů a, b ve stupních):

 

ObserverPoint[1]:=ObserverDistance*cos(Alfa*pi/180)*cos(Beta*pi/180);

ObserverPoint[2]:=ObserverDistance*sin(Alfa*pi/180)*cos(Beta*pi/180);

ObserverPoint[3]:=ObserverDistance*sin(Beta*pi/180);

 

Průmět  bodu  určíme jako průsečík přímky  s průmětnou. Průmětna má rovnici , parametrické rovnice promítacího paprsku jsou

 

 

Dosazením do rovnice průmětny dostáváme pro hodnot parametru rovnici

 

 

Odtud máme hodnotu parametru:                    

 

Tento vzoreček je použit v následující proceduře (střed promítání C je označen ObserverPoint - bod pozorování):

 

Procedure TDraw3D.PlaneIntersect(A:T3DPoint;var pA:T3DPoint);

var t:Double;  S:TVector;

begin

 S:=MajorRay;

 t:=1-S[1]*ObserverPoint[1]-S[2]*ObserverPoint[2]-S[3]*ObserverPoint[3];

 t:=t/(S[1]*(A[1]-ObserverPoint[1])+S[2]*(A[2]-ObserverPoint[2])+S[3]*(A[3]-ObserverPoint[3]));

 pA[1]:=ObserverPoint[1]+(A[1]-ObserverPoint[1])*t;

 pA[2]:=ObserverPoint[2]+(A[2]-ObserverPoint[2])*t;

 pA[3]:=ObserverPoint[3]+(A[3]-ObserverPoint[3])*t;

end;

 

Tento průsečík se nachází v průmětně, která splývá s obrazovkou, a je třeba ho ještě transformovat do světových souřadnic procedurou Projection. Tyto dvě procedury je pak třeba použít při každém nastavování bodu. Např. procedura pro kreslení úsečky vypadá takto (čtenář nechť tuto proceduru srovná se stejnou procedurou v kapitole 3.1.):

 

procedure Draw3D.Line(A,B:T3DPoint;Red,Green,Blue:Byte);

var Xp,Yp :T2DPoint;

    Xc,Yc :T3DPoint;

begin

PlaneIntersect(A,Xc);PlaneIntersect(B,Yc);

Projection(Xc,Xp);Projection(Yc,Yp);

{pro kreslení do objektu Canvas}

  With Image1.Canvas do

   begin

    Pen.Color:=Red+256*Green+256*256*Blue;

    MoveTo(XCoor(Xp[1]),YCoor(Xp[2]));

    LineTo(XCoor(Yp[1]),YCoor(Yp[2]));

   end;

{přímým přístupem do ScanLine

X[1]:=XCoor(pX[1]);X[2]:=YCoor(pX[2]);Y[1]:=XCoor(pY[1]);Y[2]:=YCoor(pY[2]);

Line2D(X,Y,Red,Green,Blue);}

 

Zobrazování objektů ve středovém promítání:

 

 

 

 

 

Zobrazení krychle                                                       zdrojový kód   spustitelný kód

Graf funkce dvou proměnných                                     zdrojový kód   spustitelný kód

 (totéž s interaktivní změnou rovnice plochy)                 zdrojový kód   spustitelný kód

Plocha zadaná parametrickými rovnicemi                     zdrojový kód   spustitelný kód

 (totéž s interaktivní změnou rovnic plochy)                  zdrojový kód   spustitelný kód

 

Poznámka: Tvar průmětů prostorových útvarů závisí na relativní vzdálenosti středu promítání od promítaného útvaru, přesněji řečeno na maximálním úhlu, který svírají promítací paprsky (tzv. zorném úhlu). Zorný úhel člověka je individuální a pohybuje se mezi 42 - 44 stupni. Tomuto zornému úhlu odpovídá obrázek grafu funkce . Krychli ani anuloid tak, jak jsou zobrazeny, by již člověk vidět nemohl. Zorný úhel krychle je asi 60o, anuloidu dokonce 67o . Takto zobrazit tato tělesa dokáže jen počítač nebo širokoúhlý objektiv.

 

 

 

Ještě extrémnější příklad vidíme na tomto obrázku. Vlevo - snímek pořízený širokoúhlým objektivem Canon. Promítací paprsek dopadá na silnici v dolní části obrázku téměř kolmo, v horní části snímku je s ní téměř rovnoběžný. Z toho vyplývá, že zorný úhel tohoto objektivu je téměř 90o. Vpravo vidíme prakticky stejnou (i když značně zjednodušenou) scénu sestroje­nou počítačem

 

Promítání na kulovou plochu

 

Dosud jsme se zabývali promítáním prostoru na rovinu. V praxi se však často vyskytují případy, kdy je při promítání zapotřebí velmi velký zorný úhel. V těchto případech přestává promítání na rovinu vyhovovat, neboť rozměry průmětny extrémně rostou. Existují dokonce objektivy se zorným úhlem větším než 180o a promítání na rovinu není možné z principu. V těchto případech lze použít promítání na kulovou nebo válcovou plochu. Zde existuje více možností volby průmětny, tak způsobu transformace z kulové či válcové plochy do roviny, ke které v konečné fázi musí dojít. V tomto odstavci ukážeme jednu z možností, při které využijeme předcházejících výsledků. Převezmeme střed promítání, jeho určení směrovými úhly a jeho vzdáleností od počátku souřadné soustavy. Převezmeme také promítací rovinu splývající s rovinou obrazovky. Promítacímu paprsku však postavíme do cesty kulovou plochu, jejíž středem bude střed promítání a která se bude této roviny dotýkat. Bod  promítneme středově na kulovou plochu do bodu , tento bod pak komým promítáním do roviny výstupního zařízení (bod ).

 

V algoritmickém zpracování průmětu bodu tak dojde oproti předchozí kapitole k jediné změně: procedurou Intersect určujeme průsečík nikoli se zelenou rovinou, ale s modrou kulovou plochou. Promítací paprsek je stejně jako v předchozím případě určen bodem  a směrovým vektorem . Průsečík s kulovou plochou  je na této přímce tentokrát určen hodnotou parametru

 

 

Nastavení tohoto parametru je to jediné, v čem se promítání bodu na kulovou plochu  liší od promítání na rovinu. Při promítání úseček však musíme mít na paměti, že díky tomuto nastavení parametru se jedná o transformaci nelineární (úsečka se promítne do kruhového oblouku). Průmět úsečky je tedy třeba konstruovat jako křivku pomocí jejích parametrických rovnic (viz př. 2 v kpt.6.1.).

 

Příklad 1.: Zde je zpracován průmět krychle na kulovou plochu

 

 

Zde najdete                 kompletní zdrojový kód                       a zde                spustitelný kód

 

Na připojeném obrázku vidíte snímek místnosti pořízený objektivem s velmi velkým zorným úhlem („rybím okem“). Zorný úhel tohoto objektivu se blíží 180o. Na dalším obrázku máme prakticky stejnou (pouze zjednodušenou) scénu sestrojenou počítačem.