Come calcolo il vettore normale di un segmento di linea?


177

Supponiamo che io abbia un segmento di linea che va da (x1, y1) a (x2, y2). Come calcolo il vettore normale perpendicolare alla linea?

Posso trovare molte cose su come farlo per gli aerei in 3D, ma nessuna roba 2D.

Per favore, andate piano con la matematica (sono benvenuti collegamenti a esempi funzionanti, diagrammi o algoritmi), sono un programmatore più di un matematico;)


2
E se vuoi sapere quali sono i "calcoli" dietro questo, puoi cercare la mia risposta su stackoverflow.com/a/7470098/189767 . È praticamente lo stesso, ma più elaborato.
Andreas,

2
Questa domanda riguarda la matematica, non la programmazione.
Charlie,

1
Sto votando per chiudere questa domanda come fuori tema perché si tratta di matematica, non di programmazione.
Fanne il

Risposte:


237

se definiamo dx = x2-x1 e dy = y2-y1, allora le normali sono (-dy, dx) e (dy, -dx).

Nota che non è richiesta alcuna divisione, quindi non rischi di dividere per zero.


14
È abbastanza sottile e mi ci è voluto un po 'per capire normal.x = -dy e normal.y = dx. Li ho fatti al contrario perché sembrava un refuso che assegnava la parte x al valore y ...
Piku,

@OrenTrutner Ancora non lo capisco; (x', y') = (-y, x)e (x', y') = (y, -x)sembra essere giusto, ma perché uno dovrebbe usare dxe dyqui. Inoltre, in base alle pendenze, m1 * m2 = -1per le linee ad angolo retto, quindi dy' = dx' * (-dx/dy)e dx' = dy' * (-dy/dx), come mai nella tua equazione normal.x = x' = -dy?
legends2k

1
Potresti per favore riassumere di più su come il delta gioca un ruolo qui? Sono sicuro che mi manca qualcosa qui.
legends2k

7
@ legends2k: il delta è il vettore tangente. La normale è la direzione perpendicolare alla tangente. Capovolgere i valori x / y e annullarne uno diventa ovvio se si guarda una matrice 2D per una rotazione di 90 gradi: en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
geon

@geon: Aah! Capito, stavo confondendo il delta con la pendenza mentre nella geometria affine la differenza tra due punti è un vettore, il groviglio qui :)
legends2k

95

Un altro modo di pensarci è calcolare il vettore unitario per una data direzione e quindi applicare una rotazione in senso antiorario di 90 gradi per ottenere il vettore normale.

La rappresentazione matriciale della trasformazione 2D generale si presenta così:

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

dove (x, y) sono i componenti del vettore originale e (x ', y') sono i componenti trasformati.

Se t = 90 gradi, allora cos (90) = 0 e sin (90) = 1. Sostituendolo e moltiplicandolo si ottiene:

x' = -y
y' = +x

Stesso risultato di prima, ma con qualche spiegazione in più su da dove viene.


2
Grazie mille, mi stava spezzando la testa su come veniva derivata.
legends2k

1
Anche se conoscevo la formula di rotazione in precedenza, la cosa che mi è scattata dentro la testa, con questa risposta, era che l'angolo è una costante (+/- 90), che la semplifica in una semplice negazione e inversione di xe y.
legends2k

@duffymo il risultato ha una lunghezza di uno?
Martin Meeser,

Se il vettore viene normalizzato prima della trasformazione, rimarrà tale anche dopo. Devi normalizzare prima o dopo aver effettuato la trasformazione rotazionale.
duffymo,

11

Questa domanda è stata pubblicata molto tempo fa, ma ho trovato un modo alternativo per rispondere. Quindi ho deciso di condividerlo qui.
Innanzitutto, bisogna sapere che: se due vettori sono perpendicolari, il loro prodotto punto è uguale a zero.
Il vettore normale (x',y')è perpendicolare alla linea che collega (x1,y1)e (x2,y2). Questa linea ha direzione (x2-x1,y2-y1), o (dx,dy).
Così,

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

Sono molte le coppie (x ', y') che soddisfano l'equazione di cui sopra. Ma la coppia migliore che soddisfa SEMPRE è o (dy,-dx)o(-dy,dx)


7
m1 = (y2 - y1) / (x2 - x1)

se perpendicolare a due linee:

m1*m2 = -1

poi

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 è qualcosa se vuoi passarlo da un punto che hai definito

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.