7

As far as I know the brace decoration is only available for straight lines, as in the following example :

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}
\begin{tikzpicture}[decoration={brace,raise=2pt}]
    \draw [postaction={draw,decorate,red}] (0,0) to[bend left] (3,1);
\end{tikzpicture}
\end{document}

Do you khow how can I use (define ?) a curved brace decoration that follows an arbitrary (not only straight) path.
And if possible that have not only the standard parameters raise, mirror, but also a bump position that is by default .5 and that set the position of the middle "bump" of the brace.

Thanks in advance for your help.

enter image description here

  • 1
    Here is a solution for circular arcs. – user121799 May 27 '19 at 17:04
  • Marmot, thanks for the link. But I'm looking for a decoration, not for instructions to draw a particular one. And I like the "shape" of the original brace. The only problem for me is that it do not follow the curve. And I don't know how to make a decoration that is a mixture between brace and curveto. – mefortex May 27 '19 at 17:16
6

Here is a first (!) proposal. It does some braces along arbitrary paths. The way it works is that there is recording phase, to which you pass the path. In this phase you can also specify keys. In the present version these are raise and mirror but this is up to negotiations. ;-) The second phase draws the brace. I added a simpleminded proposal but as before I will be happy to address constructive inputs that tell me how the appearance can be improved. Constructing a brace along the path you have in your MWE becomes as simple as saying

\path[record path]  (0,0) to[bend left] (3,1);
\draw[brace];

BTW, if anyone is even thinking of making this a one-step procedure by employing \pgfextra (or something equivalent): PLEASE DON'T! If you have another way that is robust I am all ears. Here is the code.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.markings}
\newcounter{bracep}
\begin{document}
\begin{tikzpicture}[record path/.style={/utils/exec=\tikzset{bent brace/.cd,#1},
    decorate,decoration={markings,mark=at position 0 with
    {\setcounter{bracep}{1}%\typeout{\pgfdecoratedpathlength}
    \path(0pt,{\pgfkeysvalueof{/tikz/bent brace/scale}*\pgfkeysvalueof{/tikz/bent brace/raise}})
     coordinate (bracep-\number\value{bracep});
     \pgfmathsetmacro{\mystep}{(\pgfdecoratedpathlength-4pt)/int(1+(\pgfdecoratedpathlength-4pt)/2pt)}
     \xdef\mystep{\mystep}},
    mark=between positions 2pt and {\pgfdecoratedpathlength-2pt} step \mystep pt with {\stepcounter{bracep}
    \pgfmathtruncatemacro{\itest}{
    ifthenelse(abs(\number\value{bracep}*2pt/\pgfdecoratedpathlength-0.5)<1pt/\pgfdecoratedpathlength,1,0)}
    \coordinate (bracep-\number\value{bracep}) at
    (0,{\pgfkeysvalueof{/tikz/bent brace/scale}*(\pgfkeysvalueof{/tikz/bent brace/raise}+2pt+\itest*2pt)})
    \ifnum\itest=1
     node[transform shape,bent brace/nodes]{\pgfkeysvalueof{/tikz/bent brace/text}}
    \fi;},
    mark=at position 1 with {\stepcounter{bracep}
    \coordinate (bracep-\number\value{bracep}) at (0,\pgfkeysvalueof{/tikz/bent brace/scale}*\pgfkeysvalueof{/tikz/bent brace/raise});}
    }},brace/.style={insert path={plot[smooth,samples at={1,...,\number\value{bracep}},variable=\x]
    (bracep-\x)}},
    bent brace/.cd,raise/.initial=0pt,scale/.initial=1,text/.initial={},
    nodes/.style={},node options/.code=\tikzset{bent brace/nodes/.append style=#1},
    mirror/.code={\tikzset{bent brace/scale=-1}}]
    \path[postaction={record path={text=stuff,node options={above,text depth=0.5ex}}},draw,ultra thin]  (0,0) to[bend left](3,1);
    \draw[brace];
    \path[postaction={record path={raise=4pt}},draw,ultra thin]  (3,1) to[bend left] (3,-2);
    \draw[blue,brace];
    \path[postaction={record path={mirror,text={more stuff},node
    options={red,below}}},draw,ultra thin] (0,0) 
    to[bend right] (3,-2);
    \draw[red,brace];
\end{tikzpicture}
\end{document}

enter image description here

The ultra thin paths are just to show the paths that get braced, and the code also has examples of some text above or below the center of the brace. Of course, one may want to combine this with decorations.text to bend the text as well.

| improve this answer | |
  • One of a wonderful suggestion again from you.... – MadyYuvi May 28 '19 at 4:25
  • Thanks Marmot for all your efforts ! I'm sure I'll learn a lot from your code. But I'm really looking for a decoration not for some other way to do a curved brace. Since I asked the question I discovered \pgfdeclaredecoration in the manual. I hope that somebody will be able to show me how to do this. Thanks one more time. – mefortex May 28 '19 at 5:15
  • When I try \draw[record path,smooth] plot coordinates{(3,1) (3,-2) (1,-1)}; tex throw an error ! Dimension too large.. Any Idea ? – mefortex May 28 '19 at 5:23
  • 1
    @mefortex Decorations will also have problems with \draw plot[smooth] coordinates{(3,1) (3,-2) (1,-1)}; because the curvature is rather high. Here the error comes from decorations.markings. See e.g. tex.stackexchange.com/q/409367/121799 for a related discussion and to see that this is not restricted to decorations.markings. (And I am aware of \pgfdeclaredecoration, I was using it many times, see e.g. tex.stackexchange.com/a/449706/121799.) – user121799 May 28 '19 at 13:04
  • Thanks for your explanation and the links ! – mefortex May 28 '19 at 13:22
4

One option for this would be to define new arrow tips that do the curved ends. This would mean that the brace would exactly follow the original path (except at the ends) rather than being offset, and the easiest way to put the central bump in would be to manually break the path. Nevertheless, there's a simplicity to the idea that I quite like. (I did have a look at the decoration route, but looking was as far as I got.)

\documentclass{article}
%\url{https://tex.stackexchange.com/q/492887/86}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\pgfdeclarearrow{%
  name=Brace tip,
  parameters = {%
    \the\pgfarrowlength
    \the\pgfarrowlinewidth
  },
  setup code = {
    \pgfarrowssettipend{.5\pgfarrowlength}
    \pgfarrowssetlineend{-.45\pgfarrowlength}
    \pgfarrowssetvisualbackend{-.5\pgfarrowlength}
    \pgfarrowssetbackend{-.5\pgfarrowlength}
    \pgfarrowshullpoint{.5\pgfarrowlength}{.5\pgfarrowlength}
    \pgfarrowshullpoint{.5\pgfarrowlength}{-.5\pgflinewidth}
    \pgfarrowshullpoint{-.5\pgfarrowlength}{.5\pgflinewidth}
    \pgfarrowshullpoint{-.5\pgfarrowlength}{-.5\pgflinewidth}
    \pgfarrowssavethe\pgfarrowlength
  },
  drawing code = {
    \pgfpathmoveto{\pgfqpoint{-.5\pgfarrowlength}{.5\pgflinewidth}}%
    \pgfpathcurveto%
    {\pgfqpoint{.2\pgfarrowlength}{.5\pgflinewidth}}%
    {\pgfpoint{.5\pgfarrowlength-.25\pgflinewidth}{.05\pgfarrowlength}}%
    {\pgfpoint{.5\pgfarrowlength}{.5\pgfarrowlength}}%
    \pgfpathcurveto%
    {\pgfpoint{.5\pgfarrowlength+.25\pgflinewidth}{.05\pgfarrowlength}}%
    {\pgfqpoint{.2\pgfarrowlength}{-.5\pgflinewidth}}%
    {\pgfqpoint{-.5\pgfarrowlength}{-.5\pgflinewidth}}%
    \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}{.5\pgflinewidth}}
    \pgfpathclose
    \pgfusepathqfill
  },
  defaults = {
    length = .5cm,
  }
}

\begin{document}
\begin{tikzpicture}
\draw[Brace tip-Brace tip,ultra thick] (0,0) .. controls +(2,0) and +(0,-2) .. (4,4);
\draw[{Brace tip[swap]}-{Brace tip[swap]},ultra thick] (4,4) .. controls +(0,2) and +(-2,0) .. (8,8);
\end{tikzpicture}
\end{document}

Brace along curve

| improve this answer | |
  • Nice ! I think that this is what is used by Qrrbrbirlbel in this answer pointed to me by Marmot. Why should we define new arrow in place to use Computer Modern Rightarrow with left, right, harpoon and if necessary reversed options ? – mefortex May 28 '19 at 20:24
  • I guess it's a similar idea - I hadn't seen that answer. I have a small preference for tapered ends as in this one. I don't really understand your question, though. – Andrew Stacey May 28 '19 at 21:42
  • Sorry to not being clear in my question. My question is : why we should define a new arrow tip and not simply using existing one like for example \draw[{Computer Modern Rightarrow[left,reversed]}-{Computer Modern Rightarrow[left,reversed]}] (0,0) .. controls +(2,0) and +(0,-2) .. (4,4);\draw[{Computer Modern Rightarrow[right,reversed]}-{Computer Modern Rightarrow[right,reversed]}] (4,4) .. controls +(0,2) and +(-2,0) .. (8,8); ? – mefortex May 29 '19 at 5:24
  • Oh sorry, I see now : your arrow tip is nicer (it goes thin at the end) and the join in the middle is perfect. Thanks for showing me how we can define this arrow tips ! – mefortex May 29 '19 at 5:31
  • The other reason being that I was unaware of that arrow tip! So I've learnt something too. – Andrew Stacey May 29 '19 at 7:28

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.