Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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:

enter image description here

… 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 (cylinder) circle[radius = 0.25cm];
  \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}

share|improve this question
3  
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 at 22:04
3  
@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 at 22:10
6  
fwiw, I think your question is fine, and on topic - I feel like you'll be unlucky to get it closed –  cmhughes May 9 at 22:56
5  
@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 at 23:05
1  
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 at 23:08

3 Answers 3

up vote 10 down vote accepted

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}

enter image description here

share|improve this answer
2  
You can save one more keystroke by removing % right after {standalone}. –  stalking is prohibited May 10 at 10:07
3  
@IamwhoIsayIam I can save a lot by removing all the spaces and make a one liner. –  percusse May 10 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 at 2:02
1  
@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 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}
{radius}{intersection}{)--}{tri}{line}\end{document}
share|improve this answer
12  
TeX.SX users, beware! Obfuscating troll on the loose! –  Jubobs May 9 at 22:51
    
So true! And that comment is @David, not at Jubobs. –  Steven B. Segletes May 9 at 23:17
    
@Jubobs "troll" what a thing to say:-) –  David Carlisle May 10 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 at 12:19
2  
@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 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,
    MarkAngleRadius=1,
}

\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}
    \rput{(C)}(P){\psarc(P){.6}{90}{180}\psline(P)([nodesep=.5,angle={!\n\space 4 mul Pi add 2 div neg RadtoDeg}]P)}
    \pcline[offset=.5]{|*-|*}(C)(C|P)
    \pcline[linestyle=dashed,nodesepB=-.5](P)(C|P)
\end{pspicture}}
\end{document}

Final result

share|improve this answer
    
(+1) I'm sorry, I just… have to know… I don't know PSTricks, but I need to know if the turning radius line touches the top of the triangle there. For science (and mild obsessive-compulsive tendencies). –  Sean Allred May 12 at 3:40
    
@SeanAllred: Is it a question or a statement? –  stalking is prohibited May 12 at 4:34
    
Question. :) It looks like it should. –  Sean Allred May 12 at 14:17
    
@SeanAllred: The rotating radius line will reach the top point of the triangle if and only if a certain condition is satisfied. The condition is the length of the hypotenuse must be an integer multiple of the wheel circumference. –  stalking is prohibited May 12 at 14:47
1  
Yay! Thanks for the explanation. :) –  Sean Allred May 12 at 14:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.