Shading inside a triangle when the coordinates of one vertex are calculated by TikZ

The following code instructs TikZ to draw a right triangle and to put a grid on the Cartesian plane. I would like to make two modifications to it.

I want the inside of the triangle to be "colored" white. I looked at Chapter 15, Section 7 of the manual at the web site http://texdoc.net/texmf-dist/doc/generic/pgf/pgfmanual.pdf. It shows the code to shade a circle if its center and radius are specified, and it shows the code to shade a rectangle if two of its vertices are specified. In the following code, one vertex, R, of the triangle is calculated by TikZ using the code \coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);. How do I "color" the inside of the triangle white without manually calculating the coordinates of R? (There is a right-angle mark inside the triangle; it should not be "covered.")

The triangle is drawn over the vertex at R. This looks odd. How do I have TikZ draw the triangle under the vertices?

\documentclass[10pt]{amsart}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}

\draw[yellow, line width=0.1pt] (-1.75,-3.25) grid[xstep=0.5, ystep=0.5]  (2.75,1.75);
\draw[draw=gray!30,latex-latex] (0,1.75) +(0,0.25cm) node[above right] {$y$} -- (0,-3.25) -- +(0,-0.25cm);
\draw[draw=gray!30,latex-latex] (-1.75,0) +(-0.25cm,0) -- (2.75,0) -- +(0.25cm,0) node[below right] {$x$};

\node[outer sep=0pt,circle, fill,inner sep=1.5pt,label={[fill=white]left:$P$}] (P) at (-1,-1) {};
\node[outer sep=0pt,circle, fill,inner sep=1.5pt, label={[fill=white]right:$Q$}] (Q) at (2,1) {};

\draw[green!20!white] (P) -- (Q);

\coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
\node[outer sep=0pt,circle, fill,inner sep=1.5pt, label={[fill=white]right:$R$}] at(R) {};
\draw[green!20!white] (Q) -- (P) -- (R) -- (Q) -- cycle;

\coordinate (a) at ($(P)!5mm! -45:(Q)$);
\draw[green!20!white] (a) -- ($(P)!(a)!(Q)$);
\draw[green!20!white] (a) -- ($(P)!(a)!(R)$);

\end{tikzpicture}

\end{document}


Add fill=white, like this: \draw[green!20!white, fill=white] (Q) -- (P) -- (R) -- (Q) -- cycle;

In order for the dots to appear on the front, I have taken the liberty of rewriting your code. You could have used Layers1, but the code would be more complicated than this and I don't think it's worth it if you need it just this time.

I added some new things like tikzset, so you can use a single word to define node properties (and you don't need to have those long node option lists), furthermore, you only need to fix one to fix them all, without having to change each one.

I defined the coordinates and used those coordinates first to write the nodes P, Q, and R, and then I used the same coordinates to create little black circle nodes.

\documentclass[margin=10pt]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
points/.style={outer sep=0pt, circle, inner sep=1.5pt, fill=white},
dotnode/.style={circle, fill=black, inner sep=0pt,minimum size=4pt},
}

\begin{document}

\begin{tikzpicture}

\coordinate (P) at (-1,-1);
\coordinate (Q) at (2,1);
\coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
\coordinate (a) at ($(P)!5mm! -45:(Q)$);

\draw[yellow, line width=0.1pt] (-1.75,-3.25) grid[xstep=0.5, ystep=0.5]  (2.75,1.75);
\draw[draw=gray!30,latex-latex] (0,1.75) +(0,0.25cm) node[above right] {$y$} -- (0,-3.25) -- +(0,-0.25cm);
\draw[draw=gray!30,latex-latex] (-1.75,0) +(-0.25cm,0) -- (2.75,0) -- +(0.25cm,0) node[below right] {$x$};

\node[points, anchor=east] at (-1,-1) {$P$};a
\node[points, anchor=west] at (2,1) {$Q$};
\node[points, anchor=west] at (R) {$R$};

\draw[green!20!white] (P) -- (Q);
\draw[green!20!white, fill=white] (Q) -- (P) -- (R) -- (Q) -- cycle;

\draw[green!20!white] (a) -- ($(P)!(a)!(Q)$);
\draw[green!20!white] (a) -- ($(P)!(a)!(R)$);

\node[dotnode] at (P) {};
\node[dotnode] at (Q) {};
\node[dotnode] at (R) {};

\end{tikzpicture}

\end{document}


1: See Section 90: Layered Graphics on the Pgfmanual, page 820.

• What command puts the nodes over the triangle, and what command puts the right-angle mark over the fill=white declaration? (I will also refer to section 90 of the manual.) – Adelyn Apr 23 '15 at 15:56
• @Adelyn The nodes are over the triangle simply because they're listed afterwards separately. It could be done with layers with a single command but I preferred this approach. The same thing can be said about the fill=white option. – Alenanno Apr 23 '15 at 16:00
• @Alenanno Thanks for the code. This display is what I wanted. – user74973 Apr 23 '15 at 16:16
• @user74973 You're welcome! In the first Tikzset, I realised that there is an option fill, but since fill=white is specified later, you can safely delete the former. :) I have fixed my answer accordingly. – Alenanno Apr 23 '15 at 16:17
• @Alenanno It i not flattery to say that the structure of your code is impeccable! – user74973 Apr 23 '15 at 16:22

I not sure about what without manually calculating the coordinates of R means. May be something like

\node[outer sep=0pt,circle, draw,inner sep=1.5pt, label={[fill=white]right:$R$}] (R)
at ($(P)!1cm*sqrt(5)!-90:(Q)$){};


In any case, TikZ draws everything in the same order as code is written. Therefore, as you draw

\draw[green!20!white] (Q) -- (P) -- (R) -- (Q) -- cycle;


after

\coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
\node[outer sep=0pt,circle, fill,inner sep=1.5pt, label={[fill=white]right:$R$}] at(R) {};


the triangle is drawn over R. But why over R and not over P and Q? Because R, as you can see from previous lines, is a not drawn coordinate (you draw the dot with un unnamed node over R) while P and Q has been defined as nodes with a certain size. And

\draw[green!20!white] (Q) -- (P) -- (R) -- (Q) -- cycle;


draws lines between node borders, borders which don't only exist in case of R because it's a point.

See what happens with following code. Nodes P and Q are only drawn and remember that circle around R is an unnamed node which is not referenced later on.

\documentclass[10pt]{amsart}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}

\node[outer sep=0pt,circle, draw ,inner sep=1.5pt,label={[fill=white]left:$P$}] (P) at (-1,-1) {};
\node[outer sep=0pt,circle, draw,inner sep=1.5pt, label={[fill=white]right:$Q$}] (Q) at (2,1) {};

\coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
\node[outer sep=0pt,circle, draw,inner sep=1.5pt, label={[fill=white]right:$R$}] at(R) {};
\draw[red, fill=green] (Q) -- (P) -- (R) --(Q)-- cycle;

\end{tikzpicture}
\end{document}


While

\documentclass[10pt]{amsart}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}

\node[outer sep=0pt,circle, draw ,inner sep=1.5pt,label={[fill=white]left:$P$}] (P) at (-1,-1) {};
\node[outer sep=0pt,circle, draw,inner sep=1.5pt, label={[fill=white]right:$Q$}] (Q) at (2,1) {};

\draw[green!20!white] (P) -- (Q);

%\coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
\node[outer sep=0pt,circle, draw,inner sep=1.5pt, label={[fill=white]right:$R$}] (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$){};

\draw[red, fill=green] (Q) -- (P) -- (R) --(Q)-- cycle;

\end{tikzpicture}
\end{document}


produces

As you can see from previous figure, in this case is not possible to close an area to be filled because R has a real size and the path is disjoint (is it correct?).

How to solve both problems: filling the triangle and doing it below nodes? With backgrounds tikzlibrary and closing the path.

Following code shows a possible solution. Grid and axes are drawn on the background layer which is declared by backgrounds library. And the white triangle is also drawn on background layer, but over grid because everything is drawn in order.

\begin{scope}[on background layer]
...
\end{scope}


But triangle vertex and corner are drawn on foreground layer.

The triangle can be filled referencing nodes centers instead of only their names

\draw[green!20!white, fill=white] (Q.center) -- (P.center) -- (R.center) -- cycle;


The complete code:

\documentclass[tikz,10pt,border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,backgrounds}

\begin{document}
\begin{tikzpicture}[dot/.style={circle, fill, inner sep=1.5pt, outer sep=0pt}]

\begin{scope}[on background layer]
\draw[yellow, line width=0.1pt] (-1.75,-3.25) grid[xstep=0.5, ystep=0.5]  (2.75,1.75);
\draw[draw=gray!30,latex-latex] (0,1.75) +(0,0.25cm) node[above right] {$y$} -- (0,-3.25) -- +(0,-0.25cm);
\draw[draw=gray!30,latex-latex] (-1.75,0) +(-0.25cm,0) -- (2.75,0) -- +(0.25cm,0) node[below right] {$x$};
\end{scope}

\coordinate[dot, label={[fill=white]left:$P$}] (P) at (-1,-1) {};
\coordinate[dot, label={[fill=white]right:$Q$}] (Q) at (2,1) {};
\coordinate[dot, label={[fill=white]below right:$R$}] (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$)  {};
%
%%\draw[green!20!white] (P) -- (Q);
%
%%\coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
%
\begin{scope}[on background layer]
\draw[green!20!white, fill=white] (Q.center) -- (P.center) -- (R.center) -- cycle;
\end{scope}
%
\coordinate (a) at ($(P)!5mm! -45:(Q)$);
\draw[green!20!white] ($(P)!(a)!(Q)$)--(a)--($(P)!(a)!(R)$);

\end{tikzpicture}

\end{document}


• I had thought about the background layer, it certainly helps, but it also put it behind the grid. I didn't think of applying the same to the grid itself. :D – Alenanno Apr 23 '15 at 16:20
• @Alenanno I also did it wrong with the first test. ;-) – Ignasi Apr 23 '15 at 16:22
• @ Ignasi Is backgrounds discussed in Chapter 90 of the manual at http://www.texample.net/media/pgf/builds/pgfmanualCVS2012-11-04.pdf? – user74973 Apr 23 '15 at 16:28
• @user74973 It's discussed at chapter 43 in TikZ manual 3.0 – Ignasi Apr 23 '15 at 18:54
• @user74973 The manual is also in your system, type "texdoc pgfmanual" from command line. For MikTeX I use "texdoc --view pgfmanual". Documentation for all packages can be read with previous command. All files are under doc folder inside TeX main folder. – Ignasi Apr 24 '15 at 6:46

The MetaPost way of doing this, for those who are interested: filling the triangle with white color is simply achieved through unfilling its content after drawing the grid and the axes, and before drawing the triangle itself (and its labels).

path triangle; triangle = P--Q--R--cycle;
unfill triangle; draw triangle;


Not that the triangle has been defined as a closed path: P--Q--R--cycle; : the --cyclepart is thus compulsory, otherwise the path can not be filled nor unfilled.

I do not know about “layers” in MetaPost itself, but I have heard something about them when using the MetaFun format. Not sure about it, though.

NB: unfilling a closed path in the MetaPost way means in fact filling it with the color of the background. Since it is generally white, it amounts to the same thing in most cases. Otherwise, simply replace the instruction unfill triangle; by the more direct fill triangle with color white;.

\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
\mplibsetformat{metafun}
\mplibtextextlabel{enable}
\begin{document}
\begin{mplibcode}
% Axes parameters
u := cm; % Unit length
xmin := -1.75u; xstep := .5u; xmax := 2.75u;
ymin := -5u; ystep := xstep; ymax := 1.75u;
% Triangle summits
pair P, Q, R; P = u*(-1, -1); Q = u*(2, 1);
R = P + 2u*sqrt2*unitvector(Q-P) rotated -90;

beginfig(1);
% Grid
drawoptions(withcolor yellow);
for i = ceiling(xmin/xstep) upto floor(xmax/xstep):
draw (i*xstep, ymin) -- (i*xstep, ymax);
endfor
for j = ceiling(ymin/ystep) upto floor(ymax/ystep):
draw (xmin, j*ystep) -- (xmax, j*ystep);
endfor
% Axes
drawoptions(withcolor .8white);
drawarrow (xmin, 0) -- (xmax, 0);
drawarrow (0, ymin) -- (0, ymax);
% Triangle
drawoptions(withcolor green);
path triangle; triangle = P--Q--R--cycle;
unfill triangle; draw triangle;
% Right-angle mark of length 2 mm (and no label)
anglemethod := 2; anglelength := 2mm;
draw anglebetween(P--Q, P--R, "");
% Labels
drawoptions();
label.bot("$x$", (xmax, 0)); label.lft("$y$", (0, ymax));
dotlabel.lft("$P$", P); dotlabel.rt("$Q$", Q); dotlabel.bot("$R$", R);
endfig;
\end{mplibcode}
\end{document}