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.

I want to draw this figure in Tikz (apologies for poor image quality):

enter image description here

However, I can't quite figure out a good way to go about it. The only way I know how to draw this is as follows:

  1. Declare a scope which includes arrows halfway along each line segment, and \draw each of the 14 line segments on the outside inside this scope.

  2. Manually \draw the rest of the lines and label them accordingly.

  3. Manually \fill the 8 shaded regions.

  4. Add the two arcs on the sides and label one \gamma.

Surely this is not the most efficient method. Using the calc package might save me a little calculation, but not much time overall. The only other way I've thought to do this is define a command which draws each unshaded triangle, and another which draws each shaded one, but I'm not sure how to automate the label placement, or how to declare a scope within newcommand to use my method for getting arrows on the sides.

What is the best way to draw something like this?

share|improve this question

2 Answers 2

up vote 7 down vote accepted

This uses Caramdir's solution from How to draw an arrow in the middle of the line?

Code

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\usepackage{xifthen}

\begin{document}

\pgfmathsetmacro{\octagonradius}{3}
\pgfmathsetmacro{\octagonbigradius}{\octagonradius/sin(67.5)}

\begin{tikzpicture}
[   midarrow/.style={thick,decoration={markings,mark=at position 0.5 with {\arrow{>}}},postaction={decorate}}
]
    \foreach \x in {1,...,8}
    {   \ifthenelse{\isodd{\x}}
        {\xdef\mysign{1}}
        {\xdef\mysign{-1}}
        \fill[red,opacity=0.4,shift={(0,\mysign*\octagonradius)}] (0,0) -- (45*\x+22.5:\octagonbigradius) -- (45*\x+67.5:\octagonbigradius) -- cycle;
        \fill[blue,opacity=0.4,shift={(0,\mysign*\octagonradius)}] (0,0) -- (45*\x+22.5:\octagonbigradius) -- (45*\x-22.5:\octagonbigradius) -- cycle;
        \draw[shift={(0,\mysign*\octagonradius)}] (0,0) -- node[label=45*\x+112.5:1] {} (45*\x+22.5:\octagonbigradius);
        \draw[shift={(0,\mysign*\octagonradius)}] (0,0) -- node[label=45*\x+157.5:0] {} (45*\x+67.5:\octagonbigradius);
    }
    \foreach \x in {0,...,6}
    {   \ifthenelse{\isodd{\x}}
        {\xdef\mysign{1}}
        {\xdef\mysign{-1}}
        \draw[midarrow,shift={(0,\mysign*\octagonradius)}] (45*\x-22.5:\octagonbigradius) -- (45*\x-67.5:\octagonbigradius);
        \draw[midarrow,shift={(0,-1*\mysign*\octagonradius)}] (45*\x+112.5:\octagonbigradius) -- (45*\x+157.5:\octagonbigradius);
    }
    \draw[shift={(0,\octagonradius)}] (247.5:\octagonbigradius) -- (292.5:\octagonbigradius);
    \draw[very thick,->] (-\octagonbigradius,\octagonbigradius) to[bend right=40] node[left] {Y} (-\octagonbigradius,-\octagonbigradius);
    \draw[very thick,->] (\octagonbigradius,-\octagonbigradius) to[bend right=40] node[right] {Y} (\octagonbigradius,\octagonbigradius);
\end{tikzpicture}

\end{document}

Result

enter image description here

share|improve this answer
    
I think I see the general strategy you're using, but I don't understand what \xdef\mysign{1} is doing. –  Alex Becker Sep 6 '12 at 7:37
    
@AlexBecker: mysign is set to 1 if x is odd and to -1 if it is even. This is used for the shift of the drawing commands, so shifted up or shifted down. It would have also been possible to do if x odd then draw[red,shift up] else draw[red, shift down], but I didn't like putting the draw commands twice. –  Tom Bombadil Sep 6 '12 at 7:42
    
Thanks very much. I actually just realized that after staring at the code some more. I'm going to try using this method to make a similar drawing and see how things work out. –  Alex Becker Sep 6 '12 at 7:45

When you have something that is very periodic a \foreach loop is very encouraging. I have here shown a simple picture given you enough for you to start, but still limited to not be complete.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[%
  ->-/.style={%
      postaction={decorate},decoration={%
          markings,mark=at position #1 with {\arrow{stealth}}%
      }%
  },->-/.default=.5,%
  -<-/.style={
      postaction={decorate},decoration={%
          markings,mark=at position #1 with {\arrowreversed{stealth}}%
      }%
  },-<-/.default=.5]
  \foreach \angle [count=\i] in {22.5,67.5,...,337.5} {
      \ifodd\i\relax
      \draw[-<-] (0,0) -- node{0} (\angle-45:2cm) -- (\angle:2cm) -- cycle;
      \else
      \fill[->-] (0,0) -- node{1} (\angle-45:2cm) -- (\angle:2cm) -- cycle;
      \fi
  }
\end{tikzpicture}  
\end{document} 

I have chosen to use decorations as arrows. In that way it is easier to maintain and reuse the code. The style ->- defaults to drawing an arrow halfway on the path. And -<- draws one reversed. In order to get the 1 and 0 on the curve you need to use the node path halfway on the path.

The crude result:

enter image description here

share|improve this answer
    
I hadn't seen loops in TeX before. Thanks for the answer, it should help me with some of the other stuff I have to TeX. –  Alex Becker Sep 6 '12 at 7:24

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.