5

Here's what I currently have to type:

\documentclass{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (90:3cm);
  \coordinate (b) at (210:3cm);
  \coordinate (c) at (-30:3cm);

  \node [above] at (a) {$a$};
  \node [below left] at (b) {$b$};
  \node [below right] at (c) {$c$};

  \draw [thick,green, fill=green,opacity=0.5]
  (barycentric cs:a=1,b=0,c=0) --
  (barycentric cs:a=1,b=0,c=1) --
  (barycentric cs:a=1,b=1,c=0) -- cycle;

  \draw [ultra thick] (a) -- (b) -- (c) --cycle;
\end{tikzpicture}
\end{document}

This is a little tedious. Since I'll want to draw lots of shapes using the same a,b,c-based barycentric coordinates. Is there a way to pass an option to scope for example that would allow me to have (1,0,1) evaluate as (barycentric cs:a=1,b=0,c=1)?

Seamus
  • 73,242

3 Answers3

6

If it is ok for you to use normalized barycentric coordinates, ie (x,y,z) such that x+y+z=1, then you can simply set x=(a),y=(b),z=(c). So in place of (1,1,0) you should use (.5,.5,0).

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \path
      (90:3cm) coordinate (a) node[above] {$a$}
      (210:3cm) coordinate (b) node[below left] {$b$}
      (-30:3cm) coordinate (c) node[below right] {$c$};

    \draw [thick,green, fill=green,opacity=0.5]
      (barycentric cs:a=1,b=0,c=0) --
      (barycentric cs:a=1,b=0,c=1) --
      (barycentric cs:a=1,b=1,c=0) -- cycle;

    \draw [ultra thick] (a) -- (b) -- (c) --cycle;

    % set x=(a),y=(b),z=(c) and use normalized barycentric coordinates
    \draw[ultra thick, red, dashed, x=(a),y=(b),z=(c)]
    (1,0,0)  -- (.5,0,.5) -- (.5,.5,0) --cycle;
  \end{tikzpicture}
\end{document}

enter image description here

Kpym
  • 23,002
  • Aha! I was wondering about this. So $x=(a)$ just sets the "x" coordinate in xyz coordinates to be the vector to (a)? – Seamus Jan 04 '19 at 17:03
  • 2
    When you set x=(a),y=(b),z=(c) than (x,y,z) is a point with coordinates x.a+y.b+z.c. That's all. – Kpym Jan 04 '19 at 17:05
  • @Kpym I am not angry and would like to see your other, nice answer revived. The only thing I am advocating is to refer to earlier posts by others, if they are related, something that you usually do. –  Jan 04 '19 at 21:05
6

You can also use insert path to abbreviate the coordinates.

\documentclass{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[bcs/.style args={#1|#2|#3}{insert path={--(barycentric
cs:a=#1,b=#2,c=#3)}}]
  \coordinate (a) at (90:3cm);
  \coordinate (b) at (210:3cm);
  \coordinate (c) at (-30:3cm);

  \node [above] at (a) {$a$};
  \node [below left] at (b) {$b$};
  \node [below right] at (c) {$c$};

  \draw [thick,green, fill=green,opacity=0.5] (a)
  [bcs={1|0|1},bcs={1|1|0}] -- cycle;

  \draw [ultra thick] (a) -- (b) -- (c) --cycle;
\end{tikzpicture}
\end{document}

enter image description here

Another thing you could do is to locally change the TikZ parser. Then the whole path really boils down to

  \begin{scope}[bary={a}{b}{c}]
   \draw [thick,green, fill=green,opacity=0.5] 
    (1,0,0) -- (1,0,1) -- (1,1,0) -- cycle;
  \end{scope}

where bary={a}{b}{c} install the barycentric coordinate system in the scope (we don't want it everywhere) and you really just have to specify the three numbers.

\documentclass[tikz,border=3.14mm]{standalone}

\makeatletter % https://tex.stackexchange.com/a/365418/121799
\tikzset{bary/.code n args={3}{
  \def\tikz@parse@splitxyz##1##2##3,##4,{%
    \def\@next{\tikz@scan@one@point##1(barycentric cs:#1=##2,#2=##3,#3=##4)}%
    }}}
\makeatother

\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (90:3cm);
  \coordinate (b) at (210:3cm);
  \coordinate (c) at (-30:3cm);

  \node [above] at (a) {$a$};
  \node [below left] at (b) {$b$};
  \node [below right] at (c) {$c$};
  \begin{scope}[bary={a}{b}{c}]
  \draw [thick,green, fill=green,opacity=0.5] 
  (1,0,0) -- (1,0,1) -- (1,1,0) -- cycle;
  \end{scope}   
  \draw [ultra thick] (a) -- (b) -- (c) --cycle;
\end{tikzpicture}
\end{document}
  • Every time I read your answers on TikZ I say to myself I have to study the user guide. I'm afraid the amount of new tools there I never read about!! – Sigur Jan 04 '19 at 16:41
  • @Sigur This impression never fades away, regardless how long you read it. ;-) –  Jan 04 '19 at 16:43
  • I was thinking about this too, but using insert path={(barycentric cs:a=#1,b=#2,c=#3)} do not work at the end of the path. For this reason you added -- in the insert path, I suppose. But now you can only draw straight lines :( – Kpym Jan 04 '19 at 16:59
  • @Kpym Yes, that's true. This great answer comes with a sort of coordinate system parser, which one may adopt to this situation here. Anyway, I added yet another possibility that changes the TikZ parser locally. –  Jan 04 '19 at 17:14
5

You can define

\newcommand{\foo}[3]{(barycentric cs:a=#1,b=#2,c=#3)}

and then use it as

  \draw [thick,green, fill=green,opacity=0.5]
  \foo{1}{0}{0} --
  \foo{1}{0}{1} --
  \foo{1}{1}{0} -- cycle;

or combine with another command with 9 parameters

\newcommand{\faa}[9]{
  \draw [thick,green, fill=green,opacity=0.5]
  \foo{#1}{#2}{#3} --
  \foo{#4}{#5}{#6} --
  \foo{#7}{#8}{#9} -- cycle;
}

and use as

\faa{1}{0}{0}{1}{0}{1}{1}{1}{1}

enter image description here

MWE

\documentclass{standalone}

\usepackage{tikz}
\newcommand{\foo}[3]{(barycentric cs:a=#1,b=#2,c=#3)}
\newcommand{\faa}[9]{
  \draw [thick,green, fill=green,opacity=0.5]
  \foo{#1}{#2}{#3} --
  \foo{#4}{#5}{#6} --
  \foo{#7}{#8}{#9} -- cycle;
}
\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (90:3cm);
  \coordinate (b) at (210:3cm);
  \coordinate (c) at (-30:3cm);

  \node [above] at (a) {$a$};
  \node [below left] at (b) {$b$};
  \node [below right] at (c) {$c$};

  \draw [thick,green, fill=green,opacity=0.5]
  \foo{1}{0}{0} --
  \foo{1}{0}{1} --
  \foo{1}{1}{0} -- cycle;

  \faa{1}{0}{0}{1}{0}{1}{1}{1}{1}

  \draw [ultra thick] (a) -- (b) -- (c) --cycle;
\end{tikzpicture}
\end{document}
Sigur
  • 37,330
  • 1
    +1. Suggestion : use \def in place of \newcommand to make more "friendly" interface. For example \def\bc(#1:#2:#3){(barycentric cs:a=#1,b=#2,c=#3)} can be used after as \bc(1:0:0). – Kpym Jan 04 '19 at 17:07