7

I am learning to use TikZ to draw things in LaTeX. One of the things that TikZ seems to use everywhere for specifying coordinates is a tuple. For example,

\begin{tikzpicture}
  \node[isosceles triangle, isosceles triangle apex angle=70,
     draw=black,fill=white, inner sep=0pt,anchor=lower 
     side,rotate=90,draw=black,
     fill=white, minimum height=2 cm] (a) at (0,0) {};
\end{tikzpicture}

Creates a small isosceles triangle. Note the use of (0,0). Let's encapsulate making a triangle as above with the following macro.

\newcommand\Tri[3]{ 
  \node[isosceles triangle, isosceles triangle apex angle=70,
     draw=black,fill=white, inner sep=0pt,anchor=lower 
     side,rotate=90,draw=black,
     fill=white, minimum height={#2} cm] (#1) at #3 {};}

Suppose I wanted to define a function that takes in a size and starting coordinate, and draws a "triangle" of triangles such as

\begin{tikzpicture}
  \Tri{a}{1}{(-1,0)}
  \Tri{b}{1}{(1,0)}
  \Tri{c}{1}{(0,1.41)}
\end{tikzpicture}

The simple way to do this is to make a macro \TriTri, such that \TriTri{a}{n}{x}{y} creates a triangle of triangles, with bottom triangle anchored at (x,y).

\newcommand\TriTri[4]{ 
  \Tri{#1}{#2}{(#3,#4)}
  \Tri{#1}{#2}{(#3+2*#2,#4)}
  \Tri{#1}{#2}{(#3+#2,{sqrt(2*#2*#2)})}} %% note #3+#2 = (x1 + x2)/2 
                                         %% the sqrt bit is sqrt(size^2 + size^2)
}

I have gotten this to work! But what I would like to do is instead of having x and y input separately, I would like to have them input as a coordinate pair. I would like to reference the coordinates as \first,\second. So that \first(x,y) = x. The desired effect is that

$$\first(1,2)$$

would be the same as

$$1$$

1 Answer 1

6

You can use the xparse package:

\documentclass{article}
\usepackage{tikz,xparse}
\usetikzlibrary{shapes.geometric}

\NewDocumentCommand{\Tri}{m m r()}
 {%
  \node[isosceles triangle, isosceles triangle apex angle=70,
     draw=black,fill=white, inner sep=0pt,anchor=lower
     side,rotate=90,draw=black,
     fill=white, minimum height=#2cm] (#1) at (#3) {};
 }

\NewDocumentCommand\TriTri{mmr(,u)}
 {%
  \Tri{#1}{#2}(#3,#4)
  \Tri{#1}{#2}(#3+2*#2,#4)
  \Tri{#1}{#2}(#3+#2,{sqrt(2*#2*#2)}) %% note #3+#2 = (x1 + x2)/2
                                      %% the sqrt bit is sqrt(size^2 + size^2)
 }

\begin{document}

\begin{tikzpicture}
\TriTri{a}{3}(2,2)
\end{tikzpicture}

\end{document}

The \Tri command accepts three arguments; the first and the second ones are enclosed in braces, while the third is between parentheses, so

\Tri{a}{3}(0,0)

In the body of the definition you'll use (#3) instead of #3, because the parentheses are stripped off.

In the case of \TriTri we have to split off the two coordinates, so we define four arguments; the first and the second ones are enclosed in braces; the third is what goes from ( to a comma, the final one is everything up to ).

Thus I have modified accordingly your code for \TriTri based on the requirements for \Tri.

2
  • Xparse looks great, and I get a feel for how this package works. However, I have a couple questions: 1) Why do you need to use \NewDocumentCommand? Is this xparse specific? 2) It seems to drop the braces surrounding a command. For example, I tried, \NewDocumentCommand{\projL}{r(,u)}{#1}. And while \projL(1,3) gives the expected 1, \projL{(1,3)} fails to compile. I like the braced delimiters, and I could parse for them, but maybe I am missing something? Commented Sep 18, 2013 at 22:42
  • @JonathanGallagher With your definition, \projL expects to see \projL(X,Y) and X will be #1, while Y will be #2. If you want a pair of coordinates, use {r()} as I did in the definition of \Tri. But the parentheses are dropped, you just put them back around #1.
    – egreg
    Commented Sep 18, 2013 at 22:53

You must log in to answer this question.

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