Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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...

share|improve this question
    
Related: tex.stackexchange.com/q/54804/4011 –  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
add comment

1 Answer

How about this:

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

enter image description here


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.

Please note:

\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.

share|improve this answer
    
The \unitvec macro should take something like (v) as argument. –  student Oct 9 '12 at 11:19
    
Then you have a problem, as Tikz internally uses only 2D coordinates. In this question, Andrew Stacey discusses a possible way around this using some experimental code. –  Tom Bombadil Oct 9 '12 at 11:22
1  
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
1  
@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
3  
@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
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.