13

According to the 'Defining New Arrow Tip Kinds' chapter of the TikZ & PGF manual for version 3.0.1a (p. 1016), one of the parameters that must be specified every time a new arrow tip kind is defined is convex hull.

The convex hull of a shape is conceptually similar to its bounding box (but the two are not quite the same). As an illustration of the concept of a convex hull, consider the following picture of an arrow tip in design. The convex hull of the arrow tip is the triangle, whose vertices are (1,0), (-3,2), and (-3,-2).

An arrow tip.

One may wonder why the convex hull needs to be explicitly specified by the designer of the arrow tip kind, when PGF has a built-in mechanism for calculating bounding boxes. The manual addresses this question as follows (last bullet point in section 100.2 on p. 1016).

Normally, PGF automatically keeps track of a bounding box of everything you draw. However, since arrow tips are drawn so often, PGF caches the code needing for drawing arrow tips internally and because of this cache it cannot determine the size of the arrow tip just based on the drawing commands used for drawing the tip. Instead, a convex hull of the arrow tip must be explicitly provided in the definition.

Why does the caching of the code needed for drawing the arrow tips preclude PGF from calculating the arrow tip's bounding-box without the user's hints?

8
  • I interpret the quotation as: PGF updates the picture's bounding box when performing a drawing command; however, drawing the arrow tips doesn't update the bounding box using the actual drawing commands, but just using the convex hull information stored at definition time. The convex hull can be more efficiently rotated or deformed according to the commands for drawing the arrow.
    – egreg
    Commented Jul 20, 2017 at 7:52
  • @egreg: But why can't PGF calculate the convex hull (alternatively, ,the bounding box) on its own just before caching?
    – Evan Aad
    Commented Jul 20, 2017 at 7:59
  • 1
    Because arrow paths are protocoled (again a section in the manual) and the context is not discoverable. Also you might want to leave out certain parts if the arrow is too decorative such as Arc Barb which is a semi cirle (hooks is worse) and the convex hull is itself instead you provide an approximation of your choice. In summary, this is a design choice.
    – percusse
    Commented Jul 20, 2017 at 8:28
  • @percusse: Could you please make the explanation easier? What does it mean that the paths are 'protocoled'? What paths? What do you mean by 'contex'? By whom is it not discoverable? But above all: why is it mandatory to specify a convex hull? Why can't PGF deduce it on its own, at least by default?
    – Evan Aad
    Commented Jul 20, 2017 at 8:35
  • 1
    @EvanAad You are the one who is jumping into the lowest levels of PGF and asking simple answers :) Imagine I give you a Bezier curve and ask you what the convex hull is, how do you find it ?
    – percusse
    Commented Jul 20, 2017 at 8:38

1 Answer 1

26
+50

The red box is the official bounding box.

The green box is the bounding box of the arrowhead.

The blue box is the fictional bounding box that is calculated using the green box instead of the convex hull.


Playing code

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\foreach\i in{1,...,60}{
    \tikz[line width=.1cm]{
        \draw[rotate=\i*6,line width=1cm,-{>[length=3cm]}](0,0)--(7,0);
        \draw[red](current bounding box.south west)rectangle(current bounding box.north east);
        \pgfinterruptboundingbox
            \draw[line width=1cm,-{>[length=3cm]},transparent](6,0)--(7,0);
            \path(current bounding box.south west)coordinate(A)
                 (current bounding box.south east)coordinate(B)
                 (current bounding box.north west)coordinate(C)
                 (current bounding box.north east)coordinate(D);
            \draw[green,transform canvas={rotate=\i*6}](A)rectangle(D);
        \endpgfinterruptboundingbox
        \path([rotate=\i*6]A)([rotate=\i*6]B)([rotate=\i*6]C)([rotate=\i*6]D);
        \draw[blue](current bounding box.south west)rectangle(current bounding box.north east);
        \path(-10,-10)(10,10);
    }
}
\end{document}
9
  • 3
    Sorcery! Off with his head!
    – Evan Aad
    Commented Jul 20, 2017 at 11:28
  • Very cool! Is the animation effect achieved solely with TikZ?
    – Evan Aad
    Commented Jul 20, 2017 at 11:28
  • 1
    @EvanAad With the help of ImageMagick, you can convert a series of PDF pages into a GIF file. The terminal command used here is convert -delay 10 -dispose previous -density 100 381452.pdf 52.gif.
    – Symbol 1
    Commented Jul 20, 2017 at 11:33
  • Thanks. Your code produces 60 pdf pages, but I don't see any \newpage command. How does TikZ know to jump to the next page?
    – Evan Aad
    Commented Jul 20, 2017 at 11:38
  • 1
    It is the \documentclass[tikz]{standalone} that will separate each tikzpicture into individual pages. By the way, \tikz is an alternative of the tikzpicture environment.
    – Symbol 1
    Commented Jul 20, 2017 at 11:40

You must log in to answer this question.

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