3d-plane and rotating coordinate system in TiKZ

I am completely new in TikZ (starting today), but I am already amazed with all its capabilities.

I would like to draw the coordinate system of a ring (a particle accelerator), showing the three directions of the particle motion, as well as the velocity vector at different points of the orbit.

These coordinates have the peculiarity that y is always normal to the plane, z is always tangent to the orbit and x is always pointing radially.

Is it possible to show this behavior at different locations of the orbit?

This is what I managed today, but it is not elegant nor efficient, because I am tilting the plane to get perspective at the same time that I want to pose a coordinate system that is not defined in the same plane.

I would really appreciate your help.

\documentclass{article}
\usepackage{verbatim}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}
\begin{document}
\begin{tikzpicture}[scale=10,tdplot_main_coords]

\begin{scope}
\coordinate (coosys0) at (0,0,0);
\draw[blue,thick,->] (coosys0)-- (0.15,0,0) node[anchor=north east]{$x$};
\draw[blue,thick,->] (coosys0)-- (0,0.15,0) node[anchor=north west]{$z$};
\draw[blue,thick,->] (coosys0)-- (0,0,0.15) node[anchor=south]{$y$};
\end{scope}

\begin{scope} [yshift=-1.3,xshift=0.7,yslant=0.5,xslant=-1]
\draw[rounded corners=12ex,black, thick] (0,0,0)rectangle(20pt,2ex);
\end{scope}

\end{tikzpicture}
\end{document}
-

Code

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\newcommand{\xangle}{7}
\newcommand{\yangle}{137.5}
\newcommand{\zangle}{90}

\newcommand{\xlength}{1}
\newcommand{\ylength}{0.5}
\newcommand{\zlength}{1}

\pgfmathsetmacro{\xx}{\xlength*cos(\xangle)}
\pgfmathsetmacro{\xy}{\xlength*sin(\xangle)}
\pgfmathsetmacro{\yx}{\ylength*cos(\yangle)}
\pgfmathsetmacro{\yy}{\ylength*sin(\yangle)}
\pgfmathsetmacro{\zx}{\zlength*cos(\zangle)}
\pgfmathsetmacro{\zy}{\zlength*sin(\zangle)}

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
y={(\yx cm,\yy cm)},
z={(\zx cm,\zy cm)},
]
\fill[blue!50!gray!30, even odd rule] (0,0,0) circle (5) (0,0,0) circle (4);

\foreach \d in {11,57,95,177,225,270}
{   \draw[blue!80!black,->] (\d:4.5) -- (\d:5.5);
\node[blue!80!black] at (\d:5.8) {z};
\draw[green!80!black,->] (\d:4.5) -- ++(0,0,1);
\node[green!80!black] at ($(\d:4.5)+(0,0,1.2)$) {y};
\draw[red!80!black,->] (\d:4.5) -- ++ (\d+90:1);
\node[red!80!black] at ($(\d:4.5)+(\d+90:1.3)$) {x};
\fill[yellow!50!gray,draw=yellow!50!black] (\d:4.5) circle (0.05cm);
}

\end{tikzpicture}

\end{document}

Explanation

• the first 6 commands set the orientation and length of the cartesic unit vectors TikZ uses. You could also use e.g. 0/225/90 1/0.5/1 for cavalier perspective or -30/210/90 1/1/1 for isometric perspective. The values you set are then passed to the tikzpicture.

• then a circular ring is drawn by using the even odd rule: all parts that are filled an odd number of times are actually filled, all parts filled an even number of times are left blank; the first fill command specifys a circle of radius 5 around the origin, and then one of radius 4, so the 'interiour' (radius <=4) is filled twice (even) and therefore left blank.

• then a foreach command is used to cycle over several points. Here, the numbers are degrees, they are saved in \d to use in the draw commands.

• the first 2 commands in the loop (blue!80!black) use the polar nation of TikZ: <angle>:<radius>. As the ring extends from radius 4 to 5, the middle is 4.5. To draw an arrow (->) of length one, one draws from \d:4.5 to \d:5.5. You could also have used (\d:4.5) -- ++ (\d:1), where the ++ means interpret the next coordinate relative to the last one. The node is put in the same direction, only further out (5.8)

• for the perpendicular arrows, the ++ notion is used. The starting point of the arrows is again \d:4.5 and we need to go one unit up, so the z-direction: ++ (0,0,1). For the node, the calc library is used. Something like \node at (a,b) ++ (c,d) {} fails, but with the calc library one can do computations with coordinates: ($(a,b) + (c,d)$). Again, the node is simply put a little higher (1.2).

• for the tangent component, the arrow once more starts at \d:4.5. As the tangent points in a direction differing by 90 degrees from \d, it is used like this: ++ (\d+90:1). For the other direction, simply use ++ (\d-90:1). The node is again just put a little further along this path (1.3).

• finally, a small yellowish dot is placed. Note the explicit use of a unit (0.05cm). This ensures that a circle is drawn, otherwise (0.05) it would be an ellipses due to the coice of axes.

• I guess I mixed up the x and z directions, you can simply correct that by changing the labels of the nodes: {x} <-> {z}.

Supplement

As this was quite fun, I polished it a little:

\pgfdeclarelayer{background layer}
\pgfsetlayers{background layer,main}

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
y={(\yx cm,\yy cm)},
z={(\zx cm,\zy cm)},
]

\fill[blue!80!cyan, even odd rule] (0,0,0) circle (5) (0,0,0) circle (4);

\foreach \d in {5,20,...,350}
{   \draw[yellow!30!black,thin,densely dotted] (0,0) -- (\d:4.5);
\draw[yellow,->,thick] (\d:4.5) -- (\d:5.5);
%\node[yellow] at (\d:5.8) {x};
\draw[orange,->,thick] (\d:4.5) -- ++(0,0,1);
%\node[orange] at ($(\d:4.5)+(0,0,1.2)$) {y};
\draw[red,->,thick] (\d:4.5) -- ++ (\d+90:1);
%\node[red] at ($(\d:4.5)+(\d+90:1.3)$) {z};
\fill[green!50!cyan,draw=black] (\d:4.5) circle (0.05cm);
}

\begin{pgfonlayer}{background layer}
\fill[black] ($(current bounding box.south west)+(0,0)$) rectangle ($(current bounding box.north east)+(0,0)$);
\end{pgfonlayer}

\node[fill=white,opacity=0.4,text opacity=1,rounded corners=2mm,align=left] at (1,-1.5,0)
{   \textcolor{yellow}{$\rightarrow$ x-direction}\\
\textcolor{orange}{$\rightarrow$ y-direction}\\
\textcolor{red}{$\rightarrow$ z-direction}
};

\end{tikzpicture}

-
Thank you very much! It was just exactly what I needed. Also thank you for the explanation, it was really clear and useful to learn more about the structure of TikZ. I know I mentioned "a ring" because it was the easiest way to explain where the coordinate system has to lie on. However, my "ring" has two opposite straight sections, so it looks more like an oval or "rounded-corners rectangle". It does not seem straightforward, but I will try from this starting point. –  Nacu Sep 18 '12 at 6:51
Excellent!! But, switching if you switch just the {x} <-> {z} in your first example then you no longer have a right handed system. Perhaps for mathematicians it does not matter. –  Peter Grill Sep 19 '12 at 0:33