2012-06-21 4 views
5

Che cos'è una formula per ottenere un vettore tridimensionale B che giace sul piano perpendicolare ad un vettore A?Che cos'è una formula per ottenere un vettore perpendicolare ad un altro vettore?

Cioè, dato un vettore A, che cos'è una formula f (angolo, modulo) che dà un vettore perpendicolare ad A, con detto modulo e ruotato attraverso un angolo?

+0

due cose: primo, stiamo operando in due dimensioni? Tre? 'N'? In secondo luogo, il tuo titolo dice "perpendicolare" ma il corpo della domanda dice "ruotato attraverso un angolo" - questo angolo sarà mai diverso da novanta gradi? – AakashM

+1

In 3 dimensioni, ci sono infinitamente diversi vettori (uno spazio vettoriale bidimensionale) perpendicolare a un dato vettore. Non esiste un singolo vettore che una formula possa generare. –

risposta

8

Se i due vettori sono perpendicolari allora il loro prodotto scalare è pari a zero.

Quindi: v1(x1, y1, z1), v2(x2, y2, z2).

=> x1 * x2 + y1 * y2 + z1 * z2 = 0 

Si conosce (x1, y1, z1). Metti arbitraria x2 e y2 e si riceverà il corrispondente z2:

z1 * z2 = -x1 * x2 - y1 * y2 
=> z2 = (-x1 * x2 - y1 * y2)/z1 

essere a conoscenza se z1 è 0. Allora sei sull'aereo.

+0

C'è un solo vettore. – MaiaVictor

+4

Sì. Hai un vettore dato 'v1 (x1, y1, z1)'. –

+1

Come dici, questo fallisce se 'z1' è 0, tuttavia la domanda rimane perfettamente matematicamente valida in questo caso. Trova un vettore perpendicolare a [1,0,0], per esempio. 'z1' è 0, ma [0,1,0] è decisamente un vettore che è tuttavia perpendicolare a [1,0,0]. Vedi la mia risposta per un metodo alternativo. – sircolinton

6

Calcolare il cross productAxC con un altro vettore C che non è collineare con A.

Ci sono molte direzioni possibili nel piano perpendicolare a A. Se non si ha realmente a cuore, quale scegliere, basta creare un vettore arbitrario C non allineati con A:

if (A2 != 0 || A3 != 0) 
    C = (1, 0, 0); 
else 
    C = (0, 1, 0); 
B = A x C; 
+0

C'è solo un vettore, voglio una formula che dia un vettore perpendicolare ad esso in funzione del suo angolo e lunghezza. – MaiaVictor

+1

Dokkat, la ragione per cui si continuano a vedere DUE vettori nella descrizione è perché dato il primo vettore V1, ci sono molti vettori V2 che sono perpendicolari a V1. Nello spazio 2D ci sono almeno due di questi vettori con lunghezza 1. Nello spazio 3D ci sono infinitamente molti vettori perpendicolari a V1! Quello che vuoi trovare è un V2 arbitrario (perp a V1) o vuoi rilevare se (V1, V2) sono perpendicolari. –

+1

@Dokkat - guarda la mia modifica. – Henrik

1

Un modo sarebbe trovare una trasformazione di rotazione dall'asse z positivo (o qualsiasi altro asse) al vettore specificato. Quindi trasformare <modulus * cos(angle), modulus * sin(angle), 0> utilizzando questa trasformazione.

def getPerpendicular(v1,modulus,angle): 
    v2 = vector(0,0,1) 
    v1_len = v2.length() 

    axis = v1.cross_product(v2) 
    sinAngle = axis.length()/v1_len  # |u x v| = |u| * |v| * sin(angle) 
    cosAngle = v1.dot_product(v2)/v1_len # u . v = |u| * |v| * cos(angle) 
    axis = axis.normalize() 
    # atan2(sin(a), cos(a)) = a, -pi < a < pi 
    angle = math.atan2(sinAngle, cosAngle) 

    rotationMatrix = fromAxisAngle(axis, angle) 

    # perpendicular to v2 
    v3 = vector(modulus*cos(angle),modulus*sin(angle),0) 

    return rotationMatrix.multiply(v3); 

Per calcolare la matrice di rotazione, si veda l'articolo: WP: Rotation matrix from axis and angle

altro metodo sarebbe usare quaternion rotation. È un po 'più per avvolgere la testa, ma sono meno numeri da tenere traccia di.

4
function (a,b,c) 
{ 
    return (-b,a,0) 
} 

Ma questa risposta non è stabile quando numerica a, b sono vicini a 0.

Per evitare questo caso, l'uso:

function (a,b,c) 
{ 
    return c<a ? (b,-a,0) : (0,-c,b) 
} 

La risposta di cui sopra è numerico stabile, poiché in case c < a quindi max(a,b) = max(a,b,c), quindi vector(b,-a,0).length() > max(a,b) = max(a,b,c) e dal max(a,b,c) non dovrebbe essere vicino a zero, così è il vettore. Il caso c > a è simile.

+0

Solo per riferimento, ho fatto il looping di 10.000 vettori di unità casuali e mi sono assicurato che 'dot (vec, above_func (vec)) == 0' per tutti i vettori (ero troppo pigro per provare a convalidare la stabilità analiticamente, quindi era la mia prossima migliore opzione). Ha funzionato perfettamente. – Steve

+2

Se il vettore è ad esempio (a = 0, b = 0, c = -1), c

1

Credo che questo dovrebbe produrre un vettore arbitrario che è perpendicolare al vettore dato vec restando numericamente stabile indipendentemente dall'angolo di vec (supponendo che la grandezza di vec non è vicino a zero). Supponiamo che Vec3D sia un vettore tridimensionale di tipo numerico arbitrario.

Vec3D arbitrary_orthogonal(Vec3D vec) 
{ 
    bool b0 = (vec[0] < vec[1]) && (vec[0] < vec[2]); 
    bool b1 = (vec[1] <= vec[0]) && (vec[1] < vec[2]); 
    bool b2 = (vec[2] <= vec[0]) && (vec[2] <= vec[1]); 

    return cross(vec, Vec3D(int(b0), int(b1), int(b2))); 
} 
0

q4w56 è quasi lì per una soluzione robusta. Problemi: 1) Non tiene in considerazione il ridimensionamento.2) Non confronta la grandezza tra due variabili quando dovrebbe.

scale = |x| + |y| + |z| 

if scale == 0: 
    return (0,0,0) 

x = x/scale 
y = y/scale 
z = z/scale 

if |x| > |y|: 
    return (z, 0,-x) 
else: 
    return (0, z,-y) 

Il ridimensionamento è importante quando si tratta di numeri molto grandi o molto piccoli. Inoltre, in generale, si sta meglio a fare operazioni in virgola mobile su valori compresi tra 0 e 1.