How to find perpendicular vector to another vector?

503.5k Views Asked by At

How do I find a vector perpendicular to a vector like this: $$3\mathbf{i}+4\mathbf{j}-2\mathbf{k}?$$ Could anyone explain this to me, please?

I have a solution to this when I have $3\mathbf{i}+4\mathbf{j}$, but could not solve if I have $3$ components...

When I googled, I saw the direct solution but did not find a process or method to follow. Kindly let me know the way to do it. Thanks.

7

There are 7 best solutions below

10
On BEST ANSWER

There exists an infinite number of vectors in 3 dimension that are perpendicular to a fixed one. They should only satisfy the following formula: $$(3\mathbf{i}+4\mathbf{j}-2\mathbf{k}) \cdot v=0$$

For finding all of them, just choose 2 perpendicular vectors, like $v_1=(4\mathbf{i}-3\mathbf{j})$ and $v_2=(2\mathbf{i}+3\mathbf{k})$ and any linear combination of them is also perpendicular to the original vector: $$v=((4a+2b)\mathbf{i}-3a\mathbf{j}+3b\mathbf{k}) \hspace{10 mm} a,b \in \mathbb{R}$$

5
On

You just need to find any vector $v \neq 0$ such that $v \cdot (3\mathbf{i}+4\mathbf{j}-2\mathbf{k}) = 0$.

There is no unique solution, any one will do. To save typing, let $p = 3\mathbf{i}+4\mathbf{j}-2\mathbf{k}$.

Pick a vector $x$, that is not on the line through the origin and $p$. Take $x = 3\mathbf{i}$, for example.

Construct a vector perpendicular to $p$ in the following way: Find a value of $t$ so that $(x+t p) \cdot p = 0$. Then the vector $v=x+t p$ will be perpendicular to $p$.

In my example, $(x+t p) = (3 + 3 t)\mathbf{i}+4 t \mathbf{j}-2t\mathbf{k}$, and $(x+t p) \cdot p = 9 + 29 t$. By choosing $t=-\frac{9}{29}$, the vector $v=x+t p$ is now perpendicular to $p$.

3
On

A related problem is to construct an algorithm that finds a non-zero perpendicular vector without branching. If the input vector is N = (a,b,c), then you could always choose T = (c,c,-a-b) but T will be zero if N=(-1,1,0). You could always check to see if T is zero, and then choose T = (-b-c,a,a) if it is, but this requires a test and branch. I can't see how to do this without the test and branch.

6
On

A suggested solution without a branch could be: Construct an array of 2 vector elements in the following way:

arr[0] = (c,c,-a-b) arr[1] = (-b-c, a,a)
int selectIndex = ((c != 0) && (-a != b)) // this is not a branch
perpendicularVector = arr[selectIndex]

If (c, c, -a-b) is zero, selectIndex is 1 and the other vector will be selected.

1
On

For any nonzero vector $(a,b,c)$, the three of $(0,c,-b),(-c,0,a)$ and $(-b,a,0)$ are orthogonal to it.

To avoid the "parallel case", you can choose the one with the largest squared modulus, among $c^2+b^2, c^2+a^2$ and $b^2+a^2$, or the one with the two largest absolute components or simply one with the largest absolute component. Choosing the largest will also optimize numerical stability.


In the given case, $(-4,3,0)$.


Update:

The largest squared modulus also corresponds to the smallest (absolute) component.

6
On

This branch-free algorithm is $\operatorname{sqrt}$-free and trig-free:

$$ \begin{aligned} \begin{bmatrix} \operatorname{copysign}\left(z,x\right) \\ \operatorname{copysign}\left(z,y\right) \\ -\operatorname{copysign}\left(|x|+|y|,z\right) \\ \end{bmatrix} \end{aligned} $$

An equivalent form

This alternative avoids the 2 $\operatorname{abs}$ at the cost of an additional $\operatorname{copysign}$:

$$ \begin{aligned} \begin{bmatrix} \operatorname{copysign}\left(z,x\right) \\ \operatorname{copysign}\left(z,y\right) \\ -\operatorname{copysign}\left(x,z\right) -\operatorname{copysign}\left(y,z\right) \\ \end{bmatrix} \end{aligned} $$

Properties

Let $L_\text{i}$ be the length of the input and $L_\text{o}$ be the length of the output:

$$ \begin{aligned} L_\text{i} \le L_\text{o} \le \sqrt{2} L_\text{i} \end{aligned} $$

which holds for both forms above.

A note about the function $\operatorname{copysign}$

Many platforms offer a function $\operatorname{copysign}\left(a,b\right)$ whose return value has the magnitude of $a$ and the sign of $b$. Despite the following mathematical definition, its implementation can be branch-free using bitwise operations:

$$ \begin{aligned} \operatorname{copysign}\left(a,b\right) &= \begin{cases} |a|&\text{for }b\ge0 \\ -|a|&\text{for }b<0 \\ \end{cases} \end{aligned} $$

If $\operatorname{copysign}$ is not available

The $\operatorname{copysign}(a,b)$ function is preferred because it is non-vanishing. However some platforms only offer a $\operatorname{sign}(b)$ function which vanishes for $b=0$:

$$ \begin{align} \operatorname{sign}(b) &= \begin{cases} 1 &\text{for } b > 0 \\ 0 &\text{for } b = 0 \\ -1 &\text{for } b < 0 \\ \end{cases} \\ \end{align} $$

Fortunately an alternative exists. The desired non-vanishing functionality can be obtained by "nudging" the output and nesting the result in another call:

$$ \begin{align} \operatorname{sign}\left[\operatorname{sign}(b)+0.5\right] &= \begin{cases} 1 &\text{for } b \ge 0 \\ -1 &\text{for } b < 0 \\ \end{cases} \\ \end{align} $$

This leads to the following form of the perpendicular to vector $(x,y,z)$ for platforms with no $\operatorname{copysign}(a,b)$ function:

$$ \begin{align} \begin{bmatrix} s_{xz}z \\ s_{yz}z \\ -s_{xz}x-s_{yz}y \end{bmatrix} \\ \end{align} $$

where:

$$ \begin{align} s_{xz} &= \operatorname{sign}\left\{ \left[ \operatorname{sign}(x)+0.5 \right] \left[ \operatorname{sign}(z)+0.5 \right] \right\} \\ s_{yz} &= \operatorname{sign}\left\{ \left[ \operatorname{sign}(y)+0.5 \right] \left[ \operatorname{sign}(z)+0.5 \right] \right\} \\ \end{align} $$

Update

In response to Adam's comment asking for the origin of this algorithm: I came up with it 11 years ago following a coding competition. It's the cross product of the input $(x,y,z)$ with some non-zero vector $u$ chosen such that $u$ is never parallel to the input. For me, the challenge was choosing the components $(u_x,u_y,u_z)$. After many attempts I finally converged on the following. First, pick zero for one of the components. I picked $u_z$ but it doesn't matter which one. If the corresponding input $z$ is non-zero, $u$ will never be parallel to the input. We have reduced the problem to 2D: The $z=0$ case for which we need a non-zero $(u_x,u_y)$ never parallel to $(x,y)$. I wanted something that resulted in a branch-free and robust solution. I ended-up picking one of the 4 vertices of an origin-centered, axis-aligned square such that the vertex is neither in the same quadrant nor the opposite quadrant as $(x,y)$. So something like $u_x=-\operatorname{copysign}(1,y)$ and $u_y=\operatorname{copysign}(1,x)$. Another way of looking at it is that $(u_x,u_y)$ is the result of rotating $(\operatorname{copysign}(1,x),\operatorname{copysign}(1,y))$ about the $z$ axis by 90 degrees to ensure that it's never parallel to $(x,y)$. Taking the cross product gives the result shown above (to within a sign; you need to multiply by $\operatorname{copysign}(1,z)$). As I mention above under Properties, this solution has the added bonus that the magnitude of the result is within a factor of $\sqrt{2}$ of the magnitude of the input.

0
On

Another way to find a vector $\vec{v}$ for a given $\vec{u}$ such that $$ \vec{u}\cdot\vec{v}=0 $$ is to use an antisymmetric matrix $A$ ($A^\top=-A$) defined as follow $$ A_{ij}u_iu_j=0\qquad(\text{sum over }ij). $$ In two dimension $A$ is $$ A=\begin{pmatrix} 0&1\\ -1&0\\ \end{pmatrix}. $$ In three dimension $A$ is $$ A=\begin{pmatrix} 0&1&1\\ -1&0&1\\ -1&-1&0\\ \end{pmatrix}. $$ In 2D only one such vector $\vec{v}=A\vec{u}$ exist, while in 3D you can apply the same matrix to the sum $\vec{u}+\vec{v}$ finding a vector perpendicular to the plane given by the other two vectors.

2D

The matrix $A$ can be calculated as follow $$ A_{ij}u_iu_j=A_{11}u_1^2+(A_{12}+A_{21})u_1u_2+A_{22}u_2^2. $$ One way is to set $A_{11}=0=A_{22}$ and $A_{21}=-A_{12}$.

3D

Again $$ A_{ij}u_iu_j=A_{11}u_1^2+(A_{12}+A_{21})u_1u_2+A_{22}u_2^2+(A_{13}+A_{31})u_1u_3+(A_{23}+A_{32})u_2u_3+A_{33}u_3^2, $$ and setting $A_{11}=A_{22}=A_{33}=0$ and $A_{21}=-A_{12}$, $A_{31}=-A_{13}$ and $A_{23}=-A_{32}$.