Proiezione di punti 3D sul piano 2D

Sia A un punto per il quale ho le coordinate 3D x, y, z e voglio trasformarle in coordinate 2D: x, y. La proiezione deve essere ortogonale su un piano definito da una data normale. Il caso banale, in cui il normale è in realtà uno degli assi, è facile da risolvere, semplicemente eliminando una coordinata, ma per quanto riguarda gli altri casi, che sono più probabili che accada?

Se si ha il punto P di destinazione con le coordinate r_P = (x,y,z) e un piano con normale n=(nx,ny,nz) è necessario definire un’origine sul piano, nonché due direzioni ortogonali per x e y . Ad esempio se la tua origine è a r_O = (ox, oy, oz) e i tuoi due assi coordinati nel piano sono definiti da e_1 = (ex_1,ey_1,ez_1) , e_2 = (ex_2,ey_2,ez_2) quindi l’ortogonalità ha Dot(n,e_1)=0 , Dot(n,e_2)=0 , Dot(e_1,e_2)=0 (prodotto punto vettoriale). Si noti che tutti i vettori di direzione dovrebbero essere normalizzati (la magnitudine dovrebbe essere uno).

Il tuo objective P deve obbedire all’equazione:

 r_P = r_O + t_1*e_1 + t_2*e_2 + s*n 

dove t_1 e t_2 sono le tue coordinate 2D lungo e_1 ed e_2 e s la normale separazione (distanza) tra il piano e il punto.

Gli scalari sono trovati per proiezioni:

 s = Dot(n, r_P-r_O) t_1 = Dot(e_1, r_P-r_O) t_2 = Dot(e_2, r_P-r_O) 

Esempio con origine del piano r_O = (-1,3,1) e normale:

 n = r_O/|r_O| = (-1/√11, 3/√11, 1/√11) 

Devi scegliere direzioni ortogonali per le coordinate 2D, ad esempio:

 e_1 = (1/√2, 0 ,1/√2) e_2 = (-3/√22, -2/√22, 3/√22) 

tale che Dot(n,e_1) = 0 e Dot(n,e_2) = 0 e Dot(e_1, e_2) = 0 .

Le coordinate 2D di un punto P r_P=(1,7,-3) sono:

 t_1 = Dot(e_1, r_P-r_O) = ( 1/√2,0,1/√2)·( (1,7,-3)-(-1,3,1) ) = -√2 t_2 = Dot(e_2, r_P-r_O) = (-3/√22, -2/√22, 3/√22)·( (1,7,-3)-(-1,3,1) ) = -26/√22 

e la separazione fuori piano:

 s = Dot(n, r_P-r_O) = 6/√11 

Trova la proiezione di A nella direzione normale . Quindi sottrarre quella proiezione da A Ciò che rimane è la proiezione di A sul piano ortogonale.

La proiezione di A sulla normale direzione dell’unità n è data da:

 (A · n) n 

Se A = (x, y, z) e l’unità normale è data da n = (nx, ny, nz) , allora la proiezione di A su n è

 (x*nx + y*ny + z*nz) n 

Quindi la proiezione di A sul piano ortogonale è

 A - (A · n) n = (x, y, z) - (x*nx + y*ny + z*nz) (nx, ny, nz) 

Ad esempio, se A = (1,2,3) e n è l’unità normale in direzione (4,5,6), allora

 In [12]: A Out[12]: array([1, 2, 3]) In [17]: d Out[17]: array([4, 5, 6]) In [20]: n = d/sqrt(4*4 + 5*5 + 6*6) # make na unit vector In [13]: n Out[13]: array([ 0.45584231, 0.56980288, 0.68376346]) 

Quindi la proiezione di A sul piano ortogonale è

 In [15]: A - np.dot(A,n)*n Out[15]: array([-0.66233766, -0.07792208, 0.50649351]) 

Come trovare le coordinate 2D:

Dovrai definire un sistema di coordinate 2D sul piano ortogonale. In altre parole, è necessario definire dove si trovano l’ x-axis y-axis . Ad esempio, è ansible definire l’ x-axis come la proiezione di (1,0,0) sul piano ortogonale (utilizzando il calcolo mostrato sopra). Questo funzionerà tranne nel caso degenere in cui (1,0,0) è normale al piano.

Una volta che hai i vettori unitari per le direzioni degli assi y , puoi proiettare A direttamente su y . La grandezza di questi vettori sono le coordinate 2D.

Ad esempio, questa è la proiezione di (1,0,0) sul piano. Prendiamo questo per essere la direzione dell’asse x:

 In [42]: x = np.array([1,0,0]) In [45]: x = x - np.dot(x, n) * n In [52]: x /= sqrt((x**2).sum()) # make xa unit vector In [53]: x Out[53]: array([ 0.89006056, -0.29182313, -0.35018776]) 

Qui calcoliamo la direzione dell’asse y: la direzione dell’asse y-axis deve essere perpendicolare sia alla normale direzione n che a x . Quindi potremmo definire y come prodotto trasversale di n e x :

 In [68]: y = np.cross(n, x) In [69]: y Out[69]: array([ -2.77555756e-17, 7.68221280e-01, -6.40184400e-01]) 

Quindi ecco le coordinate per A nell’aereo:

 In [70]: np.dot(A, x), np.dot(A, y) Out[70]: (-0.74414898890755965, -0.38411063979868798)