28

This question led to a new package:
abraces

How can I control the position of an overbrace's spike?

e.g. I want:

/------^----------------------\

aksdj ajksdnkajs ajsdknakjsnd jaknd

As opposed to:

/--------------^--------------\

aksdj ajksdnkajs ajsdknakjsnd jaknd

2 Answers 2

32

\overbrace and \underbrace are constructed out of 5 parts:

  1. left end;
  2. (left) horizontal rule;
  3. tip (up/down);
  4. (right) horizontal rule;
  5. right end.

Since both horizontal rules are leaders, it is easy enough to modify them using a "shared" approach. That is you can change the share of the left leader in comparison to the right, thereby moving the tip left or right. For example, sharing the left/right leader at a 1:2 ratio would put the tip 1/3 of the way in, while a 3:2 ratio would put the tip 60% of the way in. The default would be a centred/1:1 ratio.

enter image description here

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\usepackage{multido}% http://ctan.org/pkg/multido

\makeatletter
\def\@@bfil{\leaders \vrule \@height \ht\z@ \@depth \z@ \hfill}% default brace filler
\def\@bLfil{\@@bfil}% left leader filler
\def\@bRfil{\@@bfil}% right leader filler
\def\resetbraceratio{\gdef\@bLfil{\@@bfil}\gdef\@bRfil{\@@bfil}}% reset to default braces
\def\setbraceratio#1#2{% \setbraceratio{<left>}{<right>}
  \let\@bLfil\relax% clear left filler
  \multido{\iA=1+1}{#1}{\gappto\@bLfil{\@@bfil}}% increase left ratio
  \let\@bRfil\relax% clear right filler
  \multido{\iA=1+1}{#2}{\gappto\@bRfil{\@@bfil}}% increase right ratio
}
\def\upbracefill{$\m@th\setbox\z@\hbox{$\braceld$}\bracelu\@bLfil\bracerd\braceld\@bRfil\braceru$}
\def\downbracefill{$\m@th\setbox\z@\hbox{$\braceld$}\braceld\@bLfil\braceru\bracelu\@bRfil\bracerd$}
\makeatother

\begin{document}

\setbraceratio{3}{1}% 3:1 ratio
$\underbrace{\textrm{The quick brown fox jumped over the lazy dog}}$ \par
\setbraceratio{1}{5}% 1:5 ratio
$\underbrace{\textrm{The quick brown fox jumped over the lazy dog}}$ \par
\setbraceratio{7}{2}% 7:2 ratio
$\overbrace{\textrm{The quick brown fox jumped over the lazy dog}}$ \par

\end{document}

\setbraceratio{<left>}{<right>} sets the ratio between the left and right part of the braces, while \resetbraceratio restores to the default (or 1:1).

The problem with this approach is the the horizontal centre may differ from the location where the tip is. As such, adding text as a superscript/subscript would have to be moved into the appropriate position. It would be possible to extend this solution to work with lengths rather than ratio's. However, that would require some testing to make sure you don't exceed the box width - ratio's take care of this naturally.


The abraces package now provides a character key-driven interface to brace creation. Some examples from the documentation:

enter image description here

Brace construction is based on character combinations:

enter image description here

5
  • 2
    Nice answer!... Aug 24, 2012 at 2:36
  • @GonzaloMedina: Thanks! I'll be looking for a way to get rid of the package requirements though, and extending it to lengths (if possible).
    – Werner
    Aug 24, 2012 at 2:38
  • 2
    This should definitely be added to some "default" package like mathtools, or embedded to a seperate package!
    – yo'
    Aug 24, 2012 at 9:42
  • 1
    @tohecz: Done. :)
    – Werner
    Sep 11, 2012 at 5:24
  • This looks great :-)
    – raphink
    Sep 17, 2012 at 11:31
22

Another option is to use the infamous \tikzmark, and use a brace decoration with the aspect=<percent> to control the location of the spike. Here is a version adapted from Curly brace to insert something into an equation? Like an inverted underbrace which gives you all the inherent flexability of tikz:

enter image description here

The parameters passed to \InsertUnderBrace are:

  • [#1] tikz draw options,

  • [#2] tikz brace options,

  • {#3} name of left \tikzmark,

  • {#4} name of right \tikzmark,

  • {#5} text to be placed under the brace.

Notes:

  • This does require two runs. First one to determine the locations, and the second to do the drawing.

References:

Code:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

% Tweak these as necessary
\newcommand*{\BraceAmplitude}{0.4em}%
\newcommand*{\BraceAspect}{0.5}% 
\newcommand*{\VerticalOffset}{0.4ex}%  
\newcommand*{\HorizontalOffset}{0.0em}% 


\NewDocumentCommand{\InsertUnderBrace}{%
    O{} % #1 = draw options
    O{} % #2 = optional brace options
    m   % #3 = left tikzmark
    m   % #4 = right tikzmark
    m   % #5 = text to place underbrace
}{%
    \begin{tikzpicture}[overlay,remember picture]
\draw [decoration={brace, amplitude=\BraceAmplitude, aspect=\BraceAspect, #2}, decorate, thick, draw=blue, text=black, #1]
        ($(#4)+(\HorizontalOffset,-\VerticalOffset)$) -- 
        ($(#3)+(-\HorizontalOffset,-\VerticalOffset)$)
        node [below=\VerticalOffset, midway] {#5};
    \end{tikzpicture}%
}%


\begin{document}
\[
    \tikzmark{StartBraceA} \sin^2 \alpha + \cos^2 \theta \tikzmark{EndBraceA}
    \qquad
    \tikzmark{StartBraceB} \sin^2 \alpha + \cos^2 \theta \tikzmark{EndBraceB}
    \qquad
    \tikzmark{StartBraceC} \sin^2 \alpha + \cos^2 \theta \tikzmark{EndBraceC}
\]

\InsertUnderBrace[draw=red,text=blue]{StartBraceA}{EndBraceA}{default}

\InsertUnderBrace[draw=violet,text=blue][aspect=0.25]{StartBraceB}{EndBraceB}{$\mathrm{aspect} = 0.25$}

\InsertUnderBrace[draw=brown,text=blue, densely dotted][aspect=0.75]{StartBraceC}{EndBraceC}{$\mathrm{aspect} = 0.75$}

\end{document}
1
  • Always good to see your TikZmarks :)
    – percusse
    Aug 29, 2012 at 23:19

You must log in to answer this question.

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