Proyección punto-rayo y punto-línea

proyección punto-rayo.png

En 3D es bastante común hacer un uso intensivo del álgebra. Hay ciertas herramientas muy útiles alrededor de las cuales se puede desarrollar gran parte de la lógica de estos programas. Entre estas se encuentran las proyecciones y las intersecciones de figuras geométricas: líneas, rayos, planos, puntos, etc.

Voy a explicar brevemente el funcionamiento de las proyecciones punto-rayo y punto-línea. Como se ve en el dibujo lo que queremos es, a partir de un rayo (definido por un punto r_0 y un vector director r_d) y un punto P, encontrar el punto dentro del rayo que se encuentra más cerca de P. En el caso de la proyección punto-línea, además, queremos comprobar que el resultado de esta proyección se encuentra delimitada entre dos puntos.

Entendiendo la parte matemática

Haciendo una búsqueda rápida por Internet es fácil ver que este problema se soluciona mediante el producto punto, pero creo que es interesante entender por qué esto funciona y no limitarse a creerlo, puesto que nos abre la mente a otras soluciones. El producto punto de dos vectores se calcula de la siguiente manera:

\left \langle x_0,y_0,z_0 \right \rangle \cdot \left \langle x_1,y_1,z_1 \right \rangle = x_0 x_1 + y_0 y_1 + z_0 z_1

Esta ecuación nos servirá para realizar el cálculo pero no para entender la naturaleza de la proyección. El producto punto también puede entenderse como el coseno del ángulo \theta que forman los vectores, considerando su longitud:

\left \langle x_0,y_0,z_0 \right \rangle \cdot \left \langle x_1,y1_,z_z1 \right \rangle = ||v_0||\cdot||v_1|| \cdot cos(\theta)

Por último, a modo de conveniente recordatorio debemos tener en cuenta que el coseno de un ángulo es la relación entre el lado adyacente al ángulo y la hipotenusa:

cos(\theta) = \frac{adyacente}{hipotenusa}

Proyeccion punto-rayo2

Ahora que sabemos esto, podemos obtener un vector que vaya del punto origen del rayo r_0 al punto que queremos proyectar P, entendiendo este como el lado adyacente del triángulo que forman el rayo, el punto y la proyección. Como la dirección del rayo es un vector unitario, su magnitud puede desconsiderarse, teniendo que el producto punto es la relación entre ambos vectores multiplicada por la magnitud del vector \overrightarrow{r_0P}:

||r_d|| \cdot || \overrightarrow{r_0P} || \cdot cos(\theta) = 1\cdot|| \overrightarrow{r_0P} || \cdot cos(\theta)

El resultado nos indica la distancia entre el origen del rayo r_0 y la proyección del punto, y el signo de este el sentido en el que se proyecta el punto. En el caso de la proyección punto-línea, tan sólo es necesario comprobar que dicha distancia esté dentro de la longitud de la línea.

En código

En C++ haciendo uso de la biblioteca de GLM, la implementación es tan sencilla como:

//Devuelve la distancia de ray_origin a la proyección
float point_ray_projection(glm::vec3 ray_origin, glm::vec3 ray_direction, glm::vec3 point) {
     // Tan sólo si no podemos garantizar que ray_direction sea unitario
     ray_direction = glm::normalize(ray_direction);
     return glm::dot(ray_direction, point - ray_origin);
}

// Devuelve true si la proyección está dentro de la línea
// Asigna el punto resultante a "result"
bool point_line_projection(glm::vec3 A, glm::vec3 B, glm::vec3 point, glm::vec3 & result) {
     glm::vec3 direction = glm::normalize(B - A);
     float projection = point_ray_projection(A, direction, point);
     result = A + direction * projection;
     float length = glm::length(B - A);
     return (
          (compare_float(projection, 0.0f) || projection > 0) &&
          (compare_float(projection, length) || projection < length)
     );
}

Nótese el uso de la función compare_float. Esta se utiliza en vez del operador “==” porque no se pueden comparar números de coma flotante sin tener en cuenta la pérdida de precisión. Esta función equivale a abs(B-A) < epsilon, siendo epsilon un número muy pequeño, como 0.00001. Si no sabes por qué se hace, recomiendo informarse al respecto antes de seguir programando.

Sustituyendo el PC por un ipad

A nadie se le escapa que Apple está intentando, desde hace unos años, conseguir que los usuarios dejen a un lado sus ordenadores y utilicen iPad para realizar las mismas tareas.

Con ese propósito sacaron al mercado el iPad Pro, aunque esto de “Pro” puede ser para muchos un tanto discutible. Lo cierto es que no está pensado para un uso profesional más allá de unas cuantas aplicaciones de ofimática y utilidades de productividad, pero eso no impide que para aquellos con menos necesidades pueda convertirse en una herramienta de trabajo, o en un buen dispositivo para crear contenido y no sólo consumirlo.

Para quienes necesitamos trabajar con herramientas completas y potentes resulta un tanto confuso y frustrante, pero para el resto de la humanidad esta coletilla inspira calidad y potencia, lo cual nos da una idea de hacia quién está realmente dirigido este producto.

Es por esto que realmente nos queda mucho camino por delante si queremos ver los ordenadores de toda la vida convertidos en un nicho de mercado. En mi opinión, el iPad tiene una serie de carencias que hace muy difícil convertirlo en un sustituto absoluto del PC. Para un uso profesional lo más similar que puede comprarse es una Microsoft Surface, que no deja de ser un PC.

Navegar por Internet

En una tablet, es una experiencia muy distinta a la que podemos tener con un ordenador: la naturaleza mixta del sistema operativo, más cercana a los móviles que a los ordenadores, hace que la mayoría de sitios web estén preparadas para mostrarse en formato móvil. Dicho formato no es para nada adecuado para ser visto en horizontal con una pantalla de 9 pulgadas para arriba.

Este hecho se alivia un poco gracias a la existencia de aplicaciones para prácticamente cualquier servicio que podamos querer utilizar online, pero eso insuficiente en un momento en que la web todavía tiene demasiada importancia.

Si voy a utilizar una tablet como dispositivo principal, tengo que poder hacer todo lo que antes hacía en el PC y eso incluye navegar por la web “tradicional”.

Trabajar durante horas

Faltan mejores sistemas para interactuar durante muchas horas. Poder utilizar la tablet con los dedos está muy bien, pero si queremos utilizar el iPad con un teclado durante 6-8 horas, vamos a querer un dispositivo que nos permita hacerlo cómodamente durante largos períodos de tiempo. Para un uso como ese el mejor dispositivo que conocemos hoy en día es el ratón.

Entiendo perfectamente por qué Apple no se lanza a soportar ratones en su tablet: es más complicado que las pantallas táctiles y haría que el iPad fuera menos portátil, teniendo que cargar con un dispositivo adicional para usarlo (aunque no obligatoriamente). Puede ser difícil darse cuenta cuando ya estamos tan acostumbrados a un ratón, pero si alguien ha visto alguna vez a gente aprendiendo a usar el ordenador por primera vez habrá comprobado que es precisamente lo menos intuitivo y más difícil de aprender.

Sin embargo, me sorprende ver que la mayoría de opiniones que he encontrado al respecto ignoran las ventajas de un ratón respecto a una pantalla táctil: no tapa la pantalla constantemente, permite tener el brazo reposando sobre la mesa (no me quiero imaginar 8 horas de programación con una pantalla táctil y un teclado), facilita la selección de texto y tiene un botón secundario más fácil de usar que el ya clásico “mantener la pantalla pulsada”. Sí, es cierto, el ratón tiene muchas desventajas pero si lo que queremos es permitir un uso prolongado y diario, es necesario.

En el fondo, las razones para poder querer un ratón en vez de una pantalla táctil son exactamente las mismas que para querer un teclado físico. Cualquier otra solución puede sacarte del apuro pero para escribir un texto de 1000 palabras necesitas un teclado, y para interactuar durante 8 horas con una pantalla necesitas un ratón.

Por no mencionar que abriría la puerta a otros usos menos profesionales como el de los juegos con teclado y ratón. El iPad, aunque está a años luz de ser una máquina para gaming, es perfectamente capaz de ejecutar juegos 3D bastante decentes en primera o tercera persona (como tantos que ya hay), pero una interfaz táctil deja mucho que desear en esta clase de juegos.

Adaptar el sistema operativo para usarse con un ratón implicaría reimaginarlo en muchos aspectos para ofrecer una experiencia de uso tan buena como la que ofrecen los dedos, pero si hay alguien que puede solucionar eso ahora mismo es Apple.

No dudo por un momento de las bondades de las pantallas táctiles, pero sencillamente hay un momento para cada cosa y si Apple pretende que dejemos el ordenador cogiendo polvo tarde o temprano tendrá que soportar el uso de un ratón.

Un sistema de archivos

Tengo que confesar que no tengo una buena solución para este detalle. Apple nunca ha dejado acceder al sistema de archivos en iOS y eso tiene muchas ventajas para la mayoría de usuarios, pero si lo que quieres es que la gente deje de utilizar el PC la cosa cambia.

Qué pasa si acabo de hacer un programa en C++ con 50 ficheros y hacer commit en git? Si intentáramos hacer eso en iOS en el estado actual, aun suponiendo que contáramos con un IDE, el proceso sería enormemente tedioso. La solución de Apple de permitir crear extensiones en iOS puede dar el pego para muchas cosas, pero para un profesional de verdad es lo que es: un apaño, inviable para trabajar en serio. Y ya no hablemos de compilar y ejecutar o debugar, lo cual es sencillamente impensable.

Y esta situación es extrapolable a muchas profesiones: ¿Qué pasa con quienes usan AutoCad? ¿O los profesionales de la música/video? iOS no está preparado para solucionar las necesidades de los “hard” profesionales y en mi opinión no lo estará nunca.

En conclusión creo que el iPad, tal como lo conocemos, es capaz de reducir los ordenadores a un nicho si se arreglan ciertos detalles, pero no de hacerlos desaparecer.