3

The following code is an attempt to draw "flags". A flag is a line segment together with a box at the middle, on the left side when looking from the start point to the end point. I'm using a decoration to add a box to every line segment on a path.

\documentclass[tikz, crop, border=1]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}
\begin{tikzpicture}

\tikzset{
    flag/.style = {
        decoration = {
            show path construction,
            lineto code={%
                \drawFlag{(\tikzinputsegmentfirst)}{(\tikzinputsegmentlast)};
            },
            closepath code={%
                \drawFlag{(\tikzinputsegmentfirst)}{(\tikzinputsegmentlast)};
            },
        },
        preaction=decorate
    }
}

\newcommand{\drawFlag}[2]{
    \begin{scope}
        \coordinate (center) at ($#1!0.5!#2$) {};
        \coordinate (back) at ($(center)!0.25cm!#1$) {};
        \coordinate (front) at ($(center)!0.25cm!#2$) {};

        \draw[fill = white, line cap=round] 
            (back) -- 
            ($(back)!0.5cm!90:#2$) -- 
            ($(front)!0.5cm!90:#2$) -- 
            (front);
    \end{scope}
}

\begin{scope}[cm={1, 0, 0.5, 0.5, (0, 0)}]
\drawFlag{(0, 0)}{(2, 0)};
\draw (0, 0) -- (2, 0);
\drawFlag{(2, 0)}{(2, 2)};
\draw (2, 0) -- (2, 2);
\end{scope}

\begin{scope}[cm={1, 0, 0.5, 0.5, (3, 0)}]
\draw[flag] (0, 0) -- (2, 0) -- (2, 2);
\end{scope}

\end{tikzpicture}
\end{document}

The results of this code look like this:

enter image description here

The flags are drawn in two different ways: separately, and then as a decorated path. A shear/slant transformation is applied to both results. The separately drawn result (on the left) is how I would like it to look. However, when drawing a decorated path, the decorations seem not to be transformed (on the right). How can the decorations be made to transform too, so that these results would look the same?

Note: transform canvas does not quite give the correct result, because it distorts line widths.

2
  • While it is not impossible to read out the ambient transformation matrix with \pgfgettransformentries, and to combine the rotational part with the inner one to achieve what you are suggesting, I feel that this is a very complicated way to get the desired output. Would you be interested in alternatives that achieve the same?
    – user121799
    Dec 26, 2018 at 16:40
  • Sure, alternatives are welcome:)
    – kaba
    Dec 26, 2018 at 16:43

1 Answer 1

3

Sorry for the delay and the confusion. After some amount of failed attempts to produce something that works and is elegant I gave up on "is elegant" and provide something that seems to work. The steps are:

  1. Read out non-translational part of transformation.
  2. Make start and end coordinates \tikzinputsegmentfirst and \tikzinputsegmentlast symbolic to avoid "overdoing it" (i.e. transforming twice).
  3. Install the transformations.

Here is the result.

\documentclass[tikz, crop, border=1]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}
\begin{tikzpicture}

\tikzset{get trafo/.code={\pgfgettransformentries{\gtma}{\gtmb}{\gtmc}{\gtmd}{\gtmp}{\gtmp}},
    flag/.style = {get trafo,
        decoration = {
            show path construction,
            lineto code={%
                \path (\tikzinputsegmentfirst) coordinate (tmpa)
                (\tikzinputsegmentlast) coordinate (tmpb);
                \begin{scope}[cm={\gtma,\gtmb,\gtmc,\gtmd, (0, 0)}]
                \drawFlag{(tmpa)}{(tmpb)};
                \end{scope}
            },
            closepath code={%
                \path (\tikzinputsegmentfirst) coordinate (tmpa)
                (\tikzinputsegmentlast) coordinate (tmpb);
                \begin{scope}[cm={\gtma,\gtmb,\gtmc,\gtmd, (0, 0)}]
                \drawFlag{(tmpa)}{(tmpb)};
                \end{scope}
            },
        },
        preaction=decorate
    }
}

\newcommand{\drawFlag}[2]{
    \begin{scope}
        \coordinate (center) at ($#1!0.5!#2$) {};
        \coordinate (back) at ($(center)!0.25cm!#1$) {};
        \coordinate (front) at ($(center)!0.25cm!#2$) {};

        \draw[fill = white, line cap=round] 
            (back) -- 
            ($(back)!0.5cm!90:#2$) -- 
            ($(front)!0.5cm!90:#2$) -- 
            (front);
    \end{scope}
}

\begin{scope}[cm={1, 0, 0.5, 0.5, (0, 0)}]
\drawFlag{(0, 0)}{(2, 0)};
\draw[get trafo] (0, 0) -- (2, 0);
\drawFlag{(2, 0)}{(2, 2)};
\draw (2, 0) -- (2, 2);
\end{scope}

\begin{scope}[cm={1, 0, 0.5, 0.5, (3, 0)}]
\draw[flag] (0, 0) -- (2, 0) -- (2, 2);
\end{scope}

\end{tikzpicture}
\end{document}

enter image description here

For many purposes I wish there was a way to make coordinates "unsymbolic" (but not in the tough way as e.g. tkz-euclide). If anyone reading this knows how to do that, please let me know, I am also willing to ask an official question, of course.

2
  • Nice. Why is it needed to convert \tikinputsegmentfirst to a coordinate?
    – kaba
    Dec 27, 2018 at 13:28
  • @kaba In order to avoid double transformation.
    – user121799
    Dec 27, 2018 at 16:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .