Generate a Normal in 3D Without Branching?

77 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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.