martes, 24 de enero de 2023

Proyección lineal de escenas 3D sobre el plano con R

Tanto si tienes una cámara de fotos, usas programas para hacer render o te echas partidas a videojuegos 3D, lo que estás viendo en tus fotos o en la pantalla del ordenador no es información tridimensional real sino una aproximación plana de la misma.

Fuentes: Julius Shulman, Grupo Aranea, Quake III Arena

Estas aplicaciones comparten la forma más general, tanto por su realismo como por la facilidad de ser implementada, de representar en un dispositivo plano una escena tridimensional: realizar una proyección lineal de la escena 3D sobre un plano. Es lo que en geometría descriptiva se ha venido a llamar perspectiva cónica y que resulta realmente laboriosa de dibujar a mano.


~~~

Pero su formulación matemática es trivial hasta el insulto: basta aplicar una semejanza de triángulos para calcular la proyección de cualquier punto del espacio sobre el plano, así que los programadores aquí están de enhorabuena frente a los dibujantes.

El siguiente esquema explica la geometría de este sistema de representación: proyectamos coordenadas tridimensionales sobre un plano mediante rectas proyectantes que pasan por determinado punto. El resultado se aproxima a una visión realista obtenida si el ojo estuviera situado en dicho punto y mirando en dirección perpendicular al plano, haciendo que los objetos lejanos aparezcan más pequeños que los cercanos (clic para mayor resolución):


Situando el punto de observación en el origen de coordenadas O(0,0,0), un punto P(x,y,z) del espacio real 3D se proyecta sobre el plano de distancia focal f como el punto P'(x',y',f). La obtención de las coordenadas (x',y') de la proyección a partir de las coordenadas (x,y) del punto en el espacio 3D resulta inmediata por semejanza de triángulos (teorema de Thales):


Vemos que las coordenadas originales quedan reducidas por el factor f/z, que es la relación entre la distancia f del plano de proyección (distancia focal) y la distancia z que hay entre el observador (cámara) y el punto (sujeto), en la dirección perpendicular al plano de proyección (eje Z). Esta relación f/z es muy interesante para entender el efecto de:

  • La distancia focal (f): alterar f, es decir desplazar el plano de proyección, es equivalente a hacer un escalado o zoom de la imagen proyectada, pero no cambia las relaciones de tamaño entre objetos y por tanto no modifica la perspectiva. Así dada una superficie de proyección, f solo define el ángulo de visión abarcado.
  • La distancia al sujeto (z): en cambio al ser z un valor propio de cada elemento de la escena, hará que se les aplique un factor diferente determinando la perspectiva de la imagen obtenida. Si z tiende a infinito (sujetos lejanos), el factor f/z será aproximadamente igual para todos ellos obteniendo una perspectiva axonométrica.

~~~

Todo lo dicho es plenamente aplicable al ámbito de la fotografía, de hecho el esquema anterior es equivalente al funcionamiento de la cámara oscura o estenopeica. Así hemos hecho una demostración gráfica y matemática de que la distancia focal de un objetivo no altera la perspectiva, dependiendo ésta solo de la distancia a la cámara. Esto es algo que confunden muchos fotógrafos, incluso entre los más experimentados.

Otra lectura que obtenemos es que cualquier objeto con forma de línea recta en el mundo real se proyectará también como una recta en el plano (distorsiones de barril/cojín de la óptica al margen). De hecho ni siquiera tiene que ser un objeto realmente rectilíneo, basta que se presente como tal al observador. Por ejemplo la Vía Láctea, pese a su forma de espiral, desde nuestro planeta se ve como una alineación de estrellas al estar la Tierra contenida en ella y por eso la capturamos como una recta, mal que le pese a algunos fotógrafos de nocturnas que la prefieren representar como un arco (curvatura que resulta del software de montar panorámicas).

Por la misma geometría de la proyección, los sujetos contenidos en cualquier plano paralelo al plano de proyección quedarán representados con su forma original sin distorsionarse debido a la perspectiva. Por ejemplo una circunferencia impresa se mantendrá como tal si se fotografía apuntando la cámara perpendicularmente al papel, deformándose con forma de elipse en cualquier otro caso.

Sobre la relación f/z aplicada a la fotografía, cuando retratamos sujetos a gran distancia con un teleobjetivo tendremos esa perspectiva axonométrica de la que hablábamos, y que los fotógrafos conocen como "compresión de planos". Pero no olvidemos por lo ya dicho que la variable clave para obtener esta perspectiva plana no es el uso de una focal larga, sino colocarnos a gran distancia del sujeto.

~~~

Con las ecuaciones vistas he construido unas animaciones 3D con esferas. Estrictamente una esfera fuera del eje se proyectaría sobre el plano como una elipse, pero como aproximación para dibujarlas sin complicarnos uso circunferencias de radio el de la esfera escalado por el mismo factor f/z que aplica a la localización de su centro.

He escogido esferas porque tienen una propiedad que quería explotar: mientras no lleguen a intersecarse disponemos de un algoritmo de eliminación de partes ocultas tan sencillo como dibujarlas por orden, de mayor a menor distancia al observador: las que estén más cerca ocultarán a las que están más lejos allá donde corresponda por solape.

Para otro tipo de volúmenes, detectar cómo los objetos se tapan o intersecan entre ellos resulta mucho más complejo. A día de hoy estos algoritmos ya están muy bien implementados, incluso por hardware, en los motores de render que se usan en todos los programas 3D.


Como trampantojo para generar una sensación adicional de profundidad, aplicamos un efecto de perspectiva aérea dibujando las esferas con tonos de gris definidos por su distancia al observador.



Puede encontrarse aquí un vídeo sincronizando la animación inicial con audio. Se ha hecho todo a mano desde cero con R. Vídeo final generado en línea de comandos con FFmpeg.

Sobre las rotaciones en 3D a lo largo de un eje, es interesante apuntar que normalmente no son conmutativas. Es decir que si realizamos rotaciones sobre más de un eje, alterar el orden en que se aplican dará generalmente diferente resultado:

Fuente: Benjamin Crowell

~~~

Repositorio con el código R: GitHub.


No hay comentarios:

Publicar un comentario

Por claridad del blog, por favor trata de utilizar una sintaxis lo más correcta posible y no abusar del uso de emoticonos, mayúsculas y similares.