当 TikZ 计算出一个顶点的坐标时,三角形内的阴影

当 TikZ 计算出一个顶点的坐标时,三角形内的阴影

下面的代码指示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,然后我使用相同的坐标来创建小黑圆圈节点。

图1

\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:分层图形手册,第 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而不是 和 上PQ?因为R,正如你从前面几行中看到的, 是未绘制坐标(你在 上用一个未命名的节点绘制一个点R),而PQ已被定义为nodes具有一定大小。并且

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

在节点边界之间画线,只有在R它是一个点的情况下才存在边界。

看看下面的代码会发生什么。节点PQ仅被绘制,请记住,圆圈周围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具有实际大小并且路径是不相交的(这是正确的吗?)。

如何解决这两个问题:填充三角形并在节点下方进行?使用backgroundstikzlibrary 并关闭路径。

以下代码展示了一种可能的解决方案。网格和轴绘制在库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 格式时听说过一些关于它们的信息。不过,我对此并不确定。

注意:在 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}

在此处输入图片描述

相关内容