2012-06-21 16 views
5

¿Qué es una fórmula para obtener un vector tridimensional B que se encuentra en el plano perpendicular a un vector A?¿Qué es una fórmula para obtener un vector perpendicular a otro vector?

Es decir, dado un vector A, ¿qué es una fórmula f (ángulo, módulo) que da un vector que es perpendicular a A, con dicho módulo y girado en un ángulo?

+0

Dos cosas: primero, ¿estamos operando en dos dimensiones? ¿Tres? 'n'? En segundo lugar, su título dice "perpendicular", pero el cuerpo de la pregunta dice "girado en un ángulo": ¿será este ángulo alguna vez distinto de noventa grados? – AakashM

+1

En 3 dimensiones, hay infinitamente muchos vectores diferentes (un espacio vectorial bidimensional) perpendiculares a un vector dado. No hay un único vector que generaría una fórmula. –

Respuesta

8

si los dos vectores son perpendiculares a continuación, su producto escalar es cero.

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

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

Usted sabe (x1, y1, z1). Poner arbitraria x2 y y2 y recibirá la correspondiente z2:

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

Tenga en cuenta si es z10. Entonces estás en el avión.

+0

Solo hay un vector. – MaiaVictor

+4

Sí. Tienes un vector dado 'v1 (x1, y1, z1)'. –

+1

Como mencionas, esto falla si 'z1' es 0, sin embargo, la pregunta permanece perfectamente matemáticamente válida en tal caso. Encuentre un vector perpendicular a [1,0,0], por ejemplo. 'z1' es 0, pero [0,1,0] es definitivamente un vector perpendicular a [1,0,0]. Ver mi respuesta para un método alternativo. – sircolinton

6

Calcula cross productAxC con otro vector C que no es colineal con A.

Hay muchas direcciones posibles en el plano perpendicular a A. Si no te importa, cuál elegir, basta con crear un vector arbitrario C no colineal con A:

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

Solo hay un vector, quiero una fórmula que proporcione un vector que sea perpendicular a ella en función de su ángulo y longitud. – MaiaVictor

+1

Dokkat, la razón por la que sigues viendo DOS vectores en la descripción es porque dado el primer vector V1, hay muchos vectores V2 que son perpendiculares a V1. En el espacio 2D hay al menos dos vectores con una longitud 1. ¡En el espacio 3D hay infinitos vectores perpendiculares a V1! Lo que quiere encontrar es un V2 arbitrario (perp a V1) o quiere detectar si (V1, V2) son perpendiculares. –

+1

@Dokkat - ver mi edición. – Henrik

1

Una forma sería encontrar una transformación de rotación desde el eje z positivo (o cualquier otro eje) a su vector dado. Luego transforma <modulus * cos(angle), modulus * sin(angle), 0> usando esta transformación.

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); 

Para calcular la matriz de rotación, ver este artículo: WP: Rotation matrix from axis and angle

Otro método sería utilizar quaternion rotation. Es un poco más para entender, pero son menos los números que hay que seguir.

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

Pero esta respuesta no es estable cuando numérica a, b son cercano a 0.

Para evitar ese caso, utilice:

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

La respuesta anterior es numérica estable, ya que en caso c < a luego max(a,b) = max(a,b,c), luego vector(b,-a,0).length() > max(a,b) = max(a,b,c), y dado que max(a,b,c) no debería estar cerca de cero, también lo es el vector. El caso c > a es similar.

+0

Solo como referencia, hice un bucle de 10.000 vectores de unidades aleatorias y me aseguré de que 'dot (vec, above_func (vec)) == 0' para todos los vectores (era demasiado vago para tratar de validar la estabilidad analíticamente, por lo que era mi siguiente mejor opción). Funcionó perfectamente. – Steve

+2

Si el vector es, por ejemplo, (a = 0, b = 0, c = -1), c

+1

@GiovanniFunchal De hecho, la afirmación "max (a, b, c) no debería estar cerca de cero" puede ser falso incluso para los vectores "buenos", como el que mencionas. La explicación debe corregirse usando la norma L-infinito en lugar de max, y c Fabio

1

creo que esto debería producir un vector arbitrario que es perpendicular al vector dado vec sin dejar de ser numéricamente estable independientemente del ángulo de vec (suponiendo que la magnitud de vec no está cerca de cero). Supongamos que Vec3D es un vector tridimensional de tipo numérico 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's está casi listo para una solución robusta. Problemas: 1) No tiene en cuenta la escala.2) No compara la magnitud entre dos variables cuando debería.

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) 

La escala es importante cuando se trata de números muy grandes o muy pequeños. Además, en general, es mejor que realice operaciones de coma flotante en valores entre 0 y 1.