Proyección de puntos 3D a plano 2D

Deje A ser un punto para el que tengo las coordenadas tridimensionales x, y, z y quiero transformarlas en coordenadas 2D: x, y. La proyección será ortogonal en un plano definido por una normal dada. El caso trivial, donde lo normal es en realidad uno de los ejes, es fácil de resolver, simplemente eliminando una coordenada, pero ¿qué hay de los otros casos, que es más probable que sucedan?

Si tiene su punto objective P con coordenadas r_P = (x,y,z) y un plano con n=(nx,ny,nz) normal n=(nx,ny,nz) , necesita definir un origen en el plano, así como dos direcciones ortogonales para x y y Por ejemplo, si su origen es r_O = (ox, oy, oz) y sus dos ejes de coordenadas en el plano están definidos por e_1 = (ex_1,ey_1,ez_1) , e_2 = (ex_2,ey_2,ez_2) entonces la ortogonalidad tiene Dot(n,e_1)=0 , Dot(n,e_2)=0 , Dot(e_1,e_2)=0 (producto punto vectorial). Tenga en cuenta que todos los vectores de dirección deberían estar normalizados (la magnitud debería ser uno).

Su punto objective P debe obedecer la ecuación:

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

donde t_1 y t_2 son sus coordenadas 2D a lo largo de e_1 y e_2 la separación normal (distancia) entre el plano y el punto.

Hay escalares encontrados por proyecciones:

 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) 

Ejemplo con un origen plano r_O = (-1,3,1) y normal:

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

Debe elegir direcciones ortogonales para las coordenadas 2D, por ejemplo:

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

tal que Dot(n,e_1) = 0 y Dot(n,e_2) = 0 y Dot(e_1, e_2) = 0 .

Las coordenadas 2D de un punto P r_P=(1,7,-3) son:

 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 

y la separación fuera del plano:

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

Encuentra la proyección de A en la dirección normal . Luego resta esa proyección de A Lo que queda es la proyección de A en el plano ortogonal.

La proyección de A en la unidad dirección normal n viene dada por:

 (A · n) n 

Si A = (x, y, z) y la unidad normal está dada por n = (nx, ny, nz) , entonces la proyección de A sobre n es

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

Entonces, la proyección de A en el plano ortogonal es

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

Por ejemplo, si A = (1,2,3) yn es la unidad normal en dirección (4,5,6), entonces

 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]) 

Entonces, la proyección de A en el plano ortogonal es

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

Cómo encontrar coordenadas 2D:

Tendrá que definir un sistema de coordenadas 2D en el plano ortogonal. En otras palabras, necesita definir dónde se encuentran el x-axis y. Por ejemplo, podría definir el x-axis para que sea la proyección de (1,0,0) en el plano ortogonal (usando el cálculo que se muestra arriba). Esto funcionará excepto en el caso degenerado donde (1,0,0) es normal al avión.

Una vez que tenga vectores unitarios para las direcciones del eje y , entonces podría proyectar A directamente en x e y . La magnitud de esos vectores son las coordenadas 2D.

Por ejemplo, esta es la proyección de (1,0,0) en el plano. Consideramos que es la dirección del eje 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]) 

Aquí calculamos la dirección del eje y: la dirección del eje y-axis debe ser perpendicular a la dirección normal n a x . Entonces podríamos definir y ser el producto cruzado de x :

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

Así que aquí están las coordenadas para A en el avión:

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