# Generate a Normal in 3D Without Branching?

I have a vector $v$ in arbitrary 3D space ending at point B. In order to generate the next point -- C, I uniformly pick an angle θ to create arbitrary translations in the {$X_r$} and {$Y_r$} axes relative to the original vector.

{$X_r$} is defined as a travel from B in the continuation of the $v$ direction
{$Y_r$} is defined as travel along a normal to the $v$ direction
||$v$|| is the length of all my vectors I'm picking

Currently my equation for C is:
C= B - $v$*cos(θ)+$norm$*cos(θ)*||$v$||/||$norm$||

Which produces a vector of length ||$v$||, at angle θ, as desired.

The irritation is that I currently have to do branching to calculate the normal (to handle the case where
$v_x$ = 0, etc.)

My branching is as follows:

  if (v.X == 0 && v.Y != 0)
norm.Init(0,v.Z,-v.Y);
else if (v.Y==0 && v.X != 0)
norm.Init(v.Z,0,-v.X);
else if (v.Z==0 && v.X != 0)
norm.Init(v.Y,-v.X,0);
else if (v.X != 0 && v.Y!=0 && v.Z!=0)
norm.Init(v.Y,-v.X,0);
else
{
printf("Err! compacted coordinates!\n");
exit(1);
}


Assuming I drop the error case (which is never hit in my current code) is there a way to handle the zero-axis special case and generate the normals using a single set of expressions for X, Y, and Z.

The problem is ubiquitous for generating normals from an arbitrary line in 3D, but I wanted to give the background and my current solution to help you understand why I wanted to do this.

-
What is the vector supposed to be normal to? An arbitrary line and a vector in its normal space? – Loki Clock Jun 6 '13 at 21:19
Given a vector in $\mathbb{R}^3$, there is an entire plane normal to it, or equivalently, a circle's worth of normal directions. How do you pick your normal vector $Y_r$? Is it in a random direction normal to $X_r$? – Sammy Black Jun 6 '13 at 21:28
@Sammy I don't care what the normal is because I'm going to randomly rotate around the line afterwards... any normal will do. I just want to get rid of the branching though ... the current code does work to generate a necessary normal, but is branched. – Jason R. Mick Jun 6 '13 at 23:27
@LokiClock The normal is a sub-vector used to generate the second vector (via translation in a plane with vector $v$). It's normal to the original vector $v$. The "arbitrary line" refers to the vector $v$ plus the point it passes through (B). Any normal will do as it will be rotated by a random amount around the line after (conic point picking). – Jason R. Mick Jun 6 '13 at 23:30
The point the vector ends at $B$ is the vector. It seems like what you're describing is an arrow from $v$ to $B$. You must travel from the origin to the start of an arrow to represent it as a single vector, its endpoint. Otherwise, the arrow is an ordered pair of vectors, the start and end points. So, it seems like what you're trying to do is create a random plane with axes $B$ and random vector $C$ orthogonal to it, where the origin of $B$ and $C$ is the endpoint of an arrow $v$. And you want the length of $C$ to match that of the arrow $v$. – Loki Clock Jun 7 '13 at 0:51

If you translate all your coordinates to the starting point of a pair of line segments sharing a starting point, you will have their starting point as your origin, and you can use their endpoints as vectors defining coordinate axes. The cross product of two vectors gives you one orthogonal to both of them. If you have two arbitrary vectors $x, y$, you can add multiples of them together to span a plane. Make the multiples used its coordinates in the plane, so that $3x+2y$ is assigned the coordinates $[3,2]$. I hope that helps.