Следующий код предписывает TikZ
нарисовать прямоугольный треугольник и разместить сетку на декартовой плоскости. Я хотел бы внести в него две модификации.
Я хочу, чтобы внутренняя часть треугольника была «окрашена» в белый цвет. Я посмотрел Главу 15, Раздел 7 руководства на веб-сайте http://texdoc.net/texmf-dist/doc/generic/pgf/pgfmanual.pdf
. Там показан код для затенения круга, если указаны его центр и радиус, и показан код для затенения прямоугольника, если указаны две его вершины. В следующем коде одна вершина, R, треугольника вычисляется с помощью TikZ
кода \coordinate (R) at ($(P)!1cm*sqrt(5)!-90:(Q)$);
. Как мне «окрасить» внутреннюю часть треугольника в белый цвет, не вычисляя вручную координаты R? (Внутри треугольника есть метка прямого угла; она не должна быть «закрыта».)
Треугольник нарисован над вершиной R. Это выглядит странно. Как мне TikZ
нарисовать треугольник под вершинами?
\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}
решение1
Добавьте fill=white
, например, так:\draw[green!20!white, fill=white] (Q) -- (P) -- (R) -- (Q) -- cycle;
Для того, чтобы точки появились на лицевой стороне, я взял на себя смелость переписать ваш код. Вы могли бы использовать Layers 1 , но код был бы сложнее, чем этот, и я не думаю, что он того стоит, если он вам нужен только сейчас.
Я добавил несколько новых вещей, таких как tikzset, так что вы можете использовать одно слово для определения свойств узла (и вам не нужны эти длинные списки параметров узла), более того, вам нужно исправить только один, чтобы исправить все, без необходимости изменять каждый из них.
Я определил координаты и сначала использовал эти координаты для записи узлов P, Q и R, а затем использовал те же координаты для создания маленьких черных кружочков.
\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: См. раздел90: Многослойная графиканаPgfmanual, стр. 820.
решение2
Я не уверен насчет чегобез ручного расчета координат Rозначает. Может быть что-то вроде
\node[outer sep=0pt,circle, draw,inner sep=1.5pt, label={[fill=white]right:$R$}] (R)
at ($(P)!1cm*sqrt(5)!-90:(Q)$){};
В любом случае TikZ
рисует все в том же порядке, в котором написан код. Поэтому, как вы рисуете
\draw[green!20!white] (Q) -- (P) -- (R) -- (Q) -- cycle;
после
\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) {};
треугольник нарисован над R
. Но почему над R
и не над P
и Q
? Потому что R
, как вы можете видеть из предыдущих строк, являетсяне нарисованокоордината (вы рисуете точку с неназванным узлом над R
), в то время как P
и Q
было определено как nodes
с определенным размером. И
\draw[green!20!white] (Q) -- (P) -- (R) -- (Q) -- cycle;
рисует линии между границами узлов, границы которых не существуют только в случае , R
поскольку это точка.
Посмотрите, что происходит со следующим кодом. Узлы P
и Q
только рисуются, и помните, что окружность вокруг R
— это безымянный узел, на который позже не ссылаются.
\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}
Пока
\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}
производит
Как видно из предыдущего рисунка, в этом случае невозможно замкнуть область для заполнения, поскольку R
она имеет реальный размер, а путь не пересекается (верно?).
Как решить обе проблемы: заполнение треугольника и выполнение его под узлами? С помощью backgrounds
tikzlibrary и закрытия пути.
Следующий код показывает возможное решение. Сетка и оси рисуются на background
слое, который объявлен библиотекой backgrounds
. И белый треугольник также рисуется на фоновом слое, но поверх сетки, потому что все рисуется по порядку.
\begin{scope}[on background layer]
...
\end{scope}
Но вершина и угол треугольника рисуются на переднем плане.
Треугольник может быть заполнен ссылками на центры узлов, а не только на их имена.
\draw[green!20!white, fill=white] (Q.center) -- (P.center) -- (R.center) -- cycle;
Полный код:
\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}
решение3
Для тех, кому интересно, вот способ, который использует MetaPost: заполнение треугольника белым цветом достигается просто путем удаления заливки с его содержимого после рисования сетки и осей, но перед рисованием самого треугольника (и его меток).
path triangle; triangle = P--Q--R--cycle;
unfill triangle; draw triangle;
Не то чтобы треугольник был определен как замкнутый контур: P--Q--R--cycle;
эта --cycle
часть, таким образом, обязательна, в противном случае контур не может быть заполнен или незаполнен.
Я не знаю о «слоях» в самом MetaPost, но я что-то слышал о них при использовании формата MetaFun. Хотя не уверен насчет этого.
NB: раскрашивание замкнутого контура способом MetaPost фактически означает его заполнение цветом фона. Поскольку он обычно белый, в большинстве случаев это одно и то же. В противном случае просто замените инструкцию unfill triangle;
на более прямую 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}