# TikZ: How can I write my code more concisely?

I am learning how to use TikZ and want to learn ways to write more concise TikZ code. I feel I use many more lines than others may need to achieve the same results. In particular, I want to learn a technique or practice for writing concise code that I can use for all my TikZ documents.

As an example, consider this image:

… which was created with the code below (the spacing is supplied for readability). Note that you may have to update TikZ and pgf to run this code, as the angles and quotes libraries are relatively new as of May 2014.

\documentclass[tikz]{standalone}%

\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{angles}
\usetikzlibrary{quotes}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0, 0);
\coordinate (B) at (3, 0);
\coordinate (C) at (3, 2);

\draw[name path = tri] (A) -- (B) -- (C) -- cycle pic["$\alpha$", -stealth,
draw, angle radius = 1cm, angle eccentricity = 1.25] {angle = B--A--C};

\path[name path = line] (0, 1.4) -- +(2.9, 0);
\path[name intersections = {of = line and tri, by = P1}];

\path (P1) -- ($(P1)!.25cm!-90:(A)$) coordinate (cylinder);
\path[name path = line2] (cylinder) -- +(1.05, 0);
\path[name intersections = {of = line2 and tri}];

\draw[dashed, gray] (cylinder) -- (intersection-1);
\draw[stealth-stealth] (3.15, 2) -- ($(intersection-1) + (.15, 0)$);
\draw (3.1, 2) -- (3.2, 2);
\draw ($(intersection-1) + (.1, 0)$) -- +(.1, 0);
\draw (cylinder) -- +(45:.25);

\pgfmathsetmacro{\angle}{atan(2/3)};
\pgfmathsetmacro{\ppi}{\angle + 180}

\begin{scope}[rotate = \angle]
\clip ($(cylinder) + (0, .4)$) rectangle ($(cylinder) + (-.4, 0)$);

\draw[name path global = rotation] (cylinder) circle[radius = .395cm];
\end{scope}

\path[name path = line3] (cylinder) -- +(\ppi:.4);
\path[name intersections = {of = line3 and rotation, by = P2}];
\end{tikzpicture}
\end{document}


-
Code-review questions are not really on topic here. Unless you have a specific problem with a specific part of the code, I'm tempted to vote to close your question as "too broad". –  Jubobs May 9 '14 at 22:04
@Jubobs I re-read what question are okay and not okay section. From my reading, I don't see a problem with it. This invites sharing experiences over opinions and this is a question about how (these two come from the not okay section under some subjective are okay). –  dustin May 9 '14 at 22:10
fwiw, I think your question is fine, and on topic - I feel like you'll be unlucky to get it closed –  cmhughes May 9 '14 at 22:56
@dustin: You are using a number of practices that make your code more readable and more robust, at the expense of being a bit longer. For instance, you have lots of spaces and skipped lines that are not strictly necessary. You also describe a number of paths and coordinates in terms of previously defined things. If you were to eliminate the unnecessary spaces and give explicit, hand-computed coordinates for everything (and eliminate all your names), your code would be significantly shorter; but I urge you not to do so. –  Charles Staats May 9 '14 at 23:05
That having been said, you can probably get some mileage out of stringing together disjoint paths in one command, e.g., \path (0,0) \coordinate(A) (3,0) \coordinate(B) (3,2) \coordinate(C);. Note that I have not checked to make sure that actually works, but I know similar things are possible. –  Charles Staats May 9 '14 at 23:08

Some shortening without the angle arrow. But that can be done with angle library anyway. Changing the angle is possible.

\documentclass[tikz]{standalone}%
\begin{document}
\begin{tikzpicture}
\def\myang{35}
\draw (0,0) coordinate(o) --+(\myang:1cm) +(1,0)arc (0:\myang:1cm)
node[right,midway]{$\alpha$}--(\myang:3cm) coordinate (a)
node[minimum size=5mm,circle,draw,pos=0.4,anchor={-90+\myang}] (b) {}--(o-|a)
(b.center)--(b.\myang) (b.210)++(210:1mm) arc (210:120:3.5mm);
\draw[dashed] (b.center) -- (a|-b);
\draw[>=latex,|<->|] ([xshift=2mm]a|-b) -- ([xshift=2mm]a);
\end{tikzpicture}
\end{document}


-
You can save one more keystroke by removing % right after {standalone}. –  kiss my armpit May 10 '14 at 10:07
@IamwhoIsayIam I can save a lot by removing all the spaces and make a one liner. –  percusse May 10 '14 at 13:06
Can you explain this piece node[minimum size=5mm,circle,draw,pos=0.4,anchor={-90+\myang}] (b) {}--(o-|a) (b.center)--(b.\myang) (b.210)++(210:1mm) arc (210:120:3.5mm);? –  dustin May 13 '14 at 2:02
@dustin I'm placing a node on the 40% of the path lenght via pos key and I'm anchoring by it's point where it touches the inclined path via anchor key and name it as b. Then I continue to draw to the orthogonal intersection of o and a. Then I move the pen to b.center and draw the radius mark. Then I move again the pen to b.210 and give 1mm offset to draw the motion arc around it. I adjust the radius to 3.5 mm since the radius of the ball is 2.5mm from minimum size + 1mm offset. –  percusse May 13 '14 at 9:10

This is more concise (and no less readable than most tikz code:-)

\documentclass[tikz]{standalone}\usetikzlibrary{calc,intersections,
angles,quotes}\def\c{\coordinate}\def\d{\draw}\def\p{\path}
\def\pp#1#2#3#4#5{\p[name path=#1](#2)--+(#3);\p[name intersections={of=#1
and #4,#5}];}\let\q\pgfmathsetmacro
\begin{document}\def\z#1#2#3#4#5#6#7#8{\begin{tikzpicture}
\c(A)at(0,0);\c(B)at(3,0);\c(C)at(3,2);\d[name path=#7](A#6(B#6(C#6cycle
pic["$\alpha$",-#3,draw,#1 #4=1cm,#1 eccen#7city=1.25]{#1=B--A--C};\pp
{#8}{0,1.4}{2.9,0}{#7}{by=P1}\p(P1#6($(P1)!.25cm!-90:(A)$)coordinate(#2);
\pp{#82}{#2}{1.05,0}{#7}{}\d(#2)circle[#4=0.25cm];\d[dashed,gray](#2#6(#5-1);
\d[#3-#3](3.15,2#6($(#5-1)+(.15,0)$);\d(3.1,2#6(3.2,2);\d($(#5-1)+(.1,0)$#6+
(.1,0);\d(#2#6+(45:.25);\q{\angle}{atan(2/3)};\q{\ppi}{\angle+180}\begin
{scope}[rotate=\angle]\clip($(#2)+(0,.4)$)rect#1($(#2)+(-.4,0)$);
\d[name path global=rotation](#2)circle[#4=.395cm];\end{scope}\pp{#83}{#2}
{\ppi:.4}{rotation}{by=P2}\end{tikzpicture}}\z{angle}{cylinder}{stealth}

-
TeX.SX users, beware! Obfuscating troll on the loose! –  Jubobs May 9 '14 at 22:51
So true! And that comment is @David, not at Jubobs. –  Steven B. Segletes May 9 '14 at 23:17
@Jubobs "troll" what a thing to say:-) –  David Carlisle May 10 '14 at 0:50
@Jubobs Note that this is not really obfuscation, it is a demonstration of what happens if you apply the common programming practice of making things concise by parametrising to remove duplicate code to a macro language like TeX. So tri only gets entered once and used as {tri} and eccen tri city. To TeX, that is no different from taking any common code out of a loop. So it is a demonstration by taking to extremes that "more concise" probably shouldn't be a design goal. –  David Carlisle May 10 '14 at 12:19
@DavidCarlisle Ok, it's more akin to a combination of optimisation taken to the extreme and minification, but I maintain that troll applies here :p –  Jubobs May 10 '14 at 12:23

It is still too short in an animation.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-eucl}
\psset
{
CurveType=polygon,
PointName=none,
PointSymbol=none,
LabelSep=.5,
}

\begin{document}
\multido{\n=3.14+.10}{50}{%
\begin{pspicture}(8,6)
\pstGeonode{A}(7,0){B}(7,6){C}
\pstMarkAngle[arrows=->]{B}{A}{C}{$\alpha$}
\pnode([offset=.5,nodesep=\n]{C}A){P}
\pscircle(P){.5}