限制径向 Tikzpicture 圆形跨度的后续操作

限制径向 Tikzpicture 圆形跨度的后续操作

这篇文章是这篇文章的延伸如何限制径向褪色 Tikzpicture 的圆形跨度

考虑一下代码

\documentclass{book}
% Code can be compiled with Pdflatex or Xelatex
\usepackage{tikz} 
\usetikzlibrary{fadings}
\definecolor{darkamber}{RGB}{213,54,0}
\definecolor{sunriseyellow}{RGB}{255,219,0}
\definecolor{topaz}{RGB}{255,200,124}

\begin{document}
\thispagestyle{empty}

\tikzfading[name=fade out, inner color=transparent!0,
outer color=transparent!100]
\tikzset{
  star/.style={darkamber, fill=white, path fading=fade out}
}

\begin{tikzpicture}
\clip (-3, -3) rectangle (3, 3);
  \draw[darkamber, shading=mradial, inner color=topaz, 
  middle color=darkamber!60!sunriseyellow, outer color=darkamber]
  (-3, -3) rectangle (3, 3);
\end{tikzpicture}

\vspace*{25pt}

\begin{tikzpicture}
  \clip (-3, -3) rectangle (3, 3);
  \draw[darkamber, shading=mradial, inner color=topaz, 
  middle color=darkamber!60!sunriseyellow, outer color=darkamber]
  (-3, -3) rectangle (3, 3);
  \fill[darkamber] (180:4cm) arc (180:360:4cm) -- (0,0) -- cycle; % <---- The pie piece
\end{tikzpicture} 
\end{document}

生成两幅图像:

在此处输入图片描述

我希望能够以更便捷的方式制作第二张图像;例如,通过指定第一张图像的全圆“径向辉光”应该只扫过 0 度到 180 度,而不是明显默认的 0 度到 360 度。

通过在第一幅图像的下半部分叠加一个暗琥珀色矩形,可以得到所需的第二幅图像。

问题:这是否可能?如果可以,我该如何修改生成第一幅图像的代码,以便可以指定它产生从(在本例中)0 度到 180 度的光晕;更一般地说,比如说,A度至b度,而不必在第一幅实心图像上叠加第二幅实心图像来实现所需效果?谢谢。

注意:在如何限制径向褪色 Tikzpicture 的圆形跨度用户 SebGlav 表示,“有一种方法可以限制,但你需要先填充背景。无论如何,你都必须使用两个命令来完成。”

答案1

如果您不需要完整剪切矩形的边框,我会选择剪切。


从原点方向找到正方形或矩形上的点不是问题,PGF 自带了\pgfpointborderrectangle(这被rectangle边框锚点,但您需要确定需要击中正方形/矩形的哪些边,共有 20 种选择)。

我懒得去算数学题,让你给出这些边。所以对于角度0180部分矩形将从右边开始r,到左边结束l,因此你指定

partial rectangle from = 0 to 180 sized 3 by 3 from r to l

然后矩形的底部就是

partial rectangle from=180 to 360 sized 3 by 3 from l to r

底部三角形部分是

partial rectangle from=-60 to 240 sized 3 by 3 from b to b'

注意':这意味着我们需要击中所有四个角。如果没有,'它就不会击中任何角。


一开始,它将路径移动到角落,这样淡入淡出就计算在整个矩形上,而不仅仅是部分矩形上。(注释掉它以查看其含义。)我还没有找到从边界框中排除这些点的方法,不过这应该不是问题,因为无论如何你都想为剩余部分着色。

代码

\documentclass[tikz,convert={density=100}]{standalone}
\usetikzlibrary{fadings}
\definecolor{darkamber}{RGB}{213,54,0}
\definecolor{sunriseyellow}{RGB}{255,219,0}
\definecolor{topaz}{RGB}{255,200,124}
\newcommand*\clipRectangle[3]{
  \pgfinterruptboundingbox\clip (0,0) -- ({#1}:{sqrt 2*max(#3)})
    arc[start angle={#1}, end angle={#2}, radius={sqrt 2*max(#3)}]
    -- cycle;\endpgfinterruptboundingbox}
\makeatletter
\newcommand*\tikzScanOnePoint[1]{\tikz@scan@one@point\pgfutil@firstofone(#1)}
\makeatother
\tikzset{
  prf/.style 2 args={/utils/temp/.style={prf/##1=#2},/utils/temp/.list={#1}},
  prf/rr'/.style={prf={rt,tl,lb,br}{#1}},prf/tt'/.style={prf={tl,lb,br,rt}{#1}},
  prf/ll'/.style={prf={lb,br,rt,tl}{#1}},prf/bb'/.style={prf={br,rt,tl,lb}{#1}},
  prf/rt/.code 2 args=\pgfpathlineto{\tikzScanOnePoint{{#1},{#2}}},
  prf/tl/.code 2 args=\pgfpathlineto{\tikzScanOnePoint{{-(#1)},{#2}}},
  prf/lb/.code 2 args=\pgfpathlineto{\tikzScanOnePoint{{-(#1)},{-(#2)}}},
  prf/br/.code 2 args=\pgfpathlineto{\tikzScanOnePoint{{#1},{-(#2)}}},
  prf/rl/.style={prf/rt=#1,prf/tl=#1}, prf/tb/.style={prf/tl=#1,prf/lb=#1},
  prf/lr/.style={prf/lb=#1,prf/br=#1}, prf/bt/.style={prf/br=#1,prf/rt=#1},
  prf/rb/.style={prf/rl=#1,prf/lb=#1}, prf/tr/.style={prf/tb=#1,prf/br=#1},
  prf/lt/.style={prf/lr=#1,prf/rt=#1}, prf/bl/.style={prf/bt=#1,prf/tl=#1},
  partial rectangle from/.style args={#1 to #2 sized #3 by #4 from #5 to #6}{
    partial rectangle={#1}{#2}{#3}{#4}{#5#6}},
  partial rectangle/.code n args={5}{% #1 = start angle
                                     % #2 = end angle
                                     % #3 = width radius
                                     % #4 = height radius
                                     % #5 = sides rtlb
%    \pgfinterruptboundingbox % doesn't work
      \pgfpathmoveto{\tikzScanOnePoint{{#3},{#4}}}%
      \pgfpathmoveto{\tikzScanOnePoint{{-(#3)},{-(#4)}}}%
%    \endpgfinterruptboundingbox
    \pgfpathmoveto{\pgfpointorigin}%
    \pgfpathlineto{\pgfpointborderrectangle{\pgfpointpolar{#1}{1pt}}
                  {\tikzScanOnePoint{{#3},{#4}}}}%
    \tikzset{prf/#5/.try={#3}{#4}}
    \pgfpathlineto{\pgfpointborderrectangle{\pgfpointpolar{#2}{1pt}}
                  {\tikzScanOnePoint{{#3},{#4}}}}%
    \pgfpathclose
  }
}
\begin{document}
\begin{tikzpicture}
\scoped
  \clipRectangle{-60}{240}{3}
  \path[
    shading=mradial,
    inner color=topaz, 
    middle color=darkamber!60!sunriseyellow,
    outer color=darkamber,
  ] (-3, -3) rectangle (3, 3);
\scoped
  \clipRectangle{240}{300}{3}
  \path[
    shading=mradial,
    inner color=darkamber,
    middle color=darkamber!60!sunriseyellow,
    outer color=topaz,
  ] (-3, -3) rectangle (3, 3);
\end{tikzpicture}
\tikz[ultra thick]
\draw[
  black,
  shading=mradial,
  inner color=topaz, 
  middle color=darkamber!60!sunriseyellow,
  outer color=darkamber,
  partial rectangle from=-60 to 240 sized 3 by 3 from b to b'];

\begin{tikzpicture}[ultra thick]
\draw[
  black,
  shading=mradial,
  inner color=topaz, 
  middle color=darkamber!60!sunriseyellow,
  outer color=darkamber,
  partial rectangle from = 0 to 180 sized 3 by 3 from r to l];
\path[fill=darkamber, draw=black,
  partial rectangle from=180 to 360 sized 3 by 3 from l to r];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述在此处输入图片描述在此处输入图片描述

相关内容