4

I want to draw straight lines along a smooth path in tikz. I tried to use the decorations.markings-solution described in Drawing paths/nodes along a path in Tikz and used it like this:

\documentclass{article}

\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\begin{document}
\pagestyle{empty}

\begin{tikzpicture}[
  decoration={
    markings,
    mark=between positions 0.125 and 0.90 step 0.0625 with {\draw[thin] (0,-0.2)--(0,0.2);},
  }
]
    \draw[thick,postaction={decorate}] (-2.5,-1) to (-2,-0.5)
        to [out=45,in=180] (0,-1.5)
        to [out=0,in=180] (2,-1)
        to [out=0,in=-90] (2.5,0)
        to [out=90,in=0] (1.5,1.5)
        to [out=170,in=0] (0,1.5)
        to [out=180,in=45] (-2,-0.2)
        to [out=220,in=45] (-2.5,-1);
\end{tikzpicture}


\end{document}

The result looks like this:

enter image description here

However, this is not what I want. I want two pictures and in the first one, the straight lines should remain straight, i.e. I want them only to be shifted and not to be rotated. How can I achieve that? According to the tikz documentation, the reason why the lines are rotated is that decoration.markings automatically uses a coordinate system, where the x-axis is tangent to the curve. Is there any way to use the global coordinate system? In a second picture, I would like the straight lines to be rotated, but I want to do this myself. To calculate the degree of rotation, I need the current number of my line, which should be given by \pgfkeysvalueof{/pgf/decoration/mark info/sequence number} and the total number of lines. How do I get this?

4

The trick is to reset the transformation angle using \pgftransformresetnontranslations, I had the same problem and I only found it by digging through <tex-installation-path>/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex. Only once I knew the command I discovered it in section 75.2 of the pgfmanual.

If you want to draw a straight line at a set angle the polar coordinate system is the way to go. You can then specify the angle at which the line should be drawn, and this is parsed by the mathematical engine so you can simply say 20*\pgfkeysvalueof{/pgf/decoration/mark info/sequence number} for example. The second argument is then the distance to the origin of the coordinate system. So if you want a constant line length relative to a point other than the origin you need to specify a relative coordinate like (0,-0.2) -- +(20:4mm).

Edit If you want the midpoints of these lines on the curve the easiest way is to draw to halve lines, the second one either with the same angle +180, or a negative radius. The second option is probably safer since angles should be provided as a value between -360 and +720 degrees, and adding 180 degrees is then a significant portion of the range.

\documentclass{article}

\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\begin{document}
\pagestyle{empty}

\begin{tikzpicture}[
  decoration={
    markings,
    mark=between positions 0.125 and 0.90 step 0.0625 with {
    \pgftransformresetnontranslations    
    \draw[thin] (0,-0.2)--(0,0.2);},
  }
]
    \draw[thick,postaction={decorate}] (-2.5,-1) to (-2,-0.5)
        to [out=45,in=180] (0,-1.5)
        to [out=0,in=180] (2,-1)
        to [out=0,in=-90] (2.5,0)
        to [out=90,in=0] (1.5,1.5)
        to [out=170,in=0] (0,1.5)
        to [out=180,in=45] (-2,-0.2)
        to [out=220,in=45] (-2.5,-1);
\end{tikzpicture}

\begin{tikzpicture}[
  decoration={
    markings,
    mark=between positions 0.125 and 0.90 step 0.0625 with {
    \pgftransformresetnontranslations    
    \draw[thin] (0,0)--+(canvas polar cs:angle=20*\pgfkeysvalueof{/pgf/decoration/mark info/sequence number},radius=2mm);
    \draw[thin] (0,0)--+(canvas polar cs:angle=20*\pgfkeysvalueof{/pgf/decoration/mark info/sequence number},radius=-2mm);},
  }
]
    \draw[thick,postaction={decorate}] (-2.5,-1) to (-2,-0.5)
        to [out=45,in=180] (0,-1.5)
        to [out=0,in=180] (2,-1)
        to [out=0,in=-90] (2.5,0)
        to [out=90,in=0] (1.5,1.5)
        to [out=170,in=0] (0,1.5)
        to [out=180,in=45] (-2,-0.2)
        to [out=220,in=45] (-2.5,-1);
\end{tikzpicture}

\end{document}
  • Thanks! Your first picture is exactly how I want it. However, in your second picture, the midpoints of the lines are no longer on the curve. :( – Meneldur Feb 26 '14 at 8:40
  • Fixed that in my answer, using two halve lines in the decoration both starting on the curve. – hugovdberg Feb 26 '14 at 8:49
5

Here is a solution for the first part of your question: (red) straight lines are only shifted and not rotated.

(I don't understand the second part of your question...)

enter image description here

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\begin{document}
\begin{tikzpicture}
  \tikzset{
    decoration={
      markings,
      mark=between positions 0.125 and 0.90 step 0.0625 with {
        \draw[thin] (0,-0.2)--(0,0.2);
        \xdef\maxseq{\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}}
        \coordinate (pt-\maxseq)
        at (0,0);
      },
    }
  }

  \draw[thick,postaction={decorate}] (-2.5,-1) to (-2,-0.5)
  to [out=45,in=180] (0,-1.5)
  to [out=0,in=180] (2,-1)
  to [out=0,in=-90] (2.5,0)
  to [out=90,in=0] (1.5,1.5)
  to [out=170,in=0] (0,1.5)
  to [out=180,in=45] (-2,-0.2)
  to [out=220,in=45] (-2.5,-1);

  \foreach \c in {1,...,\maxseq}{
    \draw[red] (pt-\c) +(0,-0.2) -- +(0,0.2);
  }
\end{tikzpicture}
\end{document}
  • Thanks! You can also draw it in black (just remove the [red] or replace it with whatever you like). The trick seems to be to save the coordinates and use them to paint the straight lines separately. The second part of my questions boils down to: How to calculate \maxseq, which you also answered perfectly. :) – Meneldur Feb 26 '14 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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