MathGroup Archive 2002

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Generating Two Unit Orthogonal Vectors to a 3D Vector

  • To: mathgroup at smc.vnet.net
  • Subject: [mg36377] Re: [mg36352] Generating Two Unit Orthogonal Vectors to a 3D Vector
  • From: Daniel Lichtblau <danl at wolfram.com>
  • Date: Wed, 4 Sep 2002 02:56:32 -0400 (EDT)
  • References: <200209020809.EAA15855@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

David Park wrote:
> 
> There are many cases in graphics, and otherwise, where it is useful to
> obtain two orthogonal unit vectors to a given vector. I know a number of
> ways to do it, but they all seem to be slightly inelegant. I thought I would
> pose the problem to MathGroup. Who has the most elegant Mathematica
> routine...
> 
> OrthogonalUnitVectors::usage = "OrthogonalUnitVectors[v:{_,_,_}] will return
> two unit vectors orthogonal to each other and to v."
> 
> You can assume that v is nonzero.
> 
> David Park
> djmp at earthlink.net
> http://home.earthlink.net/~djmp/

Some possibilities:

perps1[v_] := If [v[[1]]==v[[2]]==0,
	{{1,0,0},{0,1,0}},
	{{v[[2]],-v[[1]],0}, Cross[v,{v[[2]],-v[[1]],0}]}
	]

perps2[v_] := With[{vecs=NullSpace[{v}]},
	{vecs[[1]], vecs[[2]] - (vecs[[2]].vecs[[1]])*vecs[[1]]}
	]

This appears to be 2-3 times faster than perps1 for vectors of machine
reals. I get another factor of 2 using Compile, which is appropriate for
e.g. graphics use.

perps2C = Compile[{{v,_Real,1}},
	Module[{vecs=NullSpace[{v}]},
	{vecs[[1]], vecs[[2]] - (vecs[[2]].vecs[[1]])*vecs[[1]]}
	]]

In[61]:= vecs = Table[Random[], {10000}, {3}];

In[62]:= Timing[p2 = Map[perps1C,vecs];]
Out[62]= {0.49 Second, Null}

This is on a 1.5 GHz processor.

Daniel Lichtblau
Wolfram Research


  • Prev by Date: 3D plot - resend
  • Next by Date: Fwd: Generating Two Unit Orthogonal Vectors to a 3D Vector
  • Previous by thread: Re: Generating Two Unit Orthogonal Vectors to a 3D Vector
  • Next by thread: Re: Generating Two Unit Orthogonal Vectors to a 3D Vector