# DirectX/Calcolo vettoriale

DirectX
Copertina Tutti i moduli · Sviluppo
    CopertinaDirectX/Copertina
* Ripasso di matematicaDirectX/Ripasso di matematica
** Calcolo vettorialeDirectX/Calcolo vettoriale
** Calcolo matricialeDirectX/Calcolo matriciale
** TrasformazioniDirectX/Trasformazioni
* Creare il progetto con VS2010DirectX/Creare il progetto con VS2010
* InizializzazioneDirectX/Inizializzazione
** Win32
*** Creare la finestraDirectX/Creare la finestra
*** Terminale di debugDirectX/Terminale di debug
*** Message loopDirectX/Message loop
*** Altre funzioni Win32DirectX/Altre funzioni Win32
Modifica il sommario
Per vettore intendiamo un oggetto che ha un modulo ed una direzione. A differenza dei vettori usati in fisica, questi non hanno un verso e non ne hanno bisogno. Un vettore può essere usato per indicare una forza (applicata con m intensità in quella direzione), una velocità (m km/h in una data direzione), ma anche una semplice direzione: la direzione verso cui punta la telecamera, la direzione in cui guarda il personaggio, la normale di un piano o di una faccia di un dato poligono. In questo caso il modulo viene impostato ad 1 e non ha valore significativo per il vettore stesso.

## Rappresentazione di vettori

Il modo più semplice di rappresentare un vettore è una linea. La lunghezza della linea indica il modulo, l'orientamento è la direzione. L'orientamento può essere bloccato su due assi (x, y), in questo caso si parla di Vettori 2D (D3DXVECTOR2) o può avere anche una profondità (x, y, z), diventando quindi un Vettore 3D (D3DXVECTOR3). Esiste anche un Vettore 4D (D3DXVECTOR4). La quarta coordinata (chiamata W) non può essere rappresentata ovviamente su un foglio o uno schermo, ma viene utilizzata per alcuni calcoli.

## Uguaglianza tra vettori

Due vettori si dicono uguali se hanno stesso modulo e stessa direzione, senza alcun influenza del punto di applicazione. Due vettori lunghi 1 m e paralleli su tutti gli assi, per quanto distanti essi siano sono uguali.

## Rappresentazione informatica dei vettori

Siccome i computer, come abbiamo già detto non possono lavorare geometricamente, dovremo utilizzare solo numeri per descrivere un vettore. Per il modulo nessun problema, ma per la direzione? Servirebbero 6 coordinate: 3 per la coda e 3 per la testa, da questi due punti si potrebbe ottenere la direzione. Tuttavia utilizzare 7 valori (6 coordinate + 1 modulo) per ogni vettore è altamente inefficiente, richiedendo molta memoria. Per comodità quindi si fa coincidere la coda del vettore sempre con l'origine degli assi. In questo modo utilizzando solo 3 coordinate per la testa (x, y, z), avremo già direzione e modulo. Infatti il modulo si può calcolare semplicemente come: ${\sqrt {x^{2}+y^{2}+z^{2}}}$ per il teorema di pitagora applicato allo spazio. L'origine degli assi coincide con il centro dello schermo. Mentre l'asse X ha il suo semiasse positivo a destra e l'asse Y in alto come siamo abituati, l'asse Z che perfora lo schermo può essere orientato in due modi: i valori negativi di Z che vanno dai nostri occhi all'origine e i valori positivi dall'origine al muro dietro lo schermo (sistema Left-Handed, LH) oppure al contrario, i valori negativi dal muro al monitor e positivi dal monitor agli occhi (Right-Handed, RH). Personalmente preferisco il sistema LH, DirectX tuttavia lascia la possibilità di scelta utilizzando opportune funzioni. Quando però si creano vettori, viene usato sempre il sistema LH.

## Modulo di un vettore

Il modulo di un vettore v si indica con il simbolo $\lVert v\rVert$ e si calcola con il teorema di pitagora per lo spazio utilizzando come x, y, z le componenti del vettore.

## Vettore normalizzato

Ci sono situazioni in cui il modulo di un vettore non importa, nel caso in cui debba solo indicare una direzione. In questo caso il modulo viene impostato ad 1, ed il vettore viene detto normalizzato. Normalizzare un vettore è l'operazione di portare il modulo ad 1 senza alterarne la direzione. Per normalizzare un vettore è sufficiente dividere ogni sua componente per il modulo del vettore stesso ossia:
$v_{n}={v \over {\lVert v\rVert }}=\left({x \over {\lVert v\rVert }},{y \over {\lVert v\rVert }},{z \over {\lVert v\rVert }}\right)$

## Operazioni con i vettori
### Uguaglianza

Due vettori sono uguali se hanno le corrispettive coordinate uguali: dati a = (A$_x$, A$_y$, A$_z$) e b = (B$_x$, B$_y$, B$_z$), a = b se e solo se A$_x$ = B$_x$ e A$_y$ = B$_y$ e A$_z$ = B$_z$. Oppure se preferite: $\forall a=(A_{x},A_{y},A_{z}),b=(B_{x},B_{y},B_{z}),a=b\iff A_{x}=B_{x}\ \land \ A_{y}=B_{y}\ \land \ A_{z}=B_{z}$

### Somma

La somma di due vettori è un terzo vettore le cui componenti sono la somma delle componenti dei vettori originali: dati $a=(A_{x},A_{y},A_{z})\,$ e $b=(B_{x},B_{y},B_{z})\,$, $a+b=(A_{x}+B_{x},A_{y}+B_{y},A_{z}+B_{z})\,$

### Moltiplicazione con scalari

Un vettore può essere moltiplicato per uno scalare k. Il risultato sarà un vettore in cui ogni componente è stata moltiplicata per lo scalare: Dato $a=(A_{x},A_{y},A_{z}),k\in \mathbb {R} ,k\cdot a=(k\cdot A_{x},k\cdot A_{y},k\cdot A_{z})$

### Differenza

La differenza viene definita come combinazione di somma e moltiplicazione scalare: dati a e b vettori, $a-b=a+(-1b)\,$. Quindi: $a-b=(A_{x},A_{y},A_{z})+(-B_{x},-B_{y},-B_{z})=(A_{x}-B_{x},A_{y}-B_{y},A_{z}-B_{z})\,$

### Prodotto scalare

Il prodotto scalare (dot product) tra due vettori è uno scalare composto dalla somma dei prodotti delle coppie di componenti. In altre parole: dati $a=(A_{x},A_{y},A_{z})\,$ e $b=(B_{x},B_{y},B_{z})\,$ il prodotto scalare è:
$a\cdot b=A_{x}\ B_{x}+A_{y}\ B_{y}+A_{z}\ B_{z}$
Inoltre il prodotto scalare può essere calcolato anche come:
$a\cdot b=\lVert a\rVert \lVert b\rVert \cos \theta$
dove $\theta$ è l'angolo formatosi avvicinando i vettori fino a far coincidere le code.

### Prodotto vettoriale

Il prodotto vettoriale (cross product) è un secondo tipo di prodotto tra vettori. Questo prodotto può essere calcolato solo tra vettori 3D, inutile quindi cercare di calcolare il prodotto vettoriale di due vettori nel piano. Il risultato di questa operazione è un terzo vettore di direzione perpendicolare al piano su cui poggiano entrambi i vettori di partenza. Le sue componenti sono:
$a\times b=(A_{y}\ B_{z}-A_{z}\ B_{y},\ A_{z}\ B_{x}-A_{x}\ B_{z},\ A_{x}\ B_{y}-A_{y}\ B_{x})$
Da notare che il prodotto vettoriale non gode della proprietà commutativa.

## Lavorare con i vettori in DirectX

Un vettore generico a 3 dimensioni è definito dalla libreria Direct3D come:
Quindi per sommare due vettori il codice sarebbe:
Tuttavia la libreria Direct3DX viene in nostro aiuto con una fantastica classe:
I costruttori di D3DXVECTOR3 permettono la creazione di un vettore nullo, un vettore copiato da un altro vettore e di un vettore date le tre coordinate. La grande comodità di questa classe è di supportare somma, differenza, moltiplicazione e divisione con scalari, oltre al confronto. Gestire i vettori diventa ora molto più semplice:
Allo stesso modo esistono D3DXVECTOR2 e D3DXVECTOR4 (poi capiremo a cosa serve).

### Lunghezza del vettore

Per leggere la lunghezza, o il modulo, effettiva del vettore (e non le sue componenti) D3DX mette a disposizione queste funzioni:

### Normalizzazione di vettori

Abbiamo visto che normalizzare un vettore vuol dire dividere ogni componente per il modulo del vettore stesso al fine di ottenere un modulo pari ad 1. Le classi D3DXVECTOR# non contengono funzioni come Normalize, ma D3DX ci fornisce una funzione per ottenere lo stesso effetto. Queste funzioni vogliono un puntatore dove mettere il risultato che poi verrà anche restituito dalla funzione stessa. Quindi questa funzione non crea un nuovo vettore ma ne richiede due: l'originale da normalizzare e la destinazione in cui riportare il risultato. E' anche possibile far coincidere pOut e pIn, perdendo però il vettore originale.

### Prodotto scalare

Anche per il prodotto scalare la classe D3DXVECTOR# non presenta funzioni utili. Tra l'altro la funzione operator* è utilizzata per il prodotto con scalare. Quindi il seguente codice è errato:
Per il prodotto scalare (Dot product) D3DX fornisce i seguenti metodi:
Tutte le versioni prendono come argomenti due puntatori a D3DXVECTOR#, di cui verrà calcolato il prodotto scalare (che restituisce un valore scalare, ricordiamolo), il cui risultato sarà restituito dalla funzione.

### Prodotto vettoriale

Infine ci sono funzioni anche per il calcolo del prodotto vettoriale (Cross product). Essendo il prodotto vettoriale non definito per un vettore 2D non esiste un D3DXVec2Cross, ma solo D3DXVec3Cross e D3DXVec4Cross.
In questo caso oltre ai due vettori di partenza viene passato come argomento anche un puntatore a vettore dove verrà inserito il risultato dell'operazione. Il valore di pOut viene anche restituito dalla funzione stessa.