How to find a random unit vector orthogonal to a random unit vector in 3D? I have a unit circle with the center at the origin $O=(0, 0, 0)$ and a random unit vector $\bar U = (a, b, c)$, in the Cartesian coordinate system. How can I find a random unit vector orthogonal to $\bar U$?
My try was to find an intersection of my sphere and plane, which passes through the origin and has $\bar U$ as a normal vector, and then to define a point on this unit circle randomly.
So I have the system of equations:
\begin{cases}
x^2 + y^2 + z^2 = 1, \\
ax + by + cz = 0,
\end{cases}
and I wanted to set the solutions of this system parametrically but I got stuck. I know how to set the solutions in particular cases (e.g. when $a=c\neq0$) but I have no idea for the general one.
 A: If you are only interested in a numerical solution rather than a parametric one you can do the following:
If we call $\vec{n}=(a,b,c)$ than the corresponding unit vector is $\hat{n} = \frac{\vec{n}}{| \vec{n}|}$. Now generate a uniformly distributed random point $\vec{r}$ inside a sphere of radius 1.
Form the vector $\vec{u} = \vec{r} - \left( \vec{r}.\hat{n} \right) \hat{n}$. It is easy to see that this vector is perpendicular to $\vec{n}$. So if you normalise it you get a random unitvector $\hat{u}$ that is perpendicular to the normal of your circle.
There is of course a slight numerical problem if the random vector $\vec{r}$ is almost parallel to the normal. You could repeat generating the random vector $\vec{r}$ until the angle it makes with the normal is sufficiently large.
For a parametric solution, use a simple perpendicular vector $\vec{u} = (b, -a,0)$ and calculate the cross product $\vec{v} = \vec{n} \times \vec{u}$, normalise both and take a linear combination $\hat{w} = \cos \theta \hat{u} + \sin \theta \hat{v}$ with a uniformly distributed random $\theta \in [0,2 \pi]$.
A: Assume your reference vector be $\mathbb{x}=(1,0,0)$, then the normal unit vector would be
$\mathbf{n} =(0,\cos{t},\sin{t}) \quad |\; -\pi<t \le \pi$, where $t$ is a parameter.
So, for $t$ uniformly distributed in its range,
$$ \bbox[lightyellow] {  
 \mathbf n \; \text{is a "unit random vector", normal to }\; \mathbf x }$$ (if I understood what you mean by that).
Now, instead, your reference vector is $\mathbf {v}=(a,b,c)$, with $|\mathbf {v}|=1$, which can be written in terms of polar angles as
$\mathbf {v}=(cos{\theta}cos{\phi},cos{\theta}sin{\phi},sin{\theta})$, with:
$$
\left\{ \matrix{
   - \pi  < \varphi  = \arctan _4 (a,b) \le \pi  \hfill \cr 
   - \pi /2 \le \vartheta  = \arctan \left( {{c \over {\sqrt {a^{\,2}  + b^{\,2} } }}} \right) \le \pi /2 \hfill \cr}  \right.
$$
The Rotation Matrices giving a rotation with angles $\theta$ and $\phi$ (with sign taken according to the right hand rule)
respectively around the $y$ and the $z$ axis are:
$$
R_{\,z} (\varphi ) = \left( {\matrix{
   {\cos \varphi } & { - \sin \varphi } & 0  \cr 
   {\sin \varphi } & {\cos \varphi } & 0  \cr 
   0 & 0 & 1  \cr 
 } } \right)\quad R_{\,y} (\vartheta ) = \left( {\matrix{
   {\cos \vartheta } & 0 & {\sin \vartheta }  \cr 
   0 & 1 & 0  \cr 
   { - \sin \vartheta } & 0 & {\cos \vartheta }  \cr 
 } } \right)
$$
Therefore
$$
{\bf v} = R_{\,z} (\varphi )\;R_{\,y} ( - \vartheta )\;{\bf x}
$$
and the vector $\mathbf{n}'$ you are looking for is equivalently given by:
$$ \bbox[lightyellow] {  
{\bf n}'(t) = R_{\,z} (\varphi )\;R_{\,y} ( - \vartheta )\;{\bf n}(t)
}$$
A: Orthogonal is equivalent to dot product being zero. Doesn't $\dfrac{1}{\sqrt{a^2+b^2}}(-b,a,0)$ work?
A: At least two of $(b,-a,0)$, $(c,0,-a)$ and $(0,c,-b)$ will be nonzero,
so you can normalise one of them.
There is no continuous map $f$ from unit vectors to unit vectors
with $v\cdot f(v)=0$. This is the Hairy Ball Theorem. This means
there probably won't be a "nice" closed formula for a perpendicular unit vector.
A: I know this is an old-ish question, but here is a solution that is rather simple and always works.
Let's denote a generic unit vector $ \boldsymbol{u} = (a, b, c)$, such that $|i|\neq 1$, for $i = a, b, c$. It is easy to show that, no matter the choice of $ \boldsymbol{u} $, the following three vectors are always orthogonal to $\boldsymbol{u}$:
\begin{equation}
\boldsymbol{v}_a = \begin{pmatrix} 0 \\ c \\ -b \end{pmatrix}
\quad
\boldsymbol{v}_b = \begin{pmatrix} -c \\ 0 \\ a \end{pmatrix}
\quad
\boldsymbol{v}_c = \begin{pmatrix} b \\ -a \\ 0 \end{pmatrix}
\end{equation}
Furthermore, using the cross product, one can find a third set of vectors $\boldsymbol{w}_i$ that are orthogonal to $\boldsymbol{u}$ and $\boldsymbol{v}_i$:
\begin{equation}
\boldsymbol{w}_a = \begin{pmatrix} a^2 - 1 \\ ab \\ ac \end{pmatrix}
\quad
\boldsymbol{w}_b = \begin{pmatrix} ab \\ b^2-1 \\ bc \end{pmatrix}
\quad
\boldsymbol{w}_c = \begin{pmatrix} ac \\ bc \\ c^2-1 \end{pmatrix}
\end{equation}
Each triplet $(\boldsymbol{u}, \boldsymbol{v}_i, \boldsymbol{w}_i)$ is a basis of orthogonal vectors by construction. Finally, it can be shown that the expression
\begin{equation}
\boldsymbol{p}_i = \boldsymbol{v}_i \frac{\cos\theta}{\sqrt{1-i^2}} + \boldsymbol{w}_i \frac{\sin\theta}{\sqrt{1-i^2}}
\end{equation}
generates all unit vectors that are orthogonal to $\boldsymbol{u}$ when changing $\theta$ between $0$ and $2\pi$ - this is the parameteric solution that OP was looking for.
Note that the procedure above provides 3 distinct parameterizations. However, each of them has a singularity when $i^2 = 1$, in which case $\boldsymbol{v}_i$ and $\boldsymbol{w}_i$ both become null - this is why I initially added the hypothesis that $|a|\neq 1$,  $|b|\neq 1$ and  $|c|\neq 1$. However, only one of the three triplets can be singular at a time. The "bullet-proof strategy" is to select as $i$ the closest to zero between $a$, $b$ and $c$.
Here is a Python-NumPy code that calculates the vectors:
def get_vw(u):
    # Make a permutation of the indices so that the least value is always "a"
    i = np.argmin(np.abs(u))
    a, b, c = np.roll(u.copy(), -i)
    
    # Calculate v and w using the formulae for v_a and w_a 
    d = np.sqrt(1 - a**2)
    v = np.array([0, c/d, -b/d])
    w = np.array([-d, a*b/d, a*c/d])

    # Perform the inverse permutation when returning the result
    return np.roll(v, i), np.roll(w, i)
```

