Apuntes / Visión por Computador / Apunte 1 de 6

Read in English

Coordenadas homogéneas

Tres números para cada punto y cada recta del plano, para que unir dos puntos y cortar dos rectas tome un solo producto cruz.

Dos preguntas aparecen todo el tiempo cuando un computador trabaja con geometría: ¿qué recta pasa por dos puntos dados, y dónde se cortan dos rectas dadas?

  • La recta que pasa por dos puntos

  • El punto donde se cortan dos rectas

  • Dos rectas paralelas: ¿se cortan?

Con las x e y del colegio son dos cálculos distintos, y cada uno falla en algún caso: una recta escrita con su pendiente no puede ser vertical, y el corte de dos rectas paralelas termina en una división por cero. Las coordenadas homogéneas describen cada punto y cada recta del plano con tres números en vez de dos. Así, ambas preguntas tienen la misma respuesta, un producto cruz, e incluso dos rectas paralelas tienen un punto donde se cortan. La geometría de cámaras de los apuntes que siguen está escrita en ellas.

En esta página, los puntos se dibujan con tinta roja y las rectas con tinta azul.

1Una tercera coordenada para cada punto

Escribe el punto (x, y) con un tercer número, 1:

m = xy1

Por ahora, el tercer número no agrega nada. Lo que hace útiles a estas coordenadas es una regla sobre los tres a la vez: multiplicar el vector por cualquier número λ distinto de 0 da el mismo punto. Estos tres vectores son todos el punto (2, 3):

231 ∼ 462 ∼ −1−1.5−0.5

Para leer el punto de vuelta, divide los dos primeros números por el tercero. Si m = [p q r]T, el punto es

(x, y) = (pr, qr)

La división cancela λ, porque λp / λr = p / r. Así, un cálculo puede terminar con cualquier tercer número: divide por él antes de leer el resultado. λ = 0 queda fuera porque convierte todo punto en [0 0 0]T, y un vector cuyo tercer número es 0 no tiene nada por lo cual dividir; la sección 6 muestra qué significa un vector así.

Cada punto es una recta que pasa por el origen

Detrás de la regla hay una imagen. Lee [p q r]T como una posición en un espacio con ejes p, q y r. El plano de siempre está en ese espacio a la altura r = 1, así que m = [x y 1]T es un punto sobre él. Cada múltiplo λm está en la recta que pasa por el origen y por m, y esa recta cruza el plano una sola vez, en m. Dividir por r desliza un vector a lo largo de su recta, de vuelta al plano. Un λ negativo lo deja al otro lado del origen, siempre en la misma recta.

Si el origen fuera un ojo y el plano r = 1 una ventana, cada una de estas rectas sería una línea de visión: todo lo que está sobre ella cae en el mismo lugar de la ventana. Así ve una cámara, y los apuntes de cámaras vuelven a esta imagen. La recta roja de la figura no es una recta del plano: contiene todos los vectores que representan a m.

Arrastra m por el plano y λm a lo largo de su recta, y arrastra el fondo para girar la vista. Con el teclado, selecciona la figura, λm o m con Tab y usa las flechas.

2Una recta también son tres números

Una recta del plano tiene una ecuación ax + by + c = 0. Sus tres coeficientes la describen por completo, así que la recta también puede escribirse como un vector:

ℓ = abc ⟷ ax + by + c = 0

Por ejemplo, [1 −2 4]T es la recta x − 2y + 4 = 0. Igual que con los puntos, la escala no importa: multiplicar toda la ecuación por λ no cambia qué puntos la cumplen, así que [2 −4 8]T y [−1 2 −4]T son la misma recta.

Cuándo un punto está en una recta

Reemplaza m = [x y 1]T en el lado izquierdo de la ecuación, y lo que calculas es un producto punto:

ℓTm = ax + by + c

El punto está en la recta exactamente cuando ℓTm = 0. El punto (2, 3) está en x − 2y + 4 = 0, porque 1·2 + (−2)·3 + 4·1 = 0; el punto (6, 3) no, porque 1·6 + (−2)·3 + 4·1 = 4. La prueba solo pregunta si el resultado es cero, así que da la misma respuesta con cualquier múltiplo de ℓ o de m.

La recta en un x dado

Para dibujar una recta, o saber dónde está en un x dado, despeja y de su ecuación:

y = −(ax + c) / b

Esto requiere b ≠ 0; con b = 0 la recta es vertical, x = −c/a. En x = 6, la recta anterior tiene y = −(6 + 4) / (−2) = 5: el punto (6, 5), justo encima de (6, 3).

ℓ = ⟷

Cambia a, b y c para mover la recta, y arrastra m hasta ella. El anillo marca el punto de la recta en el x de m. Con el teclado, selecciona m o un coeficiente con Tab y usa las flechas.

3Cada recta es un plano que pasa por el origen

Vuelve al espacio de la sección 1, con ejes p, q y r. Los vectores [p q r]T con ap + bq + cr = 0 forman un plano que pasa por el origen, y ℓ = [a b c]T es perpendicular a él, ya que su producto punto con cualquier vector del plano es cero. Ese plano corta a r = 1 exactamente en la recta ax + by + c = 0.

Así, un punto es una recta que pasa por el origen, y una recta es un plano que pasa por el origen. El punto m está en ℓ cuando la recta de m está dentro del plano de ℓ, que es lo que dice ℓTm = 0. Escalar ℓ estira o invierte el vector perpendicular, pero el plano sigue siendo el mismo, y la recta también. El vector cero es perpendicular a todos los vectores y no define ningún plano, por eso aquí también λ ≠ 0.

Las dos secciones que siguen usan esta imagen: unir dos puntos y cortar dos rectas se reducen a planos que pasan por el origen.

ℓ = ⟷

Arrastra λℓ a lo largo de su recta, cambia a, b y c para mover la recta, y arrastra el fondo para girar la vista. Gira la vista hasta que el plano azul se reduzca a una línea: λℓ lo corta entonces en ángulo recto. Con el teclado, selecciona la figura, λℓ o un coeficiente con Tab y usa las flechas.

4La recta que pasa por dos puntos

ℓ = m1 × m2

¿Por qué funciona? El producto cruz de dos vectores es perpendicular a ambos, y perpendicular significa producto punto cero. Así, ℓTm1 = 0 y ℓTm2 = 0, que es la prueba de la sección 2 para ambos puntos: ℓ pasa por los dos. En la imagen de la sección 3, las rectas de m1 y m2 abren un plano que pasa por el origen, el plano de la recta que pasa por ambos puntos, y m1 × m2 es el vector perpendicular a él.

Para puntos de la forma [x y 1]T, el producto cruz queda

ℓ = y1 − y2x2 − x1x1y2 − x2y1

El resultado rara vez está en su forma más simple. Para los puntos (2, 1) y (8, 5) da [−4 6 2]T, que dividido por −2 es [2 −3 −1]T, la recta 2x − 3y − 1 = 0. Por la sección 2, ambos vectores son la misma recta.

Arrastra m1 y m2. Con el teclado, selecciona un punto con Tab y muévelo con las flechas.

5Dónde se cortan dos rectas

m = ℓ1 × ℓ2

Es la misma operación con los papeles intercambiados. El vector m es perpendicular tanto a ℓ1 como a ℓ2, así que ℓ1Tm = 0 y ℓ2Tm = 0: el punto está en ambas rectas. En la imagen de la sección 3, los planos de las dos rectas se cortan en una recta que pasa por el origen, y esa recta es el punto m.

El resultado [p q r]T rara vez termina en 1, así que divide por r antes de leerlo. La recta 2x − 3y − 1 = 0 de la sección 4 y la recta 2x + y − 13 = 0 dan [40 24 8]T, y al dividir por 8 queda el punto (5, 3).

Cuando las dos rectas son paralelas, r da 0 y no hay nada por lo cual dividir. No es una falla del método: la sección 6 muestra qué significa el vector.

Arrastra los círculos para mover las rectas. Cada recta es el producto cruz de sus dos círculos, dividido hasta su forma más simple; cualquier múltiplo daría el mismo punto. Prueba a hacerlas paralelas.

6Las rectas paralelas se cortan en el infinito

Dos rectas paralelas siempre pueden escribirse con los mismos a y b, así que solo difieren en c: ℓ1 = [a b c]T y ℓ2 = [a b c′]T. Su producto cruz es

m = ℓ1 × ℓ2 = (c′ − c) [b −a 0]T

Su tercer número es 0, así que no se puede dividir para obtener un punto del plano. Sus dos primeros números apuntan a lo largo de ambas rectas: moverse en (b, −a) no cambia ax + by, porque ab − ba = 0.

La imagen en el espacio muestra lo que pasó. Los planos de las dos rectas siguen cortándose en una recta que pasa por el origen, pero para rectas paralelas esa recta queda en el suelo r = 0, paralela al plano r = 1, así que nunca llega a él. Cuando una recta gira hacia la paralela, el corte se aleja y la recta de m se aplana; pasada la paralela, el corte vuelve por el lado opuesto.

Un vector [p q 0]T se llama punto ideal, o punto en el infinito: el punto donde se cortan todas las rectas con dirección (p, q). Con los puntos ideales, dos rectas distintas cualesquiera se cortan en exactamente un punto, incluso si son paralelas.

La línea en el infinito

Todo punto ideal cumple 0·p + 0·q + 1·0 = 0, así que todos están en una misma recta, ℓ∞ = [0 0 1]T, la línea en el infinito. Su plano en el espacio es el suelo, r = 0.

Arrastra el círculo azul para girar ℓ2 en torno al punto pequeño, y arrastra el fondo para girar la vista. Baja el círculo de a un paso: el corte se aleja, las rectas se vuelven paralelas, y el corte vuelve por el otro lado. Con el teclado, selecciona la figura o el círculo con Tab y usa las flechas.

7Resumen

Las ideas clave junto a sus equivalentes en NumPy.

Punto en forma homogénea
m = [x y 1]T
m = np.array([x, y, 1])
De vuelta a cartesianas
(p/r, q/r)
x, y = m[0]/m[2], m[1]/m[2]
La escala no importa
λm ∼ m, λℓ ∼ ℓ (λ ≠ 0)
No hay código: es una propiedad, no una operación.
La recta como vector
ℓ = [a b c]T ⟷ ax + by + c = 0
ell = np.array([a, b, c])
Punto en una recta
ℓTm = 0
np.isclose(np.dot(ell, m), 0)
y para un x dado
y = −(ax + c) / b
y = -(a*x + c)/b
Recta que pasa por dos puntos
ℓ = m1 × m2
ell = np.cross(m1, m2)
Intersección de dos rectas
m = ℓ1 × ℓ2, luego dividir por r
m = np.cross(ell_1, ell_2)
Rectas paralelas
r = 0: el punto ideal (c′ − c) [b −a 0]T
np.isclose(m[2], 0)
Línea en el infinito
ℓ∞ = [0 0 1]T
ell_inf = np.array([0, 0, 1])