¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Intersección de un rayo con una esfera

Después de esta lección: Puedo calcular dónde un rayo toca una esfera.

Lección de 75 min2 comandosLaboratorio de visión por computador: píxeles, umbrales y recuento de objetos en JupyterLab

Un rayo pregunta qué objeto ve primero

Un rayo es una recta que sale de la cámara y atraviesa un píxel. Saber dónde toca ese rayo a una esfera permite decidir de qué color pintar el píxel.

Esta idea se llama trazado de rayos, y empieza con una ecuación de segundo grado.

Al final de esta lección

Nota

Puedo calcular dónde un rayo toca una esfera.

Palabras clave

PalabraQué significa
Rayouna recta con un origen y una dirección
Parámetro tcuánto avanzas por el rayo desde su origen
Esferalos puntos que están a un radio de un centro
Discriminanteel número que dice cuántas veces corta el rayo
Impactoel punto donde el rayo toca la esfera

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un rayo es un origen y una dirección

Un rayo tiene un punto de salida o y una dirección d. Sus puntos son o + t * d, con t mayor o igual que 0.

Con t = 0 estás en el origen. Con t = 1 has avanzado una dirección entera. Con t = 2, dos. Cuanto mayor es t, más lejos estás.

Ejemplo resuelto: un rayo hacia delante

tPunto del rayo (origen 0, 0, 0 y dirección 0, 0, 1)Distancia al centro (0, 0, 5)
0(0, 0, 0)5
2(0, 0, 2)3
4(0, 0, 4)1, justo el radio: es el impacto
5(0, 0, 5)0, el centro

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

El impacto sale de una ecuación cuadrática

Quieres los t para los que o + t * d está a un radio del centro. Sea oc = o - centro. Calcula tres números: a = d · d, b = oc · d y k = oc · oc - radio * radio.

El punto · es el producto escalar: multiplicas coordenada a coordenada y sumas. El discriminante es b * b - a * k, y los impactos son (-b - raíz) / a y (-b + raíz) / a.

Ejemplo resuelto: tres rayos, tres resultados

CasoabkDiscriminanteQué pasa
Hacia una esfera de centro (0, 0, 5)1-5241Da en t = 4 y en t = 6
Hacia una esfera de centro (0, 1, 5)1-5250La roza en t = 5
Hacia arriba, dirección (0, 1, 0)1024-24No da: es negativo

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Calcula el discriminante de tres rayos

Comando
docker exec jupyter python3 -c "d = lambda o, v, c, r: (lambda oc: sum(p * q for p, q in zip(oc, v)) ** 2 - sum(q * q for q in v) * (sum(p * p for p in oc) - r * r))(tuple(a - b for a, b in zip(o, c))); print(d((0, 0, 0), (0, 0, 1), (0, 0, 5), 1), d((0, 0, 0), (0, 0, 1), (0, 1, 5), 1), d((0, 0, 0), (0, 1, 0), (0, 0, 5), 1))"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Qué dicen los tres discriminantes

Imprime 1 0 -24, los tres de la tabla. El primero es positivo: el rayo atraviesa la esfera y la corta en dos puntos. El segundo es 0: la roza en uno solo.

El tercero es negativo y no tiene raíz cuadrada real: el rayo pasa de largo. Basta mirar el signo para saber si hay impacto.

Calcula el primer impacto

Código: python
# Un rayo desde (0, 0, 0) hacia delante y una esfera de centro (0, 0, 5) y radio 1.
import math

origen = (0, 0, 0)
direccion = (0, 0, 1)
centro = (0, 0, 5)
radio = 1
oc = (origen[0] - centro[0], origen[1] - centro[1], origen[2] - centro[2])
a = direccion[0] * direccion[0] + direccion[1] * direccion[1] + direccion[2] * direccion[2]
b = oc[0] * direccion[0] + oc[1] * direccion[1] + oc[2] * direccion[2]
k = oc[0] * oc[0] + oc[1] * oc[1] + oc[2] * oc[2] - radio * radio
disc = b * b - a * k
print("discriminante:", disc)
if disc >= 0:
    print("primer impacto en t =", (-b - math.sqrt(disc)) / a)
# Cambia centro a (0, 1, 5): el rayo solo roza la esfera.

Solo vale un t positivo

De los dos impactos te interesa el menor que sea positivo: el primero que ve la cámara. Si los dos son negativos, la esfera está detrás del origen y no se ve.

Si el origen está dentro de la esfera, uno es negativo y el otro positivo. Entonces vale el positivo.

Un error muy común

Advertencia

Mucha gente cree que un discriminante positivo siempre significa que la esfera se ve. No basta: con la esfera detrás de la cámara el discriminante también es positivo, pero los dos t son negativos. Comprueba siempre el signo de t.

Dibuja la silueta de una esfera con rayos

Comando
docker exec jupyter python3 -c "print('\n'.join(''.join('#' if 2400 ** 2 - (x * x + y * y + 1600) * 3276 > 0 else '.' for x in range(-13, 14)) for y in range(-12, 13, 2)))"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Cómo se lee la silueta de la esfera

La cámara está en el origen. La esfera tiene su centro en (0, 0, 60) y radio 18. Cada rayo lleva la dirección (x, y, 40). Cada # es un píxel cuyo rayo tiene discriminante positivo.

Imprime 13 filas. La primera y la última tienen 7 # y las tres del medio tienen 25. Se ve un círculo: la silueta de la esfera.

Para ir más lejos: cambia el radio

Ejecuta de nuevo el comando de la silueta y cambia el 3276 por 2000. Ese número es la distancia al centro al cuadrado menos el radio al cuadrado: 3600 menos 324.

Con 2000 el radio de la esfera sale de 40 y no de 18. Verás que la silueta llena toda la ventana, sin ningún punto. Calcula antes por qué.

Sobre este laboratorio y su código: Laboratorio de visión por computador: píxeles, umbrales y recuento de objetos en JupyterLab

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.