¿Cómo calculo el vector normal de un segmento de línea?

177

Supongamos que tengo un segmento de línea que va de (x1, y1) a (x2, y2). ¿Cómo calculo el vector normal perpendicular a la línea?

Puedo encontrar muchas cosas sobre hacer esto para planos en 3D, pero no hay cosas en 2D.

Por favor, tenga cuidado con las matemáticas (los enlaces a ejemplos trabajados, diagramas o algoritmos son bienvenidos), soy un programador más que un matemático;)

Piku
fuente
2
Y si quieres saber sobre las "matemáticas" detrás de esto, puedes buscar mi respuesta en stackoverflow.com/a/7470098/189767 . Es básicamente lo mismo, pero más elaborado.
Andreas
2
Esta pregunta es sobre matemáticas, no sobre programación.
Charlie
1
Estoy votando para cerrar esta pregunta como fuera de tema porque se trata de matemáticas, no de programación.
Pang

Respuestas:

237

si definimos dx = x2-x1 y dy = y2-y1, entonces las normales son (-dy, dx) y (dy, -dx).

Tenga en cuenta que no se requiere división, por lo que no corre el riesgo de dividir por cero.

Oren Trutner
fuente
14
Es bastante sutil y me llevó un tiempo darme cuenta de normal.x = -dy y normal.y = dx. Los tenía al revés porque parecía un error asignar la parte x para el valor y ...
Piku
@OrenTrutner Todavía no entiendo esto; (x', y') = (-y, x)y (x', y') = (y, -x)parece estar en lo cierto, pero ¿por qué uno usaría dxy dyaquí? Además, en función de las pendientes, m1 * m2 = -1para las líneas de ángulo recto, por lo tanto , dy' = dx' * (-dx/dy)y dx' = dy' * (-dy/dx)¿cómo se obtiene su ecuación normal.x = x' = -dy?
legends2k
1
¿Podría por favor informarme más sobre cómo el delta juega un papel aquí? Estoy seguro de que me falta algo aquí.
legends2k
77
@ legends2k: El delta es el vector tangente. Lo normal es la dirección perpendicular a la tangente. Voltear los valores x / y y negar uno se vuelve obvio si observa una matriz 2D para una rotación de 90 grados: en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
geon
@geon: ¡Aah! Entendido, estaba confundiendo el delta con la pendiente, mientras que en geometría afinada la diferencia entre dos puntos es un vector, el tanget aquí :)
legends2k
95

Otra forma de pensarlo es calcular el vector unitario para una dirección dada y luego aplicar una rotación de 90 grados en sentido antihorario para obtener el vector normal.

La representación matricial de la transformación 2D general se ve así:

x' = x cos(t) - y sin(t)
y' = x sin(t) + y cos(t)

donde (x, y) son los componentes del vector original y (x ', y') son los componentes transformados.

Si t = 90 grados, entonces cos (90) = 0 y sin (90) = 1. Sustituirlo y multiplicarlo da:

x' = -y
y' = +x

El mismo resultado que se dio anteriormente, pero con un poco más de explicación de dónde proviene.

duffymo
fuente
2
Muchas gracias, me estaba rompiendo la cabeza sobre cómo se estaba derivando.
legends2k
1
Aunque conocía la fórmula de rotación anteriormente, lo que hizo clic dentro de mi cabeza, por esta respuesta, fue que el ángulo es una constante (+/- 90), lo que lo simplifica a una simple negación e inversión de x e y.
legends2k
@duffymo ¿el resultado tiene una longitud de uno?
Martin Meeser
Si el vector se normaliza antes de la transformación, seguirá siéndolo después. Debe normalizar antes o después de realizar la transformación rotacional.
duffymo
11

Esta pregunta se publicó hace mucho tiempo, pero encontré una forma alternativa de responderla. Entonces decidí compartirlo aquí.
En primer lugar, uno debe saber que: si dos vectores son perpendiculares, su producto punto es igual a cero.
El vector normal (x',y')es perpendicular a la línea que conecta (x1,y1)y (x2,y2). Esta línea tiene dirección (x2-x1,y2-y1), o (dx,dy).
Entonces,

(x',y').(dx,dy) = 0
x'.dx + y'.dy = 0

Hay muchos pares (x ', y') que satisfacen la ecuación anterior. Pero el mejor par que SIEMPRE satisface es (dy,-dx)o(-dy,dx)

Tu Bui
fuente
7
m1 = (y2 - y1) / (x2 - x1)

si perpendicular dos líneas:

m1*m2 = -1

luego

m2 = -1 / m1 //if (m1 == 0, then your line should have an equation like x = b)

y = m2*x + b //b is offset of new perpendicular line.. 

b es algo si quieres pasarlo desde un punto que definiste

ufukgun
fuente