2

The wonderful answer to the question Easy curves in TikZ shares some code that is defined inside a tikzpicture environment. I share the relevant portion of the answer here:


Here is a slightly modified version of the plothandler, which allows you to specify the first and last support point using the TikZ key first support={<point>} and last support={<point>}, where <point> can be any TikZ coordinate expression, such as(1,2), (1cm,2pt), (A.south west), ([xshift=1cm] A.south west) (thanks to Andrew Stacey's wonderful answer to Extract x, y coordinate of an arbitrary point in TikZ).

By default, the points are assumed to refer to coordinates relative to the first/last point of the path. You can specify that the support points are given as absolute coordinates by using the keys absolute first support, absolute last support, or absolute supports.

 \documentclass{article}

\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,shapes.misc}

\begin{document}
\begin{tikzpicture}
\tikzset{
    show curve controls/.style={
        decoration={
            show path construction,
            curveto code={
                \draw [blue, dashed]
                    (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta)
                    node [at end, cross out, draw, solid, red, inner sep=2pt]{};
                \draw [blue, dashed]
                    (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast)
                    node [at start, cross out, draw, solid, red, inner sep=2pt]{};
            }
        }, decorate
    }
}

\makeatletter
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}

\newif\iffirstsupportabsolute
\newif\iflastsupportabsolute

\tikzset{
    absolute first support/.is if=firstsupportabsolute,
    absolute first support=false,
    absolute last support/.is if=lastsupportabsolute,
    absolute last support=false,
    absolute supports/.style={
        absolute first support=#1,
        absolute last support=#1
    },
    first support/.code={
        \gettikzxy{#1}{\pgf@plot@firstsupportrelx}{\pgf@plot@firstsupportrely}
    },
    first support={(0pt,0pt)},
    last support/.code={
        \gettikzxy{#1}{\pgf@plot@lastsupportrelx}{\pgf@plot@lastsupportrely}
    },
    last support={(0pt,0pt)}
}

\def\pgf@plot@curveto@handler@initial#1{%
  \pgf@process{#1}%
  \pgf@xa=\pgf@x%
  \pgf@ya=\pgf@y%
  \pgf@plot@first@action{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
  \xdef\pgf@plot@curveto@first{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
  \iffirstsupportabsolute
    \pgf@xa=\pgf@plot@firstsupportrelx%
    \pgf@ya=\pgf@plot@firstsupportrely%
  \else
    \advance\pgf@xa by\pgf@plot@firstsupportrelx%
    \advance\pgf@ya by\pgf@plot@firstsupportrely%
  \fi
  \xdef\pgf@plot@curveto@firstsupport{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
  \global\let\pgf@plot@curveto@first@support=\pgf@plot@curveto@firstsupport%
  \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@second%
}

\def\pgf@plot@curveto@handler@finish{%
  \ifpgf@plot@started%
    \pgf@process{\pgf@plot@curveto@second}
    \pgf@xa=\pgf@x%
    \pgf@ya=\pgf@y%
    \iflastsupportabsolute
      \pgf@xa=\pgf@plot@lastsupportrelx%
      \pgf@ya=\pgf@plot@lastsupportrely%
    \else
      \advance\pgf@xa by\pgf@plot@lastsupportrelx%
      \advance\pgf@ya by\pgf@plot@lastsupportrely%
    \fi
    \pgfpathcurveto{\pgf@plot@curveto@first@support}{\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\pgf@plot@curveto@second}%
  \fi%
}
\makeatother

\coordinate (A) at (2,-1);

\draw [gray!50]  (-1,-0.5) -- (1.5,1) -- (3,0);
\draw [
    cyan,
    postaction=show curve controls
] plot [
    smooth, tension=2,
    absolute supports,
    first support={(A)},
    last support={(A)}] coordinates { (-1,-0.5) (1.5,1) (3,0)};

\draw [
    yshift=-3cm,
    magenta,
    postaction=show curve controls
] plot [
    smooth, tension=2,
    first support={(-0.5cm,1cm)},
    last support={(0.5cm,1cm)}] coordinates { (-1,-0.5) (1.5,1) (3,0)};

\end{tikzpicture}
\end{document}

I would like to make the commands defined between \makeatletter and \makeatother available in all my documents. What is the correct way for me to do so?

  • 1
    You can create a personal sty file and the you can load it using \usepackage{}. You can save it on the tex folder to be available for all users (or just save it on the same folder as your tex file). – Sigur Jan 31 '15 at 22:36
  • put the commands without \makeat... in a file mystuff.sty and then use \usepackage{mystuff} whenever you need them – David Carlisle Jan 31 '15 at 22:36
  • @DavidCarlisle Does it matter though that (in the example) they are defined inside a tikzpicture environment? – user89 Jan 31 '15 at 22:38
  • 2
    all the \new... commands are better outside anyway the only issue is the tikzset which would affect all tikzpictures I would guess if you don't want that it is best to make your package do \newcommand\mytikzsetttings{\tikset... then just use `\mytiksettings in teh tikzpicture that need this – David Carlisle Jan 31 '15 at 22:41
  • 2
    @DavidCarlisle could you convert your comments into an answer for this one? – Paul Gessler Apr 26 '15 at 18:25

Your Answer

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

Browse other questions tagged or ask your own question.