Corso di Visual C++

Le modalità di mappatura II

 

Nella parte 13 abbiamo parlato delle modalità di mapping a scala fissa, ora esamineremo quelle a scala variabile.

Queste sono solo due: MM_ISOTROPIC ed MM_ANISOTROPIC ed entrambe permettono sia di cambiare il fattore di scala che l'orientamento degli assi.

La differenza tra le due è che con la modalità isotropica viene conservato un rapporto di 1:1 tra gli assi X e Y; in pratica un quadrato viene sempre disegnato come tale, può ad esempio essere riflesso, ma non può essere stirato per diventare un rettangolo.

Con la modalità MM_ANISOTROPIC invece il rapporto tra le coordinate X ed Y può variare ed in questo modo ad esempio un cerchio può essere trasformato in un ellisse.

Esaminate ad esempio il seguente codice:

 

void CPrg10View::OnDraw(CDC* pDC)

{

CPrg10Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

CRect rectClient;

GetClientRect (rectClient);

// 1. rectClient contiene le dimensioni in coord. di dispositivo dell'area della finestra

pDC->SetMapMode(ANISOTROPIC);

// 2. settiamo la modalità di mapping a scala variabile

pDC->SetWindowExt(100,100);

// 3. impostiamo l'area della finestra come una superficie di 100x100 unità logiche

pDC->SetViewportExt(rectClient.right, -rectClient.bottom);

// 4. setta le dimensioni del rettangolo di visualizzazione sulla finestra ( viewport )

pDC->SetViewportOrg(rectClient.right/2, rectClient.bottom/2);

// 5. setta l'origine del sistema di riferimento al centro dello schermo

pDC->Ellipse(CRect(-50,-50,50,50));

// 6. disegna l'ellisse ( notare i segni negativi ) in modo che riempia l'intero schermo

}

In questo snippet di codice vediamo come si utilizza una modalità di mappatura a scala variabile ( in assoluto la più ostica ).

Innanzitutto gli obiettivi: vogliamo disegnare un ellisse che riempia tutta la finestra e che venga disegnata utilizzando un nostro sistema di riferimento.

In 1 ( riferimento alla riga sopra il commento numerato ) recuperiamo le dimensioni della finestra della vista. Questa operazione fa si che la larghezza e l'altezza ( in pixel ) siano contenuti nei membri di dati right e bottom dell'oggetto rectClient passato per riferimento ( se non ci credete vedete il prototipo di GetClientRect ) alla funzione.

In 2 settiamo semplicemente la modalità MM_ANISOTROPIC, provate a vedere la differenza con MM_ISOTROPIC ( l'ellisse si trasformerà in un cerchio ).

In 3 indichiamo alla GDI ( tramite CDC ) che l'area della finestra dovrà essere rappresentata da un rettangolo di 100x100 unità logiche; in pratica settiamo le dimensioni logiche della finestra.

In 4 settiamo le dimensioni della Viewport, cioè l'area visibile della finestra; questa non ha alcuna relazione con le dimensioni logiche della finestra. Si pensi ad esempio ad una lente di ingrandimento che avviciniamo o allontaniamo dal foglio: se la avviciniamo la dimensione del foglio non cambia, ma a noi il suo contenuto sembrerà più grande

Ad esempio se settiamo la grandezza del foglio ( window ) a 100x100 unità e settiamo la grandezza della viewport a 100x100 allora vedremo che la nostra ellisse diventerà un cerchio al centro dello schermo, se invece settiamo la grandezza della viewport alle dimensioni della finestra ( rectClient ) allora vedremo una bella ellisse che riempie tutta la finestra.

Nel caso specifico dando un valore negativo al secondo parametro di SetViewportExt facciamo si che l'asse positivo delle Y sia verso il basso ( di default è il contrario ).

Ci può essere un po' di confusione tra la 3 e la 4, ma ricordate che un po' di prove risolveranno ogni dubbio!

In 5 settiamo la posizione dell'origine della viewport.

No comment per la 6.

Vorrei ora dirvi che esiste anche un'altra funzione per settare l'origine del sistema di coordinate: SetWindowOrg.

Potrebbe sorgervi qualche dubbio sulla sua utilità, ma spiego succintamente la differenza con SetViewportOrg.

Una chiamata a pDC-> SetViewportOrg (x,y) mette in corrispondenza il punto logico (x,y) con l'angolo in alto a sinistra dell'area di visualizzazione ( punto 0,0 del dispositivo ).

Una chiamata a pDC-> SetWindowOrg (x,y), fa il contrario, mette in corrispondenza il punto logico (0,0) con il punto di dispositivo (x,y).

Questo è tutto ciò che vi serve per iniziare con le modalità di mapping, è inutile approfondire ulteriormente l'argomento ( non banale ) dato che avrete bisogno già di un bel po' di tempo per digerire queste ultime due parti.

 

Torna all'indice Generale del corso di Corso di Visual C++ di Software Planet