20 votos

¿Cómo transformar un conjunto de vectores 3D en un plano 2D, desde un punto de vista de otro vector 3D?

Busqué en Google un poco, pero normalmente encontré explicaciones demasiado técnicas, u otras preguntas más específicas de Stackoverflow sobre el funcionamiento de los gráficos 3D. Estoy seguro de que puedo encontrar suficientes recursos para esto eventualmente, pero me imaginé que es buen material para este sitio...

Digamos que tengo un espacio tridimensional, con coordenadas x, y y z. Entonces, tengo un conjunto de vectores (vértices en los gráficos por ordenador, supongo) en ese espacio (pueden estar formando un cubo, por ejemplo).

¿Cómo hago para transformarlos para que se rendericen en un plano 2D (pantalla)? Necesito obtener las coordenadas x e y de los vectores 2D, pero, deben depender de un punto específico en el espacio - la cámara. Cuando muevo la cámara, los valores x e y deben cambiar.

Supongo que el proceso será algo así:

  1. Traduzca los vectores 3D de acuerdo con la x, y y z de la cámara.
  2. Gira los vectores 3D de acuerdo a los theta y phi de la cámara (necesitaré muchas conversiones del sistema de coordenadas polares y del sistema de coordenadas polares para esto, pero el pecado y el cos no son caros, ¿verdad?)
  3. x = x/z, y = y/z, para la transformación en 2D, creo, no estoy seguro de esta parte en absoluto, creo que la vi en alguna parte.
  4. Escala todos los vectores de acuerdo con la distancia de la cámara a la escena (o algo más?)
  5. Renderizar.

Hice una lluvia de ideas sobre la marcha, probablemente hay una tonelada de soluciones mejores. También, por favor, trata de mantener las matemáticas simples, ya que sólo conozco la regla básica de trigonometría y calculo hasta la regla de la cadena, no estoy seguro de lo que la gente está usando realmente para esto. Escuché algo sobre "matrices de rotación", ¿qué son exactamente? (Bueno, estoy a punto de buscarlas en Google, pero no me hará daño obtener una respuesta aquí también.) Además, ¿cuáles son las direcciones estándar para el espacio xyz? (¿Es z "arriba"?)

1 votos

Si se divide por $z$ entonces eso significa que el $z$ -El eje apunta lejos de ti (los puntos del horizonte caen cerca del centro). El "viejo" libro de Mike Abrash: Zen de la programación gráfica es útil para conocer cómo se hacía todo esto en la época del DOS (al final explica cómo se codificó el motor 3D de Doom). Hoy en día OpenGL está de moda (Windows ofrece una interfaz estándar, y los fabricantes de tarjetas gráficas pueden escribir sus propios controladores), y en lugar de matrices de rotación utilizan cuaterniones (o eso he oído). Un aspecto que no has mencionado es el recorte 3D. Es geometría analítica básica, pero necesaria aquí.

0 votos

@JyrkiLahtonen, vale, anotado, pero recortar es hacer desaparecer lo que está lejos y lo que está demasiado cerca, ¿no? Puedo hacer eso...

1 votos

Seguro que sí. Pero tienes que recortar las cosas fuera del llamado view frustrum para que quede bien (el cono desde la cámara hasta el viewport extendido al infinito). Además: tienes que hacerlo antes de se divide por $z$ . No tratar de averiguar después como algún idiota intentó una vez hace enésimo años (silbidos y salidas atrás a la izquierda).

25voto

Priyank Puntos 159

enter image description here

Puede haber muchas formas de transferir el mundo 3d al plano 2d . Creo que la básica es la proyección planar que mostré en la imagen. Hice los pasos para los principiantes y evité las matemáticas altas para la comprensión clara. Creo que la rotación es el siguiente paso después de entender todos los puntos de cómo transferir un punto de 3D a 2D.

Me gustaría ofrecer que las matemáticas en esta conversión. Como se puede ver en la figura que desea encontrar m y n valores para la pantalla como entero.

1- Definir el punto superior izquierdo de la pantalla en el plano. $S_1 (x_1, y_1 , z_1)$

2- Definir el punto superior derecho de la pantalla en el plano. $S_2 (x_2, y_2 , z_2)$ . La anchura de la pantalla debe satisfacer $W=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2+(z_2-z_1)^2}$ .puede seleccionar $z_1=z_2$ para la vista recta así $W$ puede ser $\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}$ .

3- Definir el punto inferior izquierdo de la pantalla en el plano. $S_3 (x_3, y_3 , z_3)$ . La altura de la pantalla debe satisfacer $H=\sqrt{(x_3-x_1)^2+(y_3-y_1)^2+(z_3-z_1)^2}$ y también sabemos que el rectángulo de la pantalla. debe satisfacer $\vec{S_1S_2} . \vec{S_1S_3} =0 $ ----> $(x_2-x_1)(x_3-x_1)+(y_2-y_1)(y_3-y_1)+(z_2-z_1)(z_3-z_1)=0 $ Nota: Si queremos la vista recta, podemos seleccionarla $x_1=x_3$ y $y_1=y_3$ así $H$ será $z_1-z_3$

4- Encuentra el punto medio de la pantalla $ M (x_0,y_0,z_0)= (\frac{x_2+x_3}{2}, \frac{y_2+y_3}{2},\frac{z_2+z_3}{2})$

5- Definir a qué distancia estará la cámara de la pantalla. $(h)$

6-Encuentra el punto de la cámara: $C(x_c,y_c,z_c)$ hay que encontrar la ecuación del plano : $ax+by+cz=1$ tres puntos es suficiente para definir un plano. Así,

-Punto de Venta $S_1$ : $a x_1+by_1+cz_1=1$

-Punto de Venta $S_2$ : $a x_2+by_2+cz_3=1$

-Punto de Venta $M$ : $a x_0+by_0+cz_0=1$

Resolver $a,b,c$ y encontrar el vector de normalización que forma un ángulo recto con el plano $N= (a_n, b_n ,c_n)= ( \frac{a}{ \sqrt{a^2+b^2+c^2}}, \frac{b}{\sqrt{a^2+b^2+c^2}}, \frac{c}{\sqrt{a^2+b^2+c^2}})$

$C(x_c,y_c,z_c) = (x_0+ha_n,y_0+hb_n,z_0+hc_n)$

7-Encontrar $A'$ esa proyección del punto $A$ en el plano de la pantalla.

-Definir la línea entre el punto $C(x_c,y_c,z_c)$ y señalar $A(x_a,y_a,z_a)$ :

$\frac{x-x_a}{x_c-x_a}=\frac{y-y_a}{y_c-y_a}=\frac{z-z_a}{z_c-z_a}=k$

y poner $x$ , $y$ , $z$ en la ecuación del plano ( $ax+by+cz=1$ ) y obtener una ecuación depende de $k$ y luego resolver $k$ Puedes conseguir $A'(x'_a,y'_a,z'_a)$ de $\frac{x-x_a}{x_c-x_a}=\frac{y-y_a}{y_c-y_a}=\frac{z-z_a}{z_c-z_a}=k$ después de resolver $k$ .

8-Para encontrar los ángulos de la pantalla:

$\cos u=\frac{\vec{S_1S_2} . \vec{S_1A'}}{|\vec{S_1S_2}||\vec{S_1A'}|}=\frac{(x_2-x_1)(x'_a-x_1)+(y_2-y_1)(y'_a-y_1)+(z_2-z_1)(z'_a-z_1)}{W\sqrt{(x'_a-x_1)^2+(y'_a-y_1)^2+(z'_a-z_1)^2}}$ .

$\cos v=\frac{\vec{S_1S_3} . \vec{S_1A'}}{|\vec{S_1S_3}||\vec{S_1A'}|}=\frac{(x_3-x_1)(x'_a-x_1)+(y_3-y_1)(y'_a-y_1)+(z_3-z_1)(z'_a-z_1)}{H\sqrt{(x'_a-x_1)^2+(y'_a-y_1)^2+(z'_a-z_1)^2}}$ .

9-Decisión de si está en pantalla o no: Si $\cos u >0 $ y $\cos v >0 $ entonces $A'$ está en pantalla. En caso contrario, el punto $A'$ está fuera de la pantalla y no podemos dibujar $A'$ en pantalla 2D.

10- Encuentra $m$ , $n$ Si $\cos u >0 $ y $\cos v >0 $

$m= \sqrt{(x'_a-x_1)^2+(y'_a-y_1)^2+(z'_a-z_1)^2} \cos u $

$n= \sqrt{(x'_a-x_1)^2+(y'_a-y_1)^2+(z'_a-z_1)^2} \sin u $

Necesitamos enteros si es así debemos ignorar después del punto para $m$ y $n$ para obtener valores enteros.

Asegúrese de que si $m>W$ y $n>H$ entonces no podemos dibujar el punto en la pantalla.

Ejemplo:

1: $S_1 (400, 400 ,400)$

2: si el ancho de nuestra pantalla es de 800 píxeles $S_2 (880, 1040 , 400)$ $z_1=z_2$ para la vista recta así $W=\sqrt{(880-400)^2+(1040-400)^2}=800$

3: $S_3 (400, 400 ,-200)$ así $H=600$

4: $M (x_0,y_0,z_0)=(640,720,100)$

5: Definir a qué distancia estará la cámara de la pantalla. Seleccioné $h=50$ . si h es más pequeño se puede ver más área en la pantalla. Se puede cambiar en el software como parámetro para obtener la mejor vista para la pantalla.

6:Encuentra el punto de la cámara: $C(x_c,y_c,z_c)$ hay que encontrar la ecuación del plano : $ax+by+cz=1$

$400a+400b+400c=1$

$880a+1040b+400c=1$

$640a+720b+100c=1$

aquí solución que wolfram ayudó:

$a=\frac{1}{100}$

$b=-\frac{3}{400}$

$c=0$

Así, la ecuación del plano de la pantalla es $\frac{1}{100}x-\frac{3}{400}y=1$

$4x-3y=400$

$N= (a_n, b_n ,c_n)= (\frac{4}{5},-\frac{3}{5},0)$

$C(x_c,y_c,z_c)=(640+50.\frac{4}{5},720- 50\frac{3}{5},100 )=(680,690,100)$

7-Encontrar $A'$ esa proyección del punto $A$ en el plano de la pantalla. $A$ dado $(0,400,400)$

$\frac{x}{680}=\frac{y-400}{690-400}=\frac{z-400}{100-400}=k$

$4x-3y=400$

$4(680k)-3(290k+400)=400$

$k=\frac{32}{37}$

$x=680k=680\frac{32}{37}=\frac{21760}{37}= \approx 588,10$

$y=290k+400=290\frac{32}{37}+400=\frac{24080}{37} \approx 650,81$

$z=-300k+400=-300\frac{32}{37}+400=\frac{5200}{37} \approx 140,54$

8- $ \cos u=\frac{\vec{S_1S_2} . \vec{S_1A'}}{|\vec{S_1S_2}||\vec{S_1A'}|}=\frac{480.188,10+640.250,81 }{800. 406,948}\approx 0,77038$

$\cos v=\frac{\vec{S_1S_3} . \vec{S_1A'}}{|\vec{S_1S_3}||\vec{S_1A'}|}=\frac{(-259,46).(-600) }{600. 406,948}\approx 0,6375$

9- $\cos u >0 $ y $\cos v >0 $ Así, el punto está en el lado de la pantalla. $ \cos u\approx 0,77038$ $\sin u \approx 0,63758 $

10- $0,77038.406,948=313,50$ -----> $ m = 314$

$0,63758.406,948=259.46$ -----> $ n= 259$

$m<800$ y $ n<600$ Así podemos dibujar el punto en la pantalla. $m$ y $n$ se seleccionan enteros porque necesitamos encontrar los valores de los píxeles de la pantalla.

El ejemplo es para demostrar la transferencia de un solo punto de 3D a 2D. Espero que le dé un punto de partida para utilizar las herramientas de geometría analítica 3D para su propósito.

0 votos

Muy buena explicación al final

0 votos

@amd Muchas gracias por los comentarios.

0 votos

Aunque el significado geométrico de $\cos u$ y $\cos v$ en los pasos 8 y 9 es transparente, creo que podría ser más limpio obtener $m$ y $n$ de una ecuación paramétrica del plano de la imagen. El recorte a la parte visible de la pantalla se convierte en una simple comprobación de rango en $m$ y $n$ . Es decir, establecer $U=(S_2S_1)/\|S_2S_1\|$ y $V=(S_3S_1)/\|S_3S_1\|$ y resolver para $(m,n)$ en $S_1+mU+nV=A$ . El punto proyectado es visible cuando $0\le m\le W$ y $0\le n\le H$ .

3voto

Venkat Kotra Puntos 279

Asistí al ciclo de conferencias del profesor Neil Dodgson en la Universidad de Cambridge, donde expuso una serie de manipulaciones matriciales que, combinadas, dan el resultado que usted pide . Desde su Notas de la conferencia de 1998 : enter image description here enter image description here enter image description here enter image description here

0 votos

Tenga en cuenta que este no es un tema trivial. Hay muchos resultados sorprendentes que atrapan a los recién llegados; por ejemplo, cuando se proyecta un Línea recta 3D en una pantalla 2D desde la perspectiva de una cámara estenopeica, el resultado suele ser un Curva 2D ¡!

1 votos

El enlace está roto. (Esta información viene por cortesía de @TemPora, que intentó comunicarlo a través de una edición).

0 votos

@Potato: He arreglado el enlace no mucho después de que lo señalaras. Puedes editar las imágenes directamente en mi respuesta de StackExchange, en caso de que esto ocurra de nuevo (¡gracias de antemano a quien tenga tiempo de hacerlo!).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X