5

I'm preparing a presentation about microcomputed tomography and it's been a while since I used TikZ.

I cannot figure out how I can rotate a grey xray cone in the drawing below around the center of the drawing.

\documentclass[export]{standalone}
\usepackage{animate}
\usepackage{tikz}

\begin{document}

\begin{animateinline}[autoplay,loop]{10}
    \multiframe{36}{n=1+1}{
        \begin{tikzpicture}[scale=2]
            % Coordinate network
%           \draw[help lines,step=0.5cm,ultra thin] (-1.45,-1.45) grid (1.45,1.45);
            \draw[->] (-1.75,0) -- (1.75,0);
            \draw[->] (0,-1.75) -- (0,1.75);
            % Rotation arc
            \draw[->, ultra thick,rotate around={\n*10:(0,0)}] (1,0) arc [start angle=0, end angle=180, radius=1];
            \draw[->, ultra thick,rotate around={\n*10:(0,0)}] (-1,0) arc [start angle=-180, end angle=0, radius=1];
            % Stuff
            \fill[red,rotate around={\n*10:(0,0)}] (-0.25,1) rectangle node (source) [black,fill=white, semitransparent, text opacity=1] {X-ray} +(0.5,0.5);
            \fill[green] (-0.25,-0.25) rectangle node [black,fill=white, semitransparent, text opacity=1] {Sample} +(0.5,0.5) ;
            \fill[blue,fill,rotate around={\n*10:(0,0)}] (-0.5,-1.25) rectangle node (detector) [black,fill=white, semitransparent, text opacity=1] {Detector} +(1,0.25);
            \draw[rotate around={\n*10:(0,0)}] (-0.5,-1) node (edgeleft) {L};
            \draw[rotate around={\n*10:(0,0)}] (0.5,-1) node (edgeright) {R};           
            % Cone, based on section 4.1.5 in pgfmanual.pdf
            \pgfdeclarelayer{background}
            \pgfsetlayers{background,main}
            \coordinate (A) at (-0,1);
            \coordinate (B) at (-0.25,-1);
            \coordinate (C) at (0.25,-1);       
            \begin{pgfonlayer}{background}
                \fill[blue,semitransparent] (A) -- (B) -- (C) -- cycle;
                \fill[gray,semitransparent] (source) -- (B) -- (C) -- cycle;
                \fill[green, ultra thick] (source) -- (edgeleft) -- (edgeright) -- cycle;
                \draw [red] (source) -- (detector);
            \end{pgfonlayer}
        \end{tikzpicture}
    }
\end{animateinline}

\end{document}

It feels to me that I should just be able to draw a polygon from source to the two edges of the detector (as I tried in the code, commented out), but this does not work.

Drawing a

  • (red) rotating pencil beam (red)
  • (blue) 'static' cone based on the three coordinates in the code (straight from the manual :) )
  • and a (grey) moving cone from the source to the starting position of the detector

works all fine, but I need a moving cone pointing from source to the edges of the detector. The only thing that I manage is a (green) line to the edgeleft. This green line is extremely thin and only visible in the compiled PDF...

Can someone provide me some insight on how I can rotate around the gray cone?

enter image description here

PS1: The animated gifs were exported with ImageMagick and this command

PS2: The styling of the animation is far from final, but first I need rotation :)

nidhin
  • 7,932
Habi
  • 7,694

2 Answers2

5

Define the layers first and then put the rest into a scope with the option [rotate around={\n*10:(0,0)}].

\documentclass[export]{standalone}
\usepackage{animate}
\usepackage{tikz}
\begin{document}
\begin{animateinline}[autoplay,loop]{10}
    \multiframe{36}{n=1+1}{
        \begin{tikzpicture}[scale=2]
            \pgfdeclarelayer{background}
            \pgfsetlayers{background,main}
            \draw[->] (-1.75,0) -- (1.75,0);
            \draw[->] (0,-1.75) -- (0,1.75);
            \fill[green] (-0.25,-0.25) rectangle node [black,fill=white, semitransparent, text opacity=1] {Sample} +(0.5,0.5) ;
            \begin{scope}[rotate around={\n*10:(0,0)}]
               \draw[->, ultra thick] (1,0) arc [start angle=0, end angle=180, radius=1];
               \draw[->, ultra thick] (-1,0) arc [start angle=-180, end angle=0, radius=1];
               \fill[red] (-0.25,1) rectangle node (source) [black,fill=white, semitransparent, text opacity=1] {X-ray} +(0.5,0.5);
               \fill[blue,fill] (-0.5,-1.25) rectangle node (detector) [black,fill=white, semitransparent, text opacity=1] {Detector} +(1,0.25);
               \draw (-0.5,-1) node (edgeleft) {L};
               \draw (0.5,-1) node (edgeright) {R};           
               \coordinate (A) at (-0,1);
               \coordinate (B) at (-0.25,-1);
               \coordinate (C) at (0.25,-1);       
               \begin{pgfonlayer}{background}
                   %\fill[blue,semitransparent] (A) -- (B) -- (C) -- cycle;
                   \fill[gray,semitransparent] (source) -- (B) -- (C) -- cycle;
                   \fill[green, ultra thick] (source) -- (edgeleft) -- (edgeright) -- cycle;
                   \draw [red] (source) -- (detector);
               \end{pgfonlayer}
            \end{scope}
        \end{tikzpicture}
    }
\end{animateinline}
\end{document}

enter image description here

gernot
  • 49,614
  • Sure, how could I forget the scope. I'll use that in my final version. Funny that with your conversion the faint green line is still visible, while in mine it isn't. – Habi Nov 08 '19 at 19:37
4

Triangle (A)--(B)--(C)--cycle and (source)--(B)--(C)--cycle does not give the desired result because coordinates are not rotated. Fix it with

\coordinate[rotate around={\n*10:(sample)}] (A) at (-0,1);
\coordinate[rotate around={\n*10:(sample)}] (B) at (-0.25,-1);
\coordinate[rotate around={\n*10:(sample)}] (C) at (0.25,-1);       

Problem with the triangle (source) -- (edgeleft) -- (edgeright) -- cycle is that it does not form a closed path. Can be fixed with

\fill[green, ultra thick] (source) -- (edgeleft.west) -- (edgeright.east) -- cycle;

Alternatively define a node at detector and then use its anchors to draw the cone.

\node[rotate around={\n*10:(sample)}, minimum width=1cm] at (0,-1.125) (det){} ;
 %
\fill[gray,semitransparent] (source) -- (det.north east) -- (det.north west) -- cycle;

enter image description here

\documentclass[export]{standalone}
\usepackage{animate}
\usepackage{tikz}

\begin{document}

\begin{animateinline}[autoplay,loop]{10}
    \multiframe{36}{n=1+1}{
        \begin{tikzpicture}[scale=2]
            \draw[->] (-1.75,0) -- (1.75,0);
            \draw[->] (0,-1.75) -- (0,1.75);
            % Rotation arc
            \draw[->, ultra thick,rotate around={\n*10:(0,0)}] (1,0) arc [start angle=0, end angle=180, radius=1];
            \draw[->, ultra thick,rotate around={\n*10:(0,0)}] (-1,0) arc [start angle=-180, end angle=0, radius=1];
            % Stuff
            \fill[red,rotate around={\n*10:(0,0)}] (-0.25,1) rectangle node (source) [black,fill=white, semitransparent, text opacity=1] {X-ray} +(0.5,0.5);
            \fill[green] (-0.25,-0.25) rectangle node [black,fill=white, semitransparent, text opacity=1] (sample){Sample} +(0.5,0.5) ;
            \node[rotate around={\n*10:(sample)}, minimum width=1cm] at (0,-1.125) (det){} ;
            \node[rotate around={\n*10:(sample)}] at (0, 1.125) (src){} ;            
            \fill[blue,fill,rotate around={\n*10:(0,0)}] (-0.5,-1.25) rectangle node (detector) [black,fill=white, semitransparent, text opacity=1] {Detector} +(1,0.25);
            \draw[rotate around={\n*10:(0,0)}] (-0.5,-1) node (edgeleft) {L};
            \draw[rotate around={\n*10:(0,0)}] (0.5,-1) node (edgeright) {R};           
            % Cone, based on section 4.1.5 in pgfmanual.pdf
            \pgfdeclarelayer{background}
            \pgfsetlayers{background,main}
            \begin{pgfonlayer}{background}
                \fill[gray,semitransparent] (src.south) -- (det.north east) -- (det.north west) -- cycle;
                \draw [red] (src.south) -- (det);
            \end{pgfonlayer}
        \end{tikzpicture}
    }
\end{animateinline}

\end{document}

PS: Note that I have made some changes to make the red line align with the cone.

nidhin
  • 7,932
  • The anchor is a very good idea, thanks! I really like the scope answer because it makes the code a bit more concise. I accepted the other answer, but will use a combination of both in the end. – Habi Nov 08 '19 at 19:35