Notazioni: I punti sono scritti dalle lettere a, b, c... I vettori dalle lettere p, q, r, ... Gli scalari dalle lettere i, j, k... Prodotto dot: p * q Prodotto cross: p x q Prodotto vettore scalare: p i oppure i p RETTA: la posso descrivere con un punto a e una direzione normale q Punti sulla retta: a + q k , con k in R. ESERCIZIO: PROIEZ PUNTO SU RETTA Data una retta R = (a, q) e un punto b, trovare c = la proiez di b su R. traccia: c = a + q j (l’incognita è solo j. Troviamola) j = (b – a) * q (poiché q vett normale) PIANO: descritto dalla coppia: - punto a (appartenente al piano) - vettore normale n (ortogonale al piano) Punti sul piano: tutti i punti b t.c.: (b – a)*n = 0 (se è neg => sotto al piano, pos => sopra al piano) Dato il punto b, la sua distanza con segno dal piano è: (b – a)*n La sua proiezione b’ sul piano è: b’ = b – ((b – a)*n) n Osservazione: (b – a)*n = b*n – a*n (prod dot distribuisce su somma vett) E l’addendo -a*n dipende solo dal piano (non dal punto testato b) Quindi chiamando, k = -a*n , in tutte le formule sopra, (b – a)*n diventa: b*n + k Quindi, il piano può essere descritto in alternaltiva (e più stringatamente) da: - vettore normale n (ortogonale al piano) - scalare k, la distanza del piano dall’origine Es, distanza con segno punto b dal piano (n,k) = b*n + k cioè: (n_x, n_y, n_z, k) * (b_x, b_y, b_z, 1) cioè: il prodotto dot fra due vett di 4 elementi, il primo dei quali rappresenta il piano (n,k) e il secondo il punto b in coord affini). ESERCIZIO: PIANO PASSANTE DA 3 PUNTI dati 3 punti a, b, c, trovare il piano z passante per i tre punti. In pseudocodice: a,b,c in coordinate affini, piano come vett di 4 el. vec4 findPlane(vec4 a, vec4 b, vec4 c ){ vec4 p = (b-a) X (c-a) ; p = p / |p|; // cross product fra due vett. // Ora p = (x,y,z,0) // normalizzare il vet p p.w = -(p * a); // “.w” è la 4ta comp del vett. // usare a, b, oppure c, => stesso ris return p; } QUATTRO MODI PER RAPPRESENTARE UNA ROTAZIONE IN R3 (attorno ad un asse passante per l’origine) (A) asse + angolo Asse = vettore (normalizzato) Angolo = scalare. Forse il metodo più intuitivo per modellare. (B) tre angoli (detti di Eulero): alpha, beta, gamma (tre scalari). Rotazione rappresentata: ruotare attorno all’asse X di alpha, poi asse Y di beta, poi asse Z di gamma. (C) matrice M, 3x3 o 4x4: ( a b c 0 ) ( d e f 0 ) ( g h i 0 ) ( 0 0 0 1 ) (a,b,..i sono 9 scalari) NB: non tutte le M sono rotazioni. Per esserlo, det(M) = 1, e ogni riga (dot) se stessa = 1, ogni riga (dot) una delle altre due = 0, cioè M * Mt = I cioè Mt = Mi (Mt è M trasposta, Mi è M inversa). (D) quaterinoni (quattro scalari) non coperti da questo corso, ma sapere che esistono. Offrono alcuni vantaggi. Task: rappresentando le rotazioni con uno dei metodi sopra: 1- come si applica una rotazione ad un punto / un vettore? 2- come si cumulano due rotazioni R1 e R2? (come si trova una rotazione congiunta R3, che equivalga a quale sia come fare le due di fila) 3- come si interpolano due rotazioni? (come si trova la rotazione intermedia) Alcuni task hanno risposte facili con alcune rappresentazioni. Per es: Con (A): facile 3. (interpolare asse e angolo) Con (B): facile 1, 3. Con (C): facile 1, 2. Passare da un sistema ad un altro: passare da (B) a (C) banale (come?). Da (C) a (B) meno banale. Vediamo col prox problema come passare da (A) a (C). ESERCIZIO: dato un asse v (vettore unitario) e un angolo j, trovare la matrice 4x4 R di rotazione attorno a quell’asse di quell’angolo. Soluz: vedere traccia di come si sposta l’asse di rotazione tenendolo parallelo all’asse delle Z. Passo 1) Troviamo una matrice di rotaz Ri (i = inversa) che porti l’asse delle Z a coincidere proprio a con v. La soluz sara’ R = R * Rz(j) * Ri Per trovare Ri trovo i tre assi del sistema di partenza di R. TrovaMat( vec3 v, float j){ Vec3 x,y,z; x = v / |v|; // normalizzo x; y = (0,0,1) X x; // prodotto cross con un vettore qualunque // se ho avuto la sforutna di scegliere un vett allineato, il // cross fa il vett lungo zero. Allora ne scelgo un altro e rifaccio if |y| == 0 then y = (0,1,0) X x; // e ora non posso essere nuovamente sfortunato y = y / |y|; // normalizzo anche y NB: non è a lung 1, anche se e’ // il cross di due vett a lung 1. // Ha come modulo il sen dell’angolo dei due vett usati z = x X y; return ( | | ( x y ( | | ( 0 0 | z | 0 0 0 0 1 // non c’e’ bisogno di normalizzare zeta. ) ( ) ) * ( Rz(j) ) ) ( ) ) ( ) ( * ( ( ( --x---y---z-0 0 0 0 0 0 1 ) ) ) ) // prodotto di tre matrici. // Rz(j) e’ la matr di rot attorno all’asse z di j gradi. }