# Best way to get the unit vector of a given vector in tikz 3d

Suppose I have a coordinate in tikz 3d which I interpret as a vector, for example

\coordinate (v) at (3,2,9);

What's the best way to get the unit vector pointing into the same direction?

My first idea was to use the let syntax, but this doesn't work in 3d.

For example

\path let \p1 = (v) in ($1/(x1^2 + x2^2 + x3^3)^(0.5)*(v)$) coordinate (vv);

Anyhow I am looking for a more easy to use solution than using let for this...

-
– student Oct 9 '12 at 7:04
I posted an update which works, but isn' too elegant. – Tom Bombadil Oct 18 '12 at 22:02

## Code

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows,calc}

\newcommand{\unitvec}[3][->]% [options], start point, vector
{   \xdef\mysum{0}
\foreach \c in  {#3}
{   \pgfmathsetmacro{\mysquare}{\mysum+pow(\c,2)}
\xdef\mysum{\mysquare}
}
\pgfmathsetmacro{\myveclen}{sqrt(\mysum)}
\draw[#1] (#2) -- ($1/\myveclen*(#3)$);
}

\begin{document}

\begin{tikzpicture}
\draw[-latex] (0,0,0) -- (3,6,2);
\unitvec[-latex,red,thick]{0,0,0}{3,6,2}

\draw[->] (0,0,0) -- (-2,4,3);
\unitvec[->,blue,thick]{0,0,0}{-2,4,3}

\draw[-stealth] (0,0,0) -- (-1,-4,-1);
\unitvec[-stealth,green,thick]{0,0,0}{-1,-4,-1}
\end{tikzpicture}

\end{document}


## Output

Edit 1: Here's a version with a new \Coordinate(<name>)(<vector>). To work it now needs \Unitvec, as \unitvec only works with direct numbers.

## Code

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows,calc}

\def\Coordinate(#1)(#2)% name, vector
{   \expandafter\xdef\csname#1\endcsname{#2}
\coordinate (#1) at (#2);
}

% for use with \Coordinates
\newcommand{\Unitvec}[3][->]% [options], start point, vector
{   \xdef\mysum{0}
\foreach \myconstant [count=\mycount] in    #3
{   \pgfmathsetmacro{\mysquare}{\mysum+pow(\myconstant,2)}
\xdef\mysum{\mysquare}
}
\pgfmathsetmacro{\myveclen}{sqrt(\mysum)}
\draw[#1] (#2) -- ($1/\myveclen*(#3)$);
}

%for use with direct numbers, e.g. \unitvec[-latex,red,thick]{0,0,0}{3,6,2}
\newcommand{\unitvec}[3][->]% [options], start point, vector
{   \xdef\mysum{0}
\foreach \c in  {#3}
{   \pgfmathsetmacro{\mysquare}{\mysum+pow(\c,2)}
\xdef\mysum{\mysquare}
}
\pgfmathsetmacro{\myveclen}{sqrt(\mysum)}
\draw[#1] (#2) -- ($1/\myveclen*(#3)$);
}

\begin{document}

\begin{tikzpicture}
\Coordinate(o)(0,0,0)
\Coordinate(a)(3,6,2)
\Coordinate(b)(-2,4,3)
\Coordinate(c)(-1,-4,-1)

\draw[-latex] (o) -- (a);
\Unitvec[-latex,red,thick]{\o}{\a}

\draw[->] (o) -- (b);
\Unitvec[->,blue,thick]{\o}{\b}

\draw[-stealth] (o) -- (c);
\Unitvec[-stealth,green,thick]{\o}{\c}

\end{tikzpicture}

\end{document}


## Output

Ecactly the same as before.

\Coordinate uses \xdef to store the vectors, so it will overwrite existing commands without hesitation. Furthermore, it uses commands, so you'll have to write \a instead of a. It also creates a regular \coordinate. If you just need the point on the canvas, you can use a (as in the \draw commands), if the true 3D position matters, you should use \a (like for \unitvec). Also, using things like - or 8 in a coordinate name, which works in TikZ does not work with edef, so only use letters.
The \unitvec macro should take something like (v) as argument. – student Oct 9 '12 at 11:19
Even though the coordinate is given with 3D entries if you place a temporary coordinate at the tip, it's saved as a 2D coordinate so you can get the angle via atan2 and use (angle:1) to draw. – percusse Oct 9 '12 at 12:43
@percusse: Nice idea, but due to perspective the (canvas) length of a unit vector is not neccessarily equal one. Probably ($1/<veclen>*(<vec>)$) will work. – Tom Bombadil Oct 9 '12 at 13:27
@student 3D library of TikZ accepts 3D inputs but converts them (or projects them) onto the 2D plane. Hence if you put a coordinate at the tip of the line that is drawn using 3D point input, it would still be a 2D point. So that would give the direction that unit vector points to. Example: \begin{tikzpicture} \draw[ultra thick] (0,0,0) -- (1,1,1) coordinate (a); \draw[yellow] (0,0) -- (a); \end{tikzpicture}. Then you can say for example, \draw[blue,thick] (0,0) -- ($(0,0)!1cm!(a)$); to go 1cm along that direction. But as Tom mentioned this might not necessarily be 1cm. – percusse Oct 9 '12 at 16:34