Search code examples
algorithmmath

A good way to find a vector perpendicular to another vector?


What is a good way to generate an arbitrary vector that is perpendicular to a vector? Given that the generated vector should be valid (i.e. unless the given vector is (0.0, 0.0, 0.0) - the output for this case should be error)?

I know that there are infinite set of possible vectors (for example see here). What I want is something rigid and bug-free for any input vector.

What I attempted was setting, here p and n are said perpendicular vectors: p[0] = 0.5*(n[0] + n[1]; p[1] = 0.5*(n[0] - n[1]) and then solve for the dot product equation to find p[2] but this is flawed when n[2] is 0. At the moment I can only think of tediously creating all the case check - but there must be better and more elegant solution?


Solution

  • Pick an arbitrary vector that is not collinear with the given vector. For "something rigid", you can have a fixed rule. For instance, pick (1, 0, 0) unless the vector is (x, 0, 0) for some x; otherwise pick (0, 1, 0).1 Then take the cross product of the arbitrary vector with the input vector. That will yield a perpendicular vector. (This only works in 3D, of course, but that seems to be what you are working in.)

    Alternatively (and this works in any dimension), pick the unit vector along the coordinate axis that yields the smallest (in magnitude) dot product with the input vector. Call this unit vector e and the input vector x. Then e − (ex) x will be perpendicular to x. (It's easy to check that the dot product is zero: assume, without loss of generality, that x is a unit vector. Then (e − (ex) x) • x = (ex) − (ex)(xx) = (ex) − (ex)(1) = 0.)

    1A better rule would be to pick whichever of (1, 0, 0), (0, 1, 0), or (0, 0, 1) forms the smallest dot product (in magnitude) with the input vector. That will give you better numerical stability.